summaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:00:50 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:00:50 +0200
commit4ecfd41e36533d858c98d051ef70cab80e69e972 (patch)
treeca07d8745967d2c6a7123a5d32269cfbfaa7bd6c /ui
parent2.2 (diff)
downloadFreeFileSync-4ecfd41e36533d858c98d051ef70cab80e69e972.tar.gz
FreeFileSync-4ecfd41e36533d858c98d051ef70cab80e69e972.tar.bz2
FreeFileSync-4ecfd41e36533d858c98d051ef70cab80e69e972.zip
2.3
Diffstat (limited to 'ui')
-rw-r--r--ui/MainDialog.cpp1997
-rw-r--r--ui/MainDialog.h82
-rw-r--r--ui/SmallDialogs.cpp139
-rw-r--r--ui/SmallDialogs.h27
-rw-r--r--ui/SyncDialog.cpp309
-rw-r--r--ui/SyncDialog.h60
-rw-r--r--ui/batchStatusHandler.cpp48
-rw-r--r--ui/batchStatusHandler.h5
-rw-r--r--ui/dragAndDrop.cpp207
-rw-r--r--ui/dragAndDrop.h63
-rw-r--r--ui/folderPair.h147
-rw-r--r--ui/gridView.cpp665
-rw-r--r--ui/gridView.h194
-rw-r--r--ui/guiGenerated.cpp347
-rw-r--r--ui/guiGenerated.h80
-rw-r--r--ui/guiStatusHandler.cpp12
-rw-r--r--ui/sorting.h275
17 files changed, 2463 insertions, 2194 deletions
diff --git a/ui/MainDialog.cpp b/ui/MainDialog.cpp
index 5f078cda..d053bed5 100644
--- a/ui/MainDialog.cpp
+++ b/ui/MainDialog.cpp
@@ -1,6 +1,7 @@
#include "mainDialog.h"
#include <wx/filename.h>
-#include "../shared/globalFunctions.h"
+#include <stdexcept>
+#include "../shared/systemConstants.h"
#include <wx/clipbrd.h>
#include <wx/dataobj.h>
#include <wx/ffile.h>
@@ -25,23 +26,61 @@
#include "../shared/fileHandling.h"
#include "../shared/xmlBase.h"
#include "../shared/standardPaths.h"
+#include "../shared/toggleButton.h"
+#include "folderPair.h"
+#include "../shared/globalFunctions.h"
using namespace FreeFileSync;
using FreeFileSync::CustomLocale;
-class FolderPairPanel : public FolderPairGenerated
+typedef FreeFileSync::FolderPairPanelBasic<FolderPairGenerated> FolderPairParent;
+
+class FolderPairPanel : public FolderPairParent
{
public:
- FolderPairPanel(wxWindow* parent) :
- FolderPairGenerated(parent),
- dragDropOnLeft(new DragDropOnDlg(m_panelLeft, m_dirPickerLeft, m_directoryLeft)),
- dragDropOnRight(new DragDropOnDlg(m_panelRight, m_dirPickerRight, m_directoryRight)) {}
+ FolderPairPanel(wxWindow* parent, MainDialog* mainDialog) :
+ FolderPairParent(parent),
+ mainDlg(mainDialog)
+ {}
private:
- //support for drag and drop
- std::auto_ptr<DragDropOnDlg> dragDropOnLeft;
- std::auto_ptr<DragDropOnDlg> dragDropOnRight;
+ virtual void OnAltFilterCfgRemoveConfirm(wxCommandEvent& event)
+ {
+ FolderPairParent::OnAltFilterCfgRemoveConfirm(event);
+ mainDlg->updateFilterConfig(false); //update filter, leave activation status as it is
+ }
+
+ virtual void OnAltSyncCfgRemoveConfirm(wxCommandEvent& event)
+ {
+ FolderPairParent::OnAltSyncCfgRemoveConfirm(event);
+ mainDlg->updateSyncConfig();
+ }
+
+ virtual wxWindow* getParentWindow()
+ {
+ return mainDlg;
+ }
+
+ virtual MainConfiguration getMainConfig() const
+ {
+ return mainDlg->getCurrentConfiguration().mainCfg;
+ }
+
+ virtual void OnAltSyncCfgChange()
+ {
+ mainDlg->updateSyncConfig();
+ }
+
+ virtual void OnAltFilterCfgChange(bool defaultValueSet)
+ {
+ if (defaultValueSet) //default
+ mainDlg->updateFilterConfig(false); //re-apply filter (without changing active-status)
+ else
+ mainDlg->updateFilterConfig(true); //activate(and apply) filter
+ }
+
+ MainDialog* mainDlg;
};
@@ -80,7 +119,7 @@ public:
mainDlg_->syncPreview.enableSynchronization(false);
//clear grids
- mainDlg_->currentGridData.clear();
+ mainDlg_->gridDataView->clearAllRows();
mainDlg_->updateGuiGrid();
return true;
@@ -130,12 +169,12 @@ private:
MenuItemMap menuItems;
};
-//##################################################################################################################################
-
+//##################################################################################################################################
MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, xmlAccess::XmlGlobalSettings& settings) :
MainDialogGenerated(frame),
globalSettings(settings),
+ gridDataView(new FreeFileSync::GridView()),
contextMenu(new wxMenu), //initialize right-click context menu; will be dynamically re-created on each R-mouse-click
cleanedUp(false),
lastSortColumn(-1),
@@ -147,9 +186,7 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, xmlAccess::X
{
wxWindowUpdateLocker dummy(this); //avoid display distortion
- gridDataView.reset(new FreeFileSync::GridView(currentGridData));
-
- m_bpButtonRemoveTopPair->Hide();
+ initViewFilterButtons();
//initialize and load configuration
readGlobalSettings();
@@ -168,7 +205,6 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, xmlAccess::X
m_bpButtonSave->SetBitmapLabel(*GlobalResources::getInstance().bitmapSave);
m_bpButtonLoad->SetBitmapLabel(*GlobalResources::getInstance().bitmapLoad);
m_bpButtonAddPair->SetBitmapLabel(*GlobalResources::getInstance().bitmapAddFolderPair);
- m_bpButtonRemoveTopPair->SetBitmapLabel(*GlobalResources::getInstance().bitmapRemoveFolderPair);
m_bitmap15->SetBitmap(*GlobalResources::getInstance().bitmapStatusEdge);
m_bitmapCreate->SetBitmap(*GlobalResources::getInstance().bitmapCreate);
@@ -180,8 +216,11 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, xmlAccess::X
//menu icons: workaround for wxWidgets: small hack to update menu items: actually this is a wxWidgets bug (affects Windows- and Linux-build)
MenuItemUpdater updateMenuFile(m_menuFile);
- updateMenuFile.addForUpdate(m_menuItem10, *GlobalResources::getInstance().bitmapCompareSmall);
- updateMenuFile.addForUpdate(m_menuItem11, *GlobalResources::getInstance().bitmapSyncSmall);
+ updateMenuFile.addForUpdate(m_menuItem10, *GlobalResources::getInstance().bitmapCompareSmall);
+ updateMenuFile.addForUpdate(m_menuItem11, *GlobalResources::getInstance().bitmapSyncSmall);
+ updateMenuFile.addForUpdate(m_menuItemNew, *GlobalResources::getInstance().bitmapNewSmall);
+ updateMenuFile.addForUpdate(m_menuItemSave, *GlobalResources::getInstance().bitmapSaveSmall);
+ updateMenuFile.addForUpdate(m_menuItemLoad, *GlobalResources::getInstance().bitmapLoadSmall);
MenuItemUpdater updateMenuAdv(m_menuAdvanced);
updateMenuAdv.addForUpdate(m_menuItemGlobSett, *GlobalResources::getInstance().bitmapSettingsSmall);
@@ -195,7 +234,6 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, xmlAccess::X
for (std::vector<LocInfoLine>::const_iterator i = LocalizationInfo::getMapping().begin(); i != LocalizationInfo::getMapping().end(); ++i)
{
wxMenuItem* newItem = new wxMenuItem(m_menuLanguages, wxID_ANY, i->languageName, wxEmptyString, wxITEM_NORMAL );
-
newItem->SetBitmap(GlobalResources::getInstance().getImageByName(i->languageFlag));
//map menu item IDs with language IDs: evaluated when processing event handler
@@ -203,7 +241,6 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, xmlAccess::X
//connect event
Connect(newItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnMenuLanguageSwitch));
-
m_menuLanguages->Append(newItem);
}
@@ -372,14 +409,18 @@ void MainDialog::writeGlobalSettings()
}
-void MainDialog::setSyncDirManually(const std::set<int>& rowsToSetOnUiTable, const FreeFileSync::SyncDirection dir)
+void MainDialog::setSyncDirManually(const std::set<unsigned int>& rowsToSetOnUiTable, const FreeFileSync::SyncDirection dir)
{
if (rowsToSetOnUiTable.size() > 0)
{
- for (std::set<int>::const_iterator i = rowsToSetOnUiTable.begin(); i != rowsToSetOnUiTable.end(); ++i)
+ for (std::set<unsigned int>::const_iterator i = rowsToSetOnUiTable.begin(); i != rowsToSetOnUiTable.end(); ++i)
{
- (*gridDataView)[*i].syncDir = dir;
- (*gridDataView)[*i].selectedForSynchronization = true;
+ FileSystemObject* fsObj = gridDataView->getObject(*i);
+ if (fsObj)
+ {
+ setSyncDirection(dir, *fsObj); //set new direction (recursively)
+ FilterProcess::setActiveStatus(true, *fsObj); //works recursively for directories
+ }
}
updateGuiGrid();
@@ -387,41 +428,26 @@ void MainDialog::setSyncDirManually(const std::set<int>& rowsToSetOnUiTable, con
}
-void MainDialog::filterRangeManually(const std::set<int>& rowsToFilterOnUiTable, const int leadingRow)
+void MainDialog::filterRangeManually(const std::set<unsigned int>& rowsToFilterOnUiTable, const int leadingRow)
{
if (rowsToFilterOnUiTable.size() > 0)
{
bool newSelection = false; //default: deselect range
//leadingRow determines de-/selection of all other rows
- if (0 <= leadingRow && leadingRow < int(gridDataView->elementsOnView()))
- newSelection = !(*gridDataView)[leadingRow].selectedForSynchronization;
+ const FileSystemObject* fsObj = gridDataView->getObject(leadingRow);
+ if (fsObj)
+ newSelection = !fsObj->selectedForSynchronization;
//if hidefiltered is active, there should be no filtered elements on screen => current element was filtered out
assert(!currentCfg.hideFilteredElements || !newSelection);
- //get all lines that need to be filtered (e.g. if a folder is marked, then its subelements should be marked as well)
- FolderCompRef compRef;
- gridDataView->viewRefToFolderRef(rowsToFilterOnUiTable, compRef);
-
- assert(compRef.size() == currentGridData.size()); //GridView::viewRefToFolderRef() should ensure this!
+ //get all lines that need to be filtered
+ std::vector<FileSystemObject*> compRef;
+ gridDataView->getAllFileRef(rowsToFilterOnUiTable, compRef); //everything in compRef is bound
- for (FolderComparison::iterator i = currentGridData.begin(); i != currentGridData.end(); ++i)
- {
- FileComparison& fileCmp = i->fileCmp;
- const std::set<int>& markedRows = compRef[i - currentGridData.begin()];
-
- std::set<int> markedRowsTotal; //retrieve additional rows that need to be filtered, too
- for (std::set<int>::const_iterator j = markedRows.begin(); j != markedRows.end(); ++j)
- {
- markedRowsTotal.insert(*j);
- FreeFileSync::addSubElements(fileCmp, fileCmp[*j], markedRowsTotal);
- }
-
- //toggle selection of filtered rows
- for (std::set<int>::iterator k = markedRowsTotal.begin(); k != markedRowsTotal.end(); ++k)
- fileCmp[*k].selectedForSynchronization = newSelection;
- }
+ for (std::vector<FileSystemObject*>::iterator i = compRef.begin(); i != compRef.end(); ++i)
+ FilterProcess::setActiveStatus(newSelection, **i); //works recursively for directories
refreshGridAfterFilterChange(400); //call this instead of updateGuiGrid() to add some delay if hideFiltered == true and to handle some graphical artifacts
}
@@ -450,12 +476,12 @@ void MainDialog::OnIdleEvent(wxEvent& event)
void MainDialog::copySelectionToClipboard(const CustomGrid* selectedGrid)
{
- const std::set<int> selectedRows = getSelectedRows(selectedGrid);
+ const std::set<unsigned int> selectedRows = getSelectedRows(selectedGrid);
if (selectedRows.size() > 0)
{
wxString clipboardString;
- for (std::set<int>::const_iterator i = selectedRows.begin(); i != selectedRows.end(); ++i)
+ for (std::set<unsigned int>::const_iterator i = selectedRows.begin(); i != selectedRows.end(); ++i)
{
for (int k = 0; k < const_cast<CustomGrid*>(selectedGrid)->GetNumberCols(); ++k)
{
@@ -479,38 +505,23 @@ void MainDialog::copySelectionToClipboard(const CustomGrid* selectedGrid)
}
-void removeInvalidRows(std::set<int>& rows, const int currentUiTableSize)
+std::set<unsigned int> MainDialog::getSelectedRows(const CustomGrid* grid) const
{
- std::set<int> validRows; //temporal table IS needed here
- for (std::set<int>::iterator i = rows.begin(); i != rows.end(); ++i)
- if (0 <= *i)
- {
- if (*i >= currentUiTableSize) //set is sorted, so no need to continue here
- break;
- validRows.insert(*i);
- }
- rows.swap(validRows);
-}
+ std::set<unsigned int> output = grid->getAllSelectedRows();
-
-std::set<int> MainDialog::getSelectedRows(const CustomGrid* grid) const
-{
- std::set<int> output = grid->getAllSelectedRows();
-
- removeInvalidRows(output, gridDataView->elementsOnView());
+ //remove invalid rows
+ output.erase(output.lower_bound(gridDataView->rowsOnView()), output.end());
return output;
}
-std::set<int> MainDialog::getSelectedRows() const
+std::set<unsigned int> MainDialog::getSelectedRows() const
{
//merge selections from left and right grid
- std::set<int> selection = getSelectedRows(m_gridLeft);
- std::set<int> additional = getSelectedRows(m_gridRight);
- for (std::set<int>::const_iterator i = additional.begin(); i != additional.end(); ++i)
- selection.insert(*i);
-
+ std::set<unsigned int> selection = getSelectedRows(m_gridLeft);
+ std::set<unsigned int> additional = getSelectedRows(m_gridRight);
+ selection.insert(additional.begin(), additional.end());
return selection;
}
@@ -607,22 +618,22 @@ private:
void MainDialog::deleteSelectedFiles()
{
//get set of selected rows on view
- const std::set<int> viewSelectionLeft = getSelectedRows(m_gridLeft);
- const std::set<int> viewSelectionRight = getSelectedRows(m_gridRight);
+ const std::set<unsigned int> viewSelectionLeft = getSelectedRows(m_gridLeft);
+ const std::set<unsigned int> viewSelectionRight = getSelectedRows(m_gridRight);
if (viewSelectionLeft.size() + viewSelectionRight.size())
{
- //map lines from GUI view to grid line references for "currentGridData"
- FolderCompRef compRefLeft;
- gridDataView->viewRefToFolderRef(viewSelectionLeft, compRefLeft);
+ //map lines from GUI view to grid line references
+ std::vector<FileSystemObject*> compRefLeft;
+ gridDataView->getAllFileRef(viewSelectionLeft, compRefLeft);
+
+ std::vector<FileSystemObject*> compRefRight;
+ gridDataView->getAllFileRef(viewSelectionRight, compRefRight);
- FolderCompRef compRefRight;
- gridDataView->viewRefToFolderRef(viewSelectionRight, compRefRight);
int totalDeleteCount = 0;
DeleteDialog* confirmDeletion = new DeleteDialog(this, //no destruction needed; attached to main window
- currentGridData,
compRefLeft,
compRefRight,
globalSettings.gui.deleteOnBothSides,
@@ -636,98 +647,95 @@ void MainDialog::deleteSelectedFiles()
return;
}
- //Attention! Modifying the grid is highly critical! There MUST NOT BE any accesses to gridDataView until this reference table is updated
- //by updateGuiGrid()!! This is easily missed, e.g. when ClearSelection() or ShowModal() or possibly any other wxWidgets function is called
- //that might want to redraw the UI (which implicitly uses the information in gridDataView (see CustomGrid)
- gridDataView->clearView(); //no superfluous precaution: e.g. consider grid update when error message is shown in multiple folder pair scenario!
-
try
{ //handle errors when deleting files/folders
ManualDeletionHandler statusHandler(this, totalDeleteCount);
- assert(compRefLeft.size() == currentGridData.size()); //GridView::viewRefToFolderRef() should ensure this!
- assert(compRefRight.size() == currentGridData.size());
-
- for (FolderComparison::iterator i = currentGridData.begin(); i != currentGridData.end(); ++i)
- {
- const int folderPairNr = i - currentGridData.begin();
-
- const std::set<int>& rowsToDeleteOnLeft = compRefLeft[folderPairNr];
- const std::set<int>& rowsToDeleteOnRight = compRefRight[folderPairNr];
-
- FreeFileSync::deleteFromGridAndHD(i->fileCmp,
- rowsToDeleteOnLeft,
- rowsToDeleteOnRight,
- globalSettings.gui.deleteOnBothSides,
- globalSettings.gui.useRecyclerForManualDeletion,
- currentCfg.mainCfg.syncConfiguration,
- &statusHandler);
- }
-
+ FreeFileSync::deleteFromGridAndHD(gridDataView->getDataTentative(),
+ compRefLeft,
+ compRefRight,
+ globalSettings.gui.deleteOnBothSides,
+ globalSettings.gui.useRecyclerForManualDeletion,
+ getCurrentConfiguration().mainCfg,
+ &statusHandler);
}
catch (FreeFileSync::AbortThisProcess&) {}
+ //remove rows that empty: just a beautification, invalid rows shouldn't cause issues
+ gridDataView->removeInvalidRows();
+
//redraw grid neccessary to update new dimensions and for UI-Backend data linkage
updateGuiGrid(); //call immediately after deleteFromGridAndHD!!!
- m_gridLeft->ClearSelection();
+ m_gridLeft-> ClearSelection();
m_gridMiddle->ClearSelection();
- m_gridRight->ClearSelection();
+ m_gridRight-> ClearSelection();
}
}
}
-void exstractNames(const FileDescrLine& fileDescr, wxString& name, wxString& dir)
+template <SelectedSide side>
+void exstractNames(const FileSystemObject& fsObj, wxString& name, wxString& dir)
{
- switch (fileDescr.objType)
+ if (!fsObj.isEmpty<side>())
+ {
+ const FileMapping* fileObj = dynamic_cast<const FileMapping*>(&fsObj);
+ if (fileObj != NULL)
+ {
+ name = fsObj.getFullName<side>().c_str();
+ dir = name.BeforeLast(globalFunctions::FILE_NAME_SEPARATOR);
+ }
+ else
+ {
+ const DirMapping* dirObj = dynamic_cast<const DirMapping*>(&fsObj);
+ if (dirObj != NULL)
+ {
+ name = fsObj.getFullName<side>().c_str();
+ dir = name;
+ }
+ }
+ }
+ else
{
- case FileDescrLine::TYPE_FILE:
- name = fileDescr.fullName.c_str();
- dir = wxString(fileDescr.fullName.c_str()).BeforeLast(globalFunctions::FILE_NAME_SEPARATOR);
- break;
-
- case FileDescrLine::TYPE_DIRECTORY:
- name = fileDescr.fullName.c_str();
- dir = fileDescr.fullName.c_str();
- break;
-
- case FileDescrLine::TYPE_NOTHING:
name.clear();
dir.clear();
- break;
}
}
-void MainDialog::openWithFileManager(const int rowNumber, const bool leftSide)
+void MainDialog::openExternalApplication(unsigned int rowNumber, bool leftSide, const wxString& commandline)
{
- wxString command = globalSettings.gui.commandLineFileManager;
+ if (commandline.empty())
+ return;
+
+ wxString command = commandline;
wxString name;
wxString dir;
wxString nameCo;
wxString dirCo;
- if (0 <= rowNumber && rowNumber < int(gridDataView->elementsOnView()))
+ const FileSystemObject* fsObj = gridDataView->getObject(rowNumber);
+ if (fsObj)
{
if (leftSide)
{
- exstractNames((*gridDataView)[rowNumber].fileDescrLeft, name, dir);
- exstractNames((*gridDataView)[rowNumber].fileDescrRight, nameCo, dirCo);
+ exstractNames<LEFT_SIDE>( *fsObj, name, dir);
+ exstractNames<RIGHT_SIDE>(*fsObj, nameCo, dirCo);
}
else
{
- exstractNames((*gridDataView)[rowNumber].fileDescrRight, name, dir);
- exstractNames((*gridDataView)[rowNumber].fileDescrLeft, nameCo, dirCo);
+ exstractNames<RIGHT_SIDE>(*fsObj, name, dir);
+ exstractNames<LEFT_SIDE>( *fsObj, nameCo, dirCo);
}
#ifdef FFS_WIN
if (name.empty())
{
if (leftSide)
- wxExecute(wxString(wxT("explorer ")) + gridDataView->getFolderPair(rowNumber).leftDirectory);
+ wxExecute(wxString(wxT("explorer ")) + fsObj->getBaseDirPf<LEFT_SIDE>());
else
- wxExecute(wxString(wxT("explorer ")) + gridDataView->getFolderPair(rowNumber).rightDirectory);
+ wxExecute(wxString(wxT("explorer ")) + fsObj->getBaseDirPf<RIGHT_SIDE>());
return;
}
#endif
@@ -746,10 +754,10 @@ void MainDialog::openWithFileManager(const int rowNumber, const bool leftSide)
#endif
}
+ command.Replace(wxT("%nameCo"), nameCo, true); //attention: replace %nameCo, %dirCo BEFORE %name, %dir to handle dependency
+ command.Replace(wxT("%dirCo"), dirCo, true);
command.Replace(wxT("%name"), name, true);
command.Replace(wxT("%dir"), dir, true);
- command.Replace(wxT("%nameCo"), nameCo, true);
- command.Replace(wxT("%dirCo"), dirCo, true);
wxExecute(command);
}
@@ -902,10 +910,31 @@ void MainDialog::onGridLeftButtonEvent(wxKeyEvent& event)
else if (keyCode == WXK_NUMPAD_ADD) //CTRL + '+'
m_gridLeft->AutoSizeColumns(false);
}
- else if (keyCode == WXK_DELETE || keyCode == WXK_NUMPAD_DELETE)
- deleteSelectedFiles();
+ else
+ switch (keyCode)
+ {
+ case WXK_DELETE:
+ case WXK_NUMPAD_DELETE:
+ deleteSelectedFiles();
+ break;
- event.Skip();
+ case WXK_SPACE:
+ {
+ wxCommandEvent dummy;
+ OnContextFilterTemp(dummy);
+ }
+ break;
+
+ case WXK_RETURN:
+ case WXK_NUMPAD_ENTER:
+ {
+ wxCommandEvent dummy(wxEVT_NULL, externalAppIDFirst); //open with first external application
+ OnContextOpenWith(dummy);
+ }
+ break;
+ }
+
+ //event.Skip(); -> swallow event! don't allow default grid commands!
}
@@ -919,7 +948,7 @@ void MainDialog::onGridMiddleButtonEvent(wxKeyEvent& event)
copySelectionToClipboard(m_gridMiddle);
}
- event.Skip();
+ //event.Skip(); -> swallow event! don't allow default grid commands!
}
@@ -936,13 +965,64 @@ void MainDialog::onGridRightButtonEvent(wxKeyEvent& event)
else if (keyCode == WXK_NUMPAD_ADD) //CTRL + '+'
m_gridRight->AutoSizeColumns(false);
}
- else if (keyCode == WXK_DELETE || keyCode == WXK_NUMPAD_DELETE)
- deleteSelectedFiles();
+ else
+ switch (keyCode)
+ {
+ case WXK_DELETE:
+ case WXK_NUMPAD_DELETE:
+ deleteSelectedFiles();
+ break;
- event.Skip();
+ case WXK_SPACE:
+ {
+ wxCommandEvent dummy;
+ OnContextFilterTemp(dummy);
+ }
+ break;
+
+ case WXK_RETURN:
+ case WXK_NUMPAD_ENTER:
+ {
+ wxCommandEvent dummy(wxEVT_NULL, externalAppIDFirst); //open with first external application
+ OnContextOpenWith(dummy);
+ }
+ break;
+ }
+ //event.Skip(); -> swallow event! don't allow default grid commands!
}
+
+//------------------------------------------------------------
+//temporal variables used by exclude via context menu
+struct SelectedExtension : public wxObject
+{
+ SelectedExtension(const wxString& ext) : extension(ext) {}
+
+ wxString extension;
+};
+
+struct FilterObject
+{
+ FilterObject(const wxString& relName, bool isDirectory) :
+ relativeName(relName),
+ isDir(isDirectory) {}
+ wxString relativeName;
+ bool isDir;
+};
+
+typedef std::vector<FilterObject> FilterObjList;
+
+struct FilterObjContainer : public wxObject
+{
+ FilterObjContainer(const FilterObjList& objList) : selectedObjects(objList) {}
+
+ FilterObjList selectedObjects;
+};
+//------------------------------------------------------------
+
+
+
void MainDialog::OnContextRim(wxGridEvent& event)
{
//usability: select row unter right-click if not already selected
@@ -962,38 +1042,41 @@ void MainDialog::OnContextRim(wxGridEvent& event)
m_gridLeft->ClearSelection();
}
}
-//------------------------------------------------------------------------------
+ //------------------------------------------------------------------------------
- const std::set<int> selectionLeft = getSelectedRows(m_gridLeft);
- const std::set<int> selectionRight = getSelectedRows(m_gridRight);
+ const std::set<unsigned int> selectionLeft = getSelectedRows(m_gridLeft);
+ const std::set<unsigned int> selectionRight = getSelectedRows(m_gridRight);
- const int selectionBegin = selectionLeft.size() + selectionRight.size() == 0 ? 0 :
- selectionLeft.size() == 0 ? *selectionRight.begin() :
- selectionRight.size() == 0 ? *selectionLeft.begin() :
- std::min(*selectionLeft.begin(), *selectionRight.begin());
+ const unsigned int selectionBegin = selectionLeft.size() + selectionRight.size() == 0 ? 0 :
+ selectionLeft.size() == 0 ? *selectionRight.begin() :
+ selectionRight.size() == 0 ? *selectionLeft.begin() :
+ std::min(*selectionLeft.begin(), *selectionRight.begin());
-//#######################################################
+ const FileSystemObject* fsObj = gridDataView->getObject(selectionBegin);
+
+
+ //#######################################################
//re-create context menu
contextMenu.reset(new wxMenu);
if (syncPreview.previewIsEnabled())
{
- if (selectionLeft.size() + selectionRight.size() > 0)
+ if (fsObj && (selectionLeft.size() + selectionRight.size() > 0))
{
//CONTEXT_SYNC_DIR_LEFT
wxMenuItem* menuItemSyncDirLeft = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_LEFT, _("Change direction"));
- menuItemSyncDirLeft->SetBitmap(getSyncOpImage((*gridDataView)[selectionBegin].cmpResult, true, SYNC_DIR_LEFT));
+ menuItemSyncDirLeft->SetBitmap(getSyncOpImage(fsObj->getCategory(), true, SYNC_DIR_LEFT));
contextMenu->Append(menuItemSyncDirLeft);
//CONTEXT_SYNC_DIR_NONE
wxMenuItem* menuItemSyncDirNone = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_NONE, _("Change direction"));
- menuItemSyncDirNone->SetBitmap(getSyncOpImage((*gridDataView)[selectionBegin].cmpResult, true, SYNC_DIR_NONE));
+ menuItemSyncDirNone->SetBitmap(getSyncOpImage(fsObj->getCategory(), true, SYNC_DIR_NONE));
contextMenu->Append(menuItemSyncDirNone);
//CONTEXT_SYNC_DIR_RIGHT
wxMenuItem* menuItemSyncDirRight = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_RIGHT, _("Change direction"));
- menuItemSyncDirRight->SetBitmap(getSyncOpImage((*gridDataView)[selectionBegin].cmpResult, true, SYNC_DIR_RIGHT));
+ menuItemSyncDirRight->SetBitmap(getSyncOpImage(fsObj->getCategory(), true, SYNC_DIR_RIGHT));
contextMenu->Append(menuItemSyncDirRight);
contextMenu->AppendSeparator();
@@ -1002,62 +1085,67 @@ void MainDialog::OnContextRim(wxGridEvent& event)
//CONTEXT_FILTER_TEMP
- if (selectionLeft.size() + selectionRight.size() > 0)
+ if (fsObj && (selectionLeft.size() + selectionRight.size() > 0))
{
- if ((*gridDataView)[selectionBegin].selectedForSynchronization) //valid access, as getSelectedRows returns valid references only
+ if (fsObj->selectedForSynchronization)
{
- wxMenuItem* menuItemExclTemp = new wxMenuItem(contextMenu.get(), CONTEXT_FILTER_TEMP, _("Exclude temporarily"));
+ wxMenuItem* menuItemExclTemp = new wxMenuItem(contextMenu.get(), CONTEXT_FILTER_TEMP, wxString(_("Exclude temporarily")) + wxT("\tSPACE"));
menuItemExclTemp->SetBitmap(*GlobalResources::getInstance().bitmapCheckBoxFalse);
contextMenu->Append(menuItemExclTemp);
}
else
{
- wxMenuItem* menuItemInclTemp = new wxMenuItem(contextMenu.get(), CONTEXT_FILTER_TEMP, _("Include temporarily"));
+ wxMenuItem* menuItemInclTemp = new wxMenuItem(contextMenu.get(), CONTEXT_FILTER_TEMP, wxString(_("Include temporarily")) + wxT("\tSPACE"));
menuItemInclTemp->SetBitmap(*GlobalResources::getInstance().bitmapCheckBoxTrue);
contextMenu->Append(menuItemInclTemp);
}
}
else
{
- contextMenu->Append(CONTEXT_FILTER_TEMP, _("Exclude temporarily")); //this element should always be visible
+ contextMenu->Append(CONTEXT_FILTER_TEMP, wxString(_("Exclude temporarily")) + wxT("\tSPACE")); //this element should always be visible
contextMenu->Enable(CONTEXT_FILTER_TEMP, false);
}
-//###############################################################################################
+ //###############################################################################################
//get list of relative file/dir-names for filtering
- exFilterCandidateObj.clear();
- FilterObject newFilterEntry;
- for (std::set<int>::const_iterator i = selectionLeft.begin(); i != selectionLeft.end(); ++i)
+ FilterObjList exFilterCandidateObj;
+ for (std::set<unsigned int>::const_iterator i = selectionLeft.begin(); i != selectionLeft.end(); ++i)
{
- const FileCompareLine& line = (*gridDataView)[*i];
- newFilterEntry.relativeName = line.fileDescrLeft.relativeName.c_str();
- newFilterEntry.type = line.fileDescrLeft.objType;
- if (!newFilterEntry.relativeName.IsEmpty())
- exFilterCandidateObj.push_back(newFilterEntry);
+ const FileSystemObject* currObj = gridDataView->getObject(*i);
+ if (currObj && !currObj->isEmpty<LEFT_SIDE>())
+ exFilterCandidateObj.push_back(
+ FilterObject(currObj->getRelativeName<LEFT_SIDE>().c_str(),
+ dynamic_cast<const DirMapping*>(currObj) != NULL));
}
- for (std::set<int>::const_iterator i = selectionRight.begin(); i != selectionRight.end(); ++i)
+ for (std::set<unsigned int>::const_iterator i = selectionRight.begin(); i != selectionRight.end(); ++i)
{
- const FileCompareLine& line = (*gridDataView)[*i];
- newFilterEntry.relativeName = line.fileDescrRight.relativeName.c_str();
- newFilterEntry.type = line.fileDescrRight.objType;
- if (!newFilterEntry.relativeName.IsEmpty())
- exFilterCandidateObj.push_back(newFilterEntry);
+ const FileSystemObject* currObj = gridDataView->getObject(*i);
+ if (currObj && !currObj->isEmpty<RIGHT_SIDE>())
+ exFilterCandidateObj.push_back(
+ FilterObject(currObj->getRelativeName<RIGHT_SIDE>().c_str(),
+ dynamic_cast<const DirMapping*>(currObj) != NULL));
}
-//###############################################################################################
+ //###############################################################################################
//CONTEXT_EXCLUDE_EXT
- exFilterCandidateExtension.clear();
- if (exFilterCandidateObj.size() > 0 && exFilterCandidateObj[0].type == FileDescrLine::TYPE_FILE)
+ if (exFilterCandidateObj.size() > 0 && !exFilterCandidateObj[0].isDir)
{
const wxString filename = exFilterCandidateObj[0].relativeName.AfterLast(globalFunctions::FILE_NAME_SEPARATOR);
if (filename.Find(wxChar('.')) != wxNOT_FOUND) //be careful: AfterLast will return the whole string if '.' is not found!
{
- exFilterCandidateExtension = filename.AfterLast(wxChar('.'));
+ const wxString extension = filename.AfterLast(wxChar('.'));
//add context menu item
- wxMenuItem* menuItemExclExt = new wxMenuItem(contextMenu.get(), CONTEXT_EXCLUDE_EXT, wxString(_("Exclude via filter:")) + wxT(" ") + wxT("*.") + exFilterCandidateExtension);
+ wxMenuItem* menuItemExclExt = new wxMenuItem(contextMenu.get(), CONTEXT_EXCLUDE_EXT, wxString(_("Exclude via filter:")) + wxT(" ") + wxT("*.") + extension);
menuItemExclExt->SetBitmap(*GlobalResources::getInstance().bitmapFilterSmall);
contextMenu->Append(menuItemExclExt);
+
+ //connect event
+ contextMenu->Connect(CONTEXT_EXCLUDE_EXT,
+ wxEVT_COMMAND_MENU_SELECTED,
+ wxCommandEventHandler(MainDialog::OnContextExcludeExtension),
+ new SelectedExtension(extension), //ownership passed!
+ this);
}
}
@@ -1073,6 +1161,40 @@ void MainDialog::OnContextRim(wxGridEvent& event)
{
menuItemExclObj->SetBitmap(*GlobalResources::getInstance().bitmapFilterSmall);
contextMenu->Append(menuItemExclObj);
+
+ //connect event
+ contextMenu->Connect(CONTEXT_EXCLUDE_OBJ,
+ wxEVT_COMMAND_MENU_SELECTED,
+ wxCommandEventHandler(MainDialog::OnContextExcludeObject),
+ new FilterObjContainer(exFilterCandidateObj), //ownership passed!
+ this);
+ }
+
+
+
+ //CONTEXT_EXTERNAL_APP
+ if (!globalSettings.gui.externelApplications.empty())
+ {
+ contextMenu->AppendSeparator();
+
+ const bool externalAppEnabled = (m_gridLeft->isLeadGrid() || m_gridRight->isLeadGrid()) &&
+ (selectionLeft.size() + selectionRight.size() == 1);
+
+ int newID = externalAppIDFirst;
+ for (xmlAccess::ExternalApps::iterator i = globalSettings.gui.externelApplications.begin();
+ i != globalSettings.gui.externelApplications.end();
+ ++i, ++newID)
+ {
+ if (i == globalSettings.gui.externelApplications.begin())
+ contextMenu->Append(newID, i->first + wxT("\t") + wxString(_("D-Click")) + wxT("; ENTER"));
+ else
+ contextMenu->Append(newID, i->first.empty() ? wxT(" ") : i->first); //wxWidgets doesn't like empty items
+
+ contextMenu->Enable(newID, externalAppEnabled);
+
+ //register event
+ contextMenu->Connect(newID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextOpenWith), NULL, this);
+ }
}
@@ -1089,18 +1211,6 @@ void MainDialog::OnContextRim(wxGridEvent& event)
contextMenu->Enable(CONTEXT_CLIPBOARD, false);
- //CONTEXT_EXPLORER
- contextMenu->Append(CONTEXT_EXPLORER, _("Open with File Manager\tD-Click"));
-
- if ( (m_gridLeft->isLeadGrid() && selectionLeft.size() <= 1) ||
- (m_gridRight->isLeadGrid() && selectionRight.size() <= 1))
- contextMenu->Enable(CONTEXT_EXPLORER, true);
- else
- contextMenu->Enable(CONTEXT_EXPLORER, false);
-
- contextMenu->AppendSeparator();
-
-
//CONTEXT_DELETE_FILES
contextMenu->Append(CONTEXT_DELETE_FILES, _("Delete files\tDEL"));
@@ -1108,98 +1218,78 @@ void MainDialog::OnContextRim(wxGridEvent& event)
contextMenu->Enable(CONTEXT_DELETE_FILES, false);
-//###############################################################################################
-
- contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextRimSelection), NULL, this);
+ //###############################################################################################
+ //connect events
+ contextMenu->Connect(CONTEXT_FILTER_TEMP, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextFilterTemp), NULL, this);
+ contextMenu->Connect(CONTEXT_CLIPBOARD, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextCopyClipboard), NULL, this);
+ contextMenu->Connect(CONTEXT_DELETE_FILES, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextDeleteFiles), NULL, this);
+ contextMenu->Connect(CONTEXT_SYNC_DIR_LEFT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextSyncDirLeft), NULL, this);
+ contextMenu->Connect(CONTEXT_SYNC_DIR_NONE, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextSyncDirNone), NULL, this);
+ contextMenu->Connect(CONTEXT_SYNC_DIR_RIGHT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextSyncDirRight), NULL, this);
//show context menu
PopupMenu(contextMenu.get());
}
-void MainDialog::OnContextRimSelection(wxCommandEvent& event)
+void MainDialog::OnContextFilterTemp(wxCommandEvent& event)
{
- const ContextIDRim eventId = static_cast<ContextIDRim>(event.GetId());
- switch (eventId)
- {
- case CONTEXT_SYNC_DIR_LEFT:
- {
- //merge selections from left and right grid
- const std::set<int> selection = getSelectedRows();
- setSyncDirManually(selection, FreeFileSync::SYNC_DIR_LEFT);
- }
- break;
-
- case CONTEXT_SYNC_DIR_NONE:
- {
- //merge selections from left and right grid
- const std::set<int> selection = getSelectedRows();
- setSyncDirManually(selection, FreeFileSync::SYNC_DIR_NONE);
- }
- break;
+ //merge selections from left and right grid
+ std::set<unsigned int> selection = getSelectedRows();
+ filterRangeManually(selection, *selection.begin());
+}
- case CONTEXT_SYNC_DIR_RIGHT:
- {
- //merge selections from left and right grid
- const std::set<int> selection = getSelectedRows();
- setSyncDirManually(selection, FreeFileSync::SYNC_DIR_RIGHT);
- }
- break;
- case CONTEXT_FILTER_TEMP:
+void MainDialog::OnContextExcludeExtension(wxCommandEvent& event)
+{
+ SelectedExtension* selExtension = dynamic_cast<SelectedExtension*>(event.m_callbackUserData);
+ if (selExtension)
{
- //merge selections from left and right grid
- std::set<int> selection = getSelectedRows();
- filterRangeManually(selection, *selection.begin());
- }
- break;
-
- case CONTEXT_EXCLUDE_EXT:
- if (!exFilterCandidateExtension.IsEmpty())
- {
- if (!currentCfg.mainCfg.excludeFilter.IsEmpty() && !currentCfg.mainCfg.excludeFilter.EndsWith(wxT(";")))
- currentCfg.mainCfg.excludeFilter+= wxT("\n");
+ if (!currentCfg.mainCfg.excludeFilter.IsEmpty() && !currentCfg.mainCfg.excludeFilter.EndsWith(wxT(";")))
+ currentCfg.mainCfg.excludeFilter += wxT("\n");
- currentCfg.mainCfg.excludeFilter+= wxString(wxT("*.")) + exFilterCandidateExtension + wxT(";"); //';' is appended to 'mark' that next exclude extension entry won't write to new line
+ currentCfg.mainCfg.excludeFilter += wxString(wxT("*.")) + selExtension->extension + wxT(";"); //';' is appended to 'mark' that next exclude extension entry won't write to new line
- currentCfg.mainCfg.filterIsActive = true;
- updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive);
+ currentCfg.mainCfg.filterIsActive = true;
+ updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive);
- FreeFileSync::FilterProcess filterInstance(currentCfg.mainCfg.includeFilter, currentCfg.mainCfg.excludeFilter);
- filterInstance.filterGridData(currentGridData);
+ applyFiltering(getCurrentConfiguration().mainCfg, gridDataView->getDataTentative());
+ updateGuiGrid();
- updateGuiGrid();
- if (currentCfg.hideFilteredElements)
- {
- m_gridLeft->ClearSelection();
- m_gridRight->ClearSelection();
- m_gridMiddle->ClearSelection();
- }
+ if (currentCfg.hideFilteredElements)
+ {
+ m_gridLeft-> ClearSelection();
+ m_gridRight-> ClearSelection();
+ m_gridMiddle->ClearSelection();
}
- break;
+ }
+}
- case CONTEXT_EXCLUDE_OBJ:
- if (exFilterCandidateObj.size() > 0) //check needed to determine if filtering is needed
+
+void MainDialog::OnContextExcludeObject(wxCommandEvent& event)
+{
+ FilterObjContainer* objCont = dynamic_cast<FilterObjContainer*>(event.m_callbackUserData);
+ if (objCont)
+ {
+ if (objCont->selectedObjects.size() > 0) //check needed to determine if filtering is needed
{
- for (std::vector<FilterObject>::const_iterator i = exFilterCandidateObj.begin(); i != exFilterCandidateObj.end(); ++i)
+ for (std::vector<FilterObject>::const_iterator i = objCont->selectedObjects.begin(); i != objCont->selectedObjects.end(); ++i)
{
if (!currentCfg.mainCfg.excludeFilter.IsEmpty() && !currentCfg.mainCfg.excludeFilter.EndsWith(wxT("\n")))
currentCfg.mainCfg.excludeFilter+= wxT("\n");
- if (i->type == FileDescrLine::TYPE_FILE)
+ if (!i->isDir)
currentCfg.mainCfg.excludeFilter+= wxString(globalFunctions::FILE_NAME_SEPARATOR) + i->relativeName;
- else if (i->type == FileDescrLine::TYPE_DIRECTORY)
+ else
currentCfg.mainCfg.excludeFilter+= wxString(globalFunctions::FILE_NAME_SEPARATOR) + i->relativeName + globalFunctions::FILE_NAME_SEPARATOR + wxT("*");
- else assert(false);
}
currentCfg.mainCfg.filterIsActive = true;
updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive);
- FreeFileSync::FilterProcess filterInstance(currentCfg.mainCfg.includeFilter, currentCfg.mainCfg.excludeFilter);
- filterInstance.filterGridData(currentGridData);
-
+ applyFiltering(getCurrentConfiguration().mainCfg, gridDataView->getDataTentative());
updateGuiGrid();
+
if (currentCfg.hideFilteredElements)
{
m_gridLeft->ClearSelection();
@@ -1207,40 +1297,67 @@ void MainDialog::OnContextRimSelection(wxCommandEvent& event)
m_gridMiddle->ClearSelection();
}
}
- break;
+ }
+}
- case CONTEXT_CLIPBOARD:
- if (m_gridLeft->isLeadGrid())
- copySelectionToClipboard(m_gridLeft);
- else if (m_gridRight->isLeadGrid())
- copySelectionToClipboard(m_gridRight);
- break;
- case CONTEXT_EXPLORER:
- if (m_gridLeft->isLeadGrid() || m_gridRight->isLeadGrid())
- {
- const CustomGrid* leadGrid = NULL;
- if (m_gridLeft->isLeadGrid())
- leadGrid = m_gridLeft;
- else
- leadGrid = m_gridRight;
+void MainDialog::OnContextCopyClipboard(wxCommandEvent& event)
+{
+ if (m_gridLeft->isLeadGrid())
+ copySelectionToClipboard(m_gridLeft);
+ else if (m_gridRight->isLeadGrid())
+ copySelectionToClipboard(m_gridRight);
+}
- std::set<int> selection = getSelectedRows(leadGrid);
- if (selection.size() == 1)
- openWithFileManager(*selection.begin(), m_gridLeft->isLeadGrid());
- else if (selection.size() == 0)
- openWithFileManager(-1, m_gridLeft->isLeadGrid());
- }
- break;
+void MainDialog::OnContextOpenWith(wxCommandEvent& event)
+{
+ if (m_gridLeft->isLeadGrid() || m_gridRight->isLeadGrid())
+ {
+ const CustomGrid* leadGrid = m_gridLeft->isLeadGrid() ?
+ static_cast<CustomGrid*>(m_gridLeft) :
+ static_cast<CustomGrid*>(m_gridRight);
+ std::set<unsigned int> selection = getSelectedRows(leadGrid);
- case CONTEXT_DELETE_FILES:
- deleteSelectedFiles();
- break;
+ const int index = event.GetId() - externalAppIDFirst;
+
+ if ( selection.size() == 1 &&
+ 0 <= index && static_cast<unsigned>(index) < globalSettings.gui.externelApplications.size())
+ openExternalApplication(*selection.begin(), m_gridLeft->isLeadGrid(), globalSettings.gui.externelApplications[index].second);
}
}
+void MainDialog::OnContextDeleteFiles(wxCommandEvent& event)
+{
+ deleteSelectedFiles();
+}
+
+
+void MainDialog::OnContextSyncDirLeft(wxCommandEvent& event)
+{
+ //merge selections from left and right grid
+ const std::set<unsigned int> selection = getSelectedRows();
+ setSyncDirManually(selection, FreeFileSync::SYNC_DIR_LEFT);
+}
+
+
+void MainDialog::OnContextSyncDirNone(wxCommandEvent& event)
+{
+ //merge selections from left and right grid
+ const std::set<unsigned int> selection = getSelectedRows();
+ setSyncDirManually(selection, FreeFileSync::SYNC_DIR_NONE);
+}
+
+
+void MainDialog::OnContextSyncDirRight(wxCommandEvent& event)
+{
+ //merge selections from left and right grid
+ const std::set<unsigned int> selection = getSelectedRows();
+ setSyncDirManually(selection, FreeFileSync::SYNC_DIR_RIGHT);
+}
+
+
void MainDialog::OnContextRimLabelLeft(wxGridEvent& event)
{
contextMenu.reset(new wxMenu); //re-create context menu
@@ -1252,7 +1369,9 @@ void MainDialog::OnContextRimLabelLeft(wxGridEvent& event)
contextMenu->Append(itemAutoAdjust);
itemAutoAdjust->Check(globalSettings.gui.autoAdjustColumnsLeft);
- contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextRimLabelSelection), NULL, this);
+ contextMenu->Connect(CONTEXT_CUSTOMIZE_COLUMN_LEFT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextCustColumnLeft), NULL, this);
+ contextMenu->Connect(CONTEXT_AUTO_ADJUST_COLUMN_LEFT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextAutoAdjustLeft), NULL, this);
+
PopupMenu(contextMenu.get()); //show context menu
}
@@ -1268,62 +1387,60 @@ void MainDialog::OnContextRimLabelRight(wxGridEvent& event)
contextMenu->Append(itemAutoAdjust);
itemAutoAdjust->Check(globalSettings.gui.autoAdjustColumnsRight);
- contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextRimLabelSelection), NULL, this);
+ contextMenu->Connect(CONTEXT_CUSTOMIZE_COLUMN_RIGHT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextCustColumnRight), NULL, this);
+ contextMenu->Connect(CONTEXT_AUTO_ADJUST_COLUMN_RIGHT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextAutoAdjustRight), NULL, this);
+
PopupMenu(contextMenu.get()); //show context menu
}
-void MainDialog::OnContextRimLabelSelection(wxCommandEvent& event)
+void MainDialog::OnContextCustColumnLeft(wxCommandEvent& event)
{
- const ContextIDRimLabel eventId = static_cast<ContextIDRimLabel>(event.GetId());
- switch (eventId)
- {
- case CONTEXT_CUSTOMIZE_COLUMN_LEFT:
+ xmlAccess::ColumnAttributes colAttr = m_gridLeft->getColumnAttributes();
+ CustomizeColsDlg* customizeDlg = new CustomizeColsDlg(this, colAttr, globalSettings.gui.showFileIconsLeft);
+ if (customizeDlg->ShowModal() == CustomizeColsDlg::BUTTON_OKAY)
{
- xmlAccess::ColumnAttributes colAttr = m_gridLeft->getColumnAttributes();
- CustomizeColsDlg* customizeDlg = new CustomizeColsDlg(this, colAttr, globalSettings.gui.showFileIconsLeft);
- if (customizeDlg->ShowModal() == CustomizeColsDlg::BUTTON_OKAY)
- {
- m_gridLeft->setColumnAttributes(colAttr);
+ m_gridLeft->setColumnAttributes(colAttr);
#ifdef FFS_WIN
- m_gridLeft->enableFileIcons(globalSettings.gui.showFileIconsLeft);
+ m_gridLeft->enableFileIcons(globalSettings.gui.showFileIconsLeft);
#endif
- m_gridLeft->setSortMarker(CustomGrid::SortMarker(-1, CustomGrid::ASCENDING)); //hide sort direction indicator on GUI grids
- m_gridMiddle->setSortMarker(CustomGrid::SortMarker(-1, CustomGrid::ASCENDING));
- m_gridRight->setSortMarker(CustomGrid::SortMarker(-1, CustomGrid::ASCENDING));
- }
+ m_gridLeft->setSortMarker(CustomGrid::SortMarker(-1, CustomGrid::ASCENDING)); //hide sort direction indicator on GUI grids
+ m_gridMiddle->setSortMarker(CustomGrid::SortMarker(-1, CustomGrid::ASCENDING));
+ m_gridRight->setSortMarker(CustomGrid::SortMarker(-1, CustomGrid::ASCENDING));
}
- break;
+}
- case CONTEXT_CUSTOMIZE_COLUMN_RIGHT:
+
+void MainDialog::OnContextCustColumnRight(wxCommandEvent& event)
+{
+ xmlAccess::ColumnAttributes colAttr = m_gridRight->getColumnAttributes();
+ CustomizeColsDlg* customizeDlg = new CustomizeColsDlg(this, colAttr, globalSettings.gui.showFileIconsRight);
+ if (customizeDlg->ShowModal() == CustomizeColsDlg::BUTTON_OKAY)
{
- xmlAccess::ColumnAttributes colAttr = m_gridRight->getColumnAttributes();
- CustomizeColsDlg* customizeDlg = new CustomizeColsDlg(this, colAttr, globalSettings.gui.showFileIconsRight);
- if (customizeDlg->ShowModal() == CustomizeColsDlg::BUTTON_OKAY)
- {
- m_gridRight->setColumnAttributes(colAttr);
+ m_gridRight->setColumnAttributes(colAttr);
#ifdef FFS_WIN
- m_gridRight->enableFileIcons(globalSettings.gui.showFileIconsRight);
+ m_gridRight->enableFileIcons(globalSettings.gui.showFileIconsRight);
#endif
- m_gridLeft->setSortMarker(CustomGrid::SortMarker(-1, CustomGrid::ASCENDING)); //hide sort direction indicator on GUI grids
- m_gridMiddle->setSortMarker(CustomGrid::SortMarker(-1, CustomGrid::ASCENDING));
- m_gridRight->setSortMarker(CustomGrid::SortMarker(-1, CustomGrid::ASCENDING));
- }
+ m_gridLeft->setSortMarker(CustomGrid::SortMarker(-1, CustomGrid::ASCENDING)); //hide sort direction indicator on GUI grids
+ m_gridMiddle->setSortMarker(CustomGrid::SortMarker(-1, CustomGrid::ASCENDING));
+ m_gridRight->setSortMarker(CustomGrid::SortMarker(-1, CustomGrid::ASCENDING));
}
- break;
+}
- case CONTEXT_AUTO_ADJUST_COLUMN_LEFT:
- globalSettings.gui.autoAdjustColumnsLeft = !globalSettings.gui.autoAdjustColumnsLeft;
- updateGuiGrid();
- break;
- case CONTEXT_AUTO_ADJUST_COLUMN_RIGHT:
- globalSettings.gui.autoAdjustColumnsRight = !globalSettings.gui.autoAdjustColumnsRight;
- updateGuiGrid();
- break;
- }
+void MainDialog::OnContextAutoAdjustLeft(wxCommandEvent& event)
+{
+ globalSettings.gui.autoAdjustColumnsLeft = !globalSettings.gui.autoAdjustColumnsLeft;
+ updateGuiGrid();
+}
+
+
+void MainDialog::OnContextAutoAdjustRight(wxCommandEvent& event)
+{
+ globalSettings.gui.autoAdjustColumnsRight = !globalSettings.gui.autoAdjustColumnsRight;
+ updateGuiGrid();
}
@@ -1334,31 +1451,16 @@ void MainDialog::OnContextMiddle(wxGridEvent& event)
contextMenu->Append(CONTEXT_CHECK_ALL, _("Check all"));
contextMenu->Append(CONTEXT_UNCHECK_ALL, _("Uncheck all"));
- if (gridDataView->refGridIsEmpty())
+ if (gridDataView->rowsTotal() == 0)
{
contextMenu->Enable(CONTEXT_CHECK_ALL, false);
contextMenu->Enable(CONTEXT_UNCHECK_ALL, false);
}
- contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextMiddleSelection), NULL, this);
- PopupMenu(contextMenu.get()); //show context menu
-}
-
+ contextMenu->Connect(CONTEXT_CHECK_ALL, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextIncludeAll), NULL, this);
+ contextMenu->Connect(CONTEXT_UNCHECK_ALL, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextExcludeAll), NULL, this);
-void MainDialog::OnContextMiddleSelection(wxCommandEvent& event)
-{
- const ContextIDMiddle eventId = static_cast<ContextIDMiddle>(event.GetId());
- switch (eventId)
- {
- case CONTEXT_CHECK_ALL:
- FreeFileSync::FilterProcess::includeAllRowsOnGrid(currentGridData);
- refreshGridAfterFilterChange(0); //call this instead of updateGuiGrid() to add some delay if hideFiltered == true and to handle some graphical artifacts break;
- break;
- case CONTEXT_UNCHECK_ALL:
- FreeFileSync::FilterProcess::excludeAllRowsOnGrid(currentGridData);
- refreshGridAfterFilterChange(400); //call this instead of updateGuiGrid() to add some delay if hideFiltered == true and to handle some graphical artifacts
- break;
- }
+ PopupMenu(contextMenu.get()); //show context menu
}
@@ -1377,25 +1479,36 @@ void MainDialog::OnContextMiddleLabel(wxGridEvent& event)
contextMenu->Append(itemCmpResult);
contextMenu->Append(itemSyncPreview);
- contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextMiddleLabelSelection), NULL, this);
+ contextMenu->Connect(CONTEXT_SYNC_PREVIEW, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextSyncView), NULL, this);
+ contextMenu->Connect(CONTEXT_COMPARISON_RESULT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextComparisonView), NULL, this);
+
PopupMenu(contextMenu.get()); //show context menu
}
-void MainDialog::OnContextMiddleLabelSelection(wxCommandEvent& event)
+void MainDialog::OnContextIncludeAll(wxCommandEvent& event)
{
- const ContextIDMiddleLabel eventId = static_cast<ContextIDMiddleLabel>(event.GetId());
- switch (eventId)
- {
- case CONTEXT_COMPARISON_RESULT:
- //change view
- syncPreview.enablePreview(false);
- break;
- case CONTEXT_SYNC_PREVIEW:
- //change view
- syncPreview.enablePreview(true);
- break;
- }
+ FilterProcess::setActiveStatus(true, gridDataView->getDataTentative());
+ refreshGridAfterFilterChange(0); //call this instead of updateGuiGrid() to add some delay if hideFiltered == true and to handle some graphical artifacts break;
+}
+
+
+void MainDialog::OnContextExcludeAll(wxCommandEvent& event)
+{
+ FilterProcess::setActiveStatus(false, gridDataView->getDataTentative());
+ refreshGridAfterFilterChange(400); //call this instead of updateGuiGrid() to add some delay if hideFiltered == true and to handle some graphical artifacts
+}
+
+
+void MainDialog::OnContextComparisonView(wxCommandEvent& event)
+{
+ syncPreview.enablePreview(false); //change view
+}
+
+
+void MainDialog::OnContextSyncView(wxCommandEvent& event)
+{
+ syncPreview.enablePreview(true); //change view
}
@@ -1407,7 +1520,7 @@ void MainDialog::OnDirSelected(wxFileDirPickerEvent& event)
syncPreview.enableSynchronization(false);
//clear grids
- currentGridData.clear();
+ gridDataView->clearAllRows();
updateGuiGrid();
event.Skip();
@@ -1442,7 +1555,7 @@ bool sameFileSpecified(const wxString& file1, const wxString& file2)
const wxString file2Full = getFullFilename(file2);
#ifdef FFS_WIN //don't respect case in windows build
- return FreeFileSync::compareStringsWin32(file1Full.c_str(), file2Full.c_str()) == 0;
+ return file1Full.CmpNoCase(file2Full) == 0;
#elif defined FFS_LINUX
return file1Full == file2Full;
#endif
@@ -1502,7 +1615,7 @@ int findTextPos(const wxArrayString& array, const wxString& text)
{
for (unsigned int i = 0; i < array.GetCount(); ++i)
#ifdef FFS_WIN //don't respect case in windows build
- if (FreeFileSync::compareStringsWin32(array[i].c_str(), text.c_str()) == 0)
+ if (array[i].CmpNoCase(text) == 0)
#elif defined FFS_LINUX
if (array[i] == text)
#endif
@@ -1579,12 +1692,29 @@ bool MainDialog::trySaveConfig() //return true if saved successfully
void MainDialog::OnLoadConfig(wxCommandEvent& event)
{
- wxFileDialog* filePicker = new wxFileDialog(this, wxEmptyString, wxEmptyString, wxEmptyString, wxString(_("FreeFileSync configuration")) + wxT(" (*.ffs_gui)|*.ffs_gui"), wxFD_OPEN);
+ wxFileDialog* filePicker = new wxFileDialog(this,
+ wxEmptyString,
+ wxEmptyString,
+ wxEmptyString,
+ wxString(_("FreeFileSync configuration")) + wxT(" (*.ffs_gui;*.ffs_batch)|*.ffs_gui;*.ffs_batch"), wxFD_OPEN);
+
if (filePicker->ShowModal() == wxID_OK)
loadConfiguration(filePicker->GetPath());
}
+void MainDialog::OnNewConfig(wxCommandEvent& event)
+{
+ if (!saveOldConfig()) //notify user about changed settings
+ return;
+
+ setCurrentConfiguration(xmlAccess::XmlGuiConfig());
+
+ SetTitle(wxString(wxT("FreeFileSync - ")) + _("Folder Comparison and Synchronization"));
+ currentConfigFileName.clear();
+}
+
+
void MainDialog::OnLoadFromHistory(wxCommandEvent& event)
{
const int selectedItem = m_choiceHistory->GetSelection();
@@ -1593,14 +1723,14 @@ void MainDialog::OnLoadFromHistory(wxCommandEvent& event)
}
-void MainDialog::loadConfiguration(const wxString& filename)
+bool MainDialog::saveOldConfig() //return false on user abort
{
//notify user about changed settings
- if (globalSettings.gui.popupOnConfigChange && !currentConfigFileName.empty()) //only if check is active and non-default config file loaded
+ if (globalSettings.optDialogs.popupOnConfigChange && !currentConfigFileName.empty()) //only if check is active and non-default config file loaded
{
if (lastConfigurationSaved != getCurrentConfiguration())
{
- bool dontShowAgain = !globalSettings.gui.popupOnConfigChange;
+ bool dontShowAgain = !globalSettings.optDialogs.popupOnConfigChange;
QuestionDlg* notifyChangeDlg = new QuestionDlg(this,
QuestionDlg::BUTTON_YES | QuestionDlg::BUTTON_NO | QuestionDlg::BUTTON_CANCEL,
@@ -1611,22 +1741,26 @@ void MainDialog::loadConfiguration(const wxString& filename)
{
case QuestionDlg::BUTTON_YES:
if (!trySaveConfig())
- return;
+ return false;
break;
case QuestionDlg::BUTTON_NO:
- globalSettings.gui.popupOnConfigChange = !dontShowAgain;
+ globalSettings.optDialogs.popupOnConfigChange = !dontShowAgain;
break;
case QuestionDlg::BUTTON_CANCEL:
- return;
+ return false;
}
}
}
- //------------------------------------------------------------------------------------
+ return true;
+}
+
+void MainDialog::loadConfiguration(const wxString& filename)
+{
if (!filename.IsEmpty())
- { //clear grids
- currentGridData.clear();
- updateGuiGrid();
+ {
+ if (!saveOldConfig())
+ return;
if (readConfigurationFromXml(filename))
pushStatusInformation(_("Configuration loaded!"));
@@ -1692,44 +1826,17 @@ void MainDialog::OnFolderHistoryKeyEvent(wxKeyEvent& event)
void MainDialog::OnClose(wxCloseEvent &event)
{
- requestShutdown();
-}
-
+ if (!saveOldConfig()) //notify user about changed settings
+ return;
-void MainDialog::OnQuit(wxCommandEvent &event)
-{
- requestShutdown();
+ Destroy();
}
-void MainDialog::requestShutdown()
+void MainDialog::OnQuit(wxCommandEvent &event)
{
- //notify user about changed settings
- if (globalSettings.gui.popupOnConfigChange && !currentConfigFileName.empty()) //only if check is active and non-default config file loaded
- {
- if (lastConfigurationSaved != getCurrentConfiguration())
- {
- bool dontShowAgain = !globalSettings.gui.popupOnConfigChange;
-
- QuestionDlg* notifyChangeDlg = new QuestionDlg(this,
- QuestionDlg::BUTTON_YES | QuestionDlg::BUTTON_NO | QuestionDlg::BUTTON_CANCEL,
- _("Save changes to current configuration?"),
- dontShowAgain);
-
- switch (notifyChangeDlg->ShowModal())
- {
- case QuestionDlg::BUTTON_YES:
- if (!trySaveConfig())
- return;
- break;
- case QuestionDlg::BUTTON_NO:
- globalSettings.gui.popupOnConfigChange = !dontShowAgain;
- break;
- case QuestionDlg::BUTTON_CANCEL:
- return;
- }
- }
- }
+ if (!saveOldConfig()) //notify user about changed settings
+ return;
Destroy();
}
@@ -1742,9 +1849,9 @@ void MainDialog::OnCheckRows(FFSCheckRowsEvent& event)
if (0 <= lowerBound)
{
- std::set<int> selectedRowsOnView;
+ std::set<unsigned int> selectedRowsOnView;
- for (int i = lowerBound; i <= std::min(upperBound, int(gridDataView->elementsOnView()) - 1); ++i)
+ for (int i = lowerBound; i <= std::min(upperBound, int(gridDataView->rowsOnView()) - 1); ++i)
selectedRowsOnView.insert(i);
filterRangeManually(selectedRowsOnView, event.rowFrom);
@@ -1759,10 +1866,14 @@ void MainDialog::OnSetSyncDirection(FFSSyncDirectionEvent& event)
if (0 <= lowerBound)
{
- for (int i = lowerBound; i <= std::min(upperBound, int(gridDataView->elementsOnView()) - 1); ++i)
+ for (int i = lowerBound; i <= std::min(upperBound, int(gridDataView->rowsOnView()) - 1); ++i)
{
- (*gridDataView)[i].syncDir = event.direction;
- (*gridDataView)[i].selectedForSynchronization = true;
+ FileSystemObject* fsObj = gridDataView->getObject(i);
+ if (fsObj)
+ {
+ setSyncDirection(event.direction, *fsObj); //set new direction (recursively)
+ FilterProcess::setActiveStatus(true, *fsObj); //works recursively for directories
+ }
}
updateGuiGrid();
@@ -1774,9 +1885,10 @@ bool MainDialog::readConfigurationFromXml(const wxString& filename, bool program
{
//load XML
xmlAccess::XmlGuiConfig newGuiCfg; //structure to receive gui settings, already defaulted!!
+ bool parsingError = false;
try
{
- xmlAccess::readGuiConfig(filename, newGuiCfg);
+ xmlAccess::readGuiOrBatchConfig(filename, newGuiCfg); //allow reading batch configurations also
}
catch (const xmlAccess::XmlError& error)
{
@@ -1785,7 +1897,10 @@ bool MainDialog::readConfigurationFromXml(const wxString& filename, bool program
else
{
if (error.getSeverity() == xmlAccess::XmlError::WARNING)
+ {
wxMessageBox(error.show(), _("Warning"), wxOK | wxICON_WARNING);
+ parsingError = true;
+ }
else
{
wxMessageBox(error.show(), _("Error"), wxOK | wxICON_ERROR);
@@ -1794,60 +1909,15 @@ bool MainDialog::readConfigurationFromXml(const wxString& filename, bool program
}
}
- currentCfg = newGuiCfg;
-
- //evaluate new settings...
-
- //disable the sync button
- syncPreview.enableSynchronization(false);
-
- //clear grids
- currentGridData.clear();
- updateGuiGrid();
-
- //(re-)set view filter buttons
- gridDataView->resetSettings();
- updateViewFilterButtons();
-
- updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive);
-
- //read folder pairs:
-
- //clear existing pairs first
- FreeFileSync::setDirectoryName(wxEmptyString, m_directoryLeft, m_dirPickerLeft);
- FreeFileSync::setDirectoryName(wxEmptyString, m_directoryRight, m_dirPickerRight);
-
- clearAddFolderPairs();
-
- if (currentCfg.directoryPairs.size() > 0)
- {
- //set main folder pair
- std::vector<FolderPair>::const_iterator main = currentCfg.directoryPairs.begin();
-
- FreeFileSync::setDirectoryName(main->leftDirectory.c_str(), m_directoryLeft, m_dirPickerLeft);
- FreeFileSync::setDirectoryName(main->rightDirectory.c_str(), m_directoryRight, m_dirPickerRight);
-
- addLeftFolderToHistory( main->leftDirectory.c_str()); //another hack: wxCombobox::Insert() asynchronously sends message
- addRightFolderToHistory(main->rightDirectory.c_str()); //overwriting a later wxCombobox::SetValue()!!! :(
-
- //set additional pairs
- addFolderPair(std::vector<FolderPair>(currentCfg.directoryPairs.begin() + 1, currentCfg.directoryPairs.end()));
- }
-
- //read GUI layout
- currentCfg.hideFilteredElements = currentCfg.hideFilteredElements;
- m_checkBoxHideFilt->SetValue(currentCfg.hideFilteredElements);
-
- currentCfg.ignoreErrors = currentCfg.ignoreErrors;
-
- syncPreview.enablePreview(currentCfg.syncPreviewEnabled);
+ setCurrentConfiguration(newGuiCfg);
//###########################################################
addFileToCfgHistory(filename); //put filename on list of last used config files
- lastConfigurationSaved = currentCfg;
+ lastConfigurationSaved = parsingError ? xmlAccess::XmlGuiConfig() : currentCfg; //simulate changed config on parsing errors
- if (filename == lastConfigFileName()) //set title
+ //set title
+ if (filename == lastConfigFileName())
{
SetTitle(wxString(wxT("FreeFileSync - ")) + _("Folder Comparison and Synchronization"));
currentConfigFileName.clear();
@@ -1858,13 +1928,6 @@ bool MainDialog::readConfigurationFromXml(const wxString& filename, bool program
currentConfigFileName = filename;
}
- //update compare variant name
- m_staticTextCmpVariant->SetLabel(wxString(wxT("(")) + getVariantName(currentCfg.mainCfg.compareVar) + wxT(")"));
-
- //update sync variant name
- m_staticTextSyncVariant->SetLabel(wxString(wxT("(")) + currentCfg.mainCfg.syncConfiguration.getVariantName() + wxT(")"));
- bSizer6->Layout(); //adapt layout for variant text
-
return true;
}
@@ -1904,12 +1967,83 @@ bool MainDialog::writeConfigurationToXml(const wxString& filename)
}
+void MainDialog::setCurrentConfiguration(const xmlAccess::XmlGuiConfig& newGuiCfg)
+{
+ currentCfg = newGuiCfg;
+
+ //evaluate new settings...
+
+ //disable the sync button
+ syncPreview.enableSynchronization(false);
+
+ //clear grids
+ gridDataView->clearAllRows();
+ updateGuiGrid();
+
+ //(re-)set view filter buttons
+ initViewFilterButtons();
+
+ updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive);
+
+
+ //read main folder pair
+ const wxString mainFolderLeft = currentCfg.mainCfg.mainFolderPair.leftDirectory.c_str();
+ const wxString mainFolderRight = currentCfg.mainCfg.mainFolderPair.rightDirectory.c_str();
+ FreeFileSync::setDirectoryName(mainFolderLeft, m_directoryLeft, m_dirPickerLeft);
+ FreeFileSync::setDirectoryName(mainFolderRight, m_directoryRight, m_dirPickerRight);
+
+ addLeftFolderToHistory( mainFolderLeft); //another hack: wxCombobox::Insert() asynchronously sends message
+ addRightFolderToHistory(mainFolderRight); //overwriting a later wxCombobox::SetValue()!!! :(
+
+ //clear existing additional folder pairs
+ clearAddFolderPairs();
+
+ //set additional pairs
+ addFolderPair(currentCfg.mainCfg.additionalPairs);
+
+
+ //read GUI layout
+ m_checkBoxHideFilt->SetValue(currentCfg.hideFilteredElements);
+
+ syncPreview.enablePreview(currentCfg.syncPreviewEnabled);
+
+ //###########################################################
+ //update compare variant name
+ m_staticTextCmpVariant->SetLabel(wxString(wxT("(")) + getVariantName(currentCfg.mainCfg.compareVar) + wxT(")"));
+
+ //update sync variant name
+ m_staticTextSyncVariant->SetLabel(wxString(wxT("(")) + currentCfg.mainCfg.getSyncVariantName() + wxT(")"));
+ bSizer6->Layout(); //adapt layout for variant text
+}
+
+
+inline
+FolderPairEnh getEnahncedPair(const FolderPairPanel* panel)
+{
+ return FolderPairEnh(panel->m_directoryLeft->GetValue().c_str(),
+ panel->m_directoryRight->GetValue().c_str(),
+ panel->altSyncConfig,
+ panel->altFilter);
+}
+
+
xmlAccess::XmlGuiConfig MainDialog::getCurrentConfiguration() const
{
xmlAccess::XmlGuiConfig guiCfg = currentCfg;
- //load settings whose ownership lies not in currentCfg
- guiCfg.directoryPairs = getFolderPairs();
+ //load settings whose ownership lies not in currentCfg:
+
+ //main folder pair
+ guiCfg.mainCfg.mainFolderPair.leftDirectory = m_directoryLeft->GetValue().c_str();
+ guiCfg.mainCfg.mainFolderPair.rightDirectory = m_directoryRight->GetValue().c_str();
+
+ //add additional pairs
+ guiCfg.mainCfg.additionalPairs.clear();
+ std::transform(additionalFolderPairs.begin(), additionalFolderPairs.end(),
+ std::back_inserter(guiCfg.mainCfg.additionalPairs), getEnahncedPair);
+
+
+ //sync preview
guiCfg.syncPreviewEnabled = syncPreview.previewIsEnabled();
return guiCfg;
@@ -1936,7 +2070,7 @@ void MainDialog::refreshGridAfterFilterChange(const int delay)
if (currentCfg.hideFilteredElements)
{
wxMilliSleep(delay); //some delay to show user the rows he has filtered out before they are removed
- updateGuiGrid(); //redraw grid to remove excluded elements (keeping sort sequence)
+ updateGuiGrid(); //redraw grid to remove excluded elements (keeping sort sequence)
m_gridLeft->ClearSelection();
m_gridRight->ClearSelection();
@@ -1952,17 +2086,7 @@ void MainDialog::OnFilterButton(wxCommandEvent &event)
//make sure, button-appearance and "filterIsActive" are in sync.
updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive);
- if (currentCfg.mainCfg.filterIsActive)
- {
- FreeFileSync::FilterProcess filterInstance(currentCfg.mainCfg.includeFilter, currentCfg.mainCfg.excludeFilter);
- filterInstance.filterGridData(currentGridData);
- refreshGridAfterFilterChange(400); //call this instead of updateGuiGrid() to add some delay if hideFiltered == true and to handle some graphical artifacts
- }
- else
- {
- FreeFileSync::FilterProcess::includeAllRowsOnGrid(currentGridData);
- refreshGridAfterFilterChange(0); //call this instead of updateGuiGrid() to add some delay if hideFiltered == true and to handle some graphical artifacts }
- }
+ updateFilterConfig(false); //refresh filtering (without changing active-status)
}
@@ -1974,41 +2098,21 @@ void MainDialog::OnHideFilteredButton(wxCommandEvent &event)
m_gridLeft->ClearSelection();
m_gridRight->ClearSelection();
+ updateGuiGrid();
- refreshGridAfterFilterChange(0);
-
- event.Skip();
+// event.Skip();
}
void MainDialog::OnConfigureFilter(wxHyperlinkEvent &event)
{
- const wxString beforeImage = currentCfg.mainCfg.includeFilter + wxChar(1) + currentCfg.mainCfg.excludeFilter;
-
FilterDlg* filterDlg = new FilterDlg(this, currentCfg.mainCfg.includeFilter, currentCfg.mainCfg.excludeFilter);
- if (filterDlg->ShowModal() == FilterDlg::BUTTON_OKAY)
+ if (filterDlg->ShowModal() == FilterDlg::BUTTON_APPLY)
{
- const wxString afterImage = currentCfg.mainCfg.includeFilter + wxChar(1) + currentCfg.mainCfg.excludeFilter;
-
- if (beforeImage != afterImage) //if filter settings are changed: set filtering to "on"
- {
- if (afterImage == (wxString(wxT("*")) + wxChar(1))) //default
- {
- currentCfg.mainCfg.filterIsActive = false;
- FreeFileSync::FilterProcess::includeAllRowsOnGrid(currentGridData);
- }
- else
- {
- currentCfg.mainCfg.filterIsActive = true;
-
- FreeFileSync::FilterProcess filterInstance(currentCfg.mainCfg.includeFilter, currentCfg.mainCfg.excludeFilter);
- filterInstance.filterGridData(currentGridData);
- }
-
- updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive);
-
- updateGuiGrid();
- }
+ if (currentCfg.mainCfg.includeFilter == wxT("*") && currentCfg.mainCfg.excludeFilter.empty()) //default
+ updateFilterConfig(false); //re-apply filter (without changing active-status)
+ else
+ updateFilterConfig(true); //activate(and apply) filter
}
//no event.Skip() here, to not start browser
@@ -2017,269 +2121,193 @@ void MainDialog::OnConfigureFilter(wxHyperlinkEvent &event)
void MainDialog::OnLeftOnlyFiles(wxCommandEvent& event)
{
- gridDataView->leftOnlyFilesActive = !gridDataView->leftOnlyFilesActive;
- updateViewFilterButtons();
+ m_bpButtonLeftOnly->toggle();
updateGuiGrid();
};
+
void MainDialog::OnLeftNewerFiles(wxCommandEvent& event)
{
- gridDataView->leftNewerFilesActive = !gridDataView->leftNewerFilesActive;
- updateViewFilterButtons();
+ m_bpButtonLeftNewer->toggle();
updateGuiGrid();
};
+
void MainDialog::OnDifferentFiles(wxCommandEvent& event)
{
- gridDataView->differentFilesActive = !gridDataView->differentFilesActive;
- updateViewFilterButtons();
+ m_bpButtonDifferent->toggle();
updateGuiGrid();
};
+
void MainDialog::OnRightNewerFiles(wxCommandEvent& event)
{
- gridDataView->rightNewerFilesActive = !gridDataView->rightNewerFilesActive;
- updateViewFilterButtons();
+ m_bpButtonRightNewer->toggle();
updateGuiGrid();
};
+
void MainDialog::OnRightOnlyFiles(wxCommandEvent& event)
{
- gridDataView->rightOnlyFilesActive = !gridDataView->rightOnlyFilesActive;
- updateViewFilterButtons();
+ m_bpButtonRightOnly->toggle();
updateGuiGrid();
};
void MainDialog::OnEqualFiles(wxCommandEvent& event)
{
- gridDataView->equalFilesActive = !gridDataView->equalFilesActive;
- updateViewFilterButtons();
+ m_bpButtonEqual->toggle();
updateGuiGrid();
};
void MainDialog::OnConflictFiles(wxCommandEvent& event)
{
- gridDataView->conflictFilesActive = !gridDataView->conflictFilesActive;
- updateViewFilterButtons();
+ m_bpButtonConflict->toggle();
updateGuiGrid();
};
void MainDialog::OnSyncCreateLeft(wxCommandEvent& event)
{
- gridDataView->syncCreateLeftActive = !gridDataView->syncCreateLeftActive;
- updateViewFilterButtons();
+ m_bpButtonSyncCreateLeft->toggle();
updateGuiGrid();
};
void MainDialog::OnSyncCreateRight(wxCommandEvent& event)
{
- gridDataView->syncCreateRightActive = !gridDataView->syncCreateRightActive;
- updateViewFilterButtons();
+ m_bpButtonSyncCreateRight->toggle();
updateGuiGrid();
};
void MainDialog::OnSyncDeleteLeft(wxCommandEvent& event)
{
- gridDataView->syncDeleteLeftActive = !gridDataView->syncDeleteLeftActive;
- updateViewFilterButtons();
+ m_bpButtonSyncDeleteLeft->toggle();
updateGuiGrid();
};
void MainDialog::OnSyncDeleteRight(wxCommandEvent& event)
{
- gridDataView->syncDeleteRightActive = !gridDataView->syncDeleteRightActive;
- updateViewFilterButtons();
+ m_bpButtonSyncDeleteRight->toggle();
updateGuiGrid();
};
void MainDialog::OnSyncDirLeft(wxCommandEvent& event)
{
- gridDataView->syncDirLeftActive = !gridDataView->syncDirLeftActive;
- updateViewFilterButtons();
+ m_bpButtonSyncDirOverwLeft->toggle();
updateGuiGrid();
};
void MainDialog::OnSyncDirRight(wxCommandEvent& event)
{
- gridDataView->syncDirRightActive = !gridDataView->syncDirRightActive;
- updateViewFilterButtons();
+ m_bpButtonSyncDirOverwRight->toggle();
updateGuiGrid();
};
void MainDialog::OnSyncDirNone(wxCommandEvent& event)
{
- gridDataView->syncDirNoneActive = !gridDataView->syncDirNoneActive;
- updateViewFilterButtons();
+ m_bpButtonSyncDirNone->toggle();
updateGuiGrid();
};
-void MainDialog::updateViewFilterButtons()
+void MainDialog::initViewFilterButtons()
{
//compare result buttons
- if (gridDataView->leftOnlyFilesActive)
- {
- m_bpButtonLeftOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapLeftOnlyAct);
- m_bpButtonLeftOnly->SetToolTip(_("Hide files that exist on left side only"));
- }
- else
- {
- m_bpButtonLeftOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapLeftOnlyDeact);
- m_bpButtonLeftOnly->SetToolTip(_("Show files that exist on left side only"));
- }
-
- if (gridDataView->rightOnlyFilesActive)
- {
- m_bpButtonRightOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapRightOnlyAct);
- m_bpButtonRightOnly->SetToolTip(_("Hide files that exist on right side only"));
- }
- else
- {
- m_bpButtonRightOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapRightOnlyDeact);
- m_bpButtonRightOnly->SetToolTip(_("Show files that exist on right side only"));
- }
-
- if (gridDataView->leftNewerFilesActive)
- {
- m_bpButtonLeftNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapLeftNewerAct);
- m_bpButtonLeftNewer->SetToolTip(_("Hide files that are newer on left"));
- }
- else
- {
- m_bpButtonLeftNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapLeftNewerDeact);
- m_bpButtonLeftNewer->SetToolTip(_("Show files that are newer on left"));
- }
-
- if (gridDataView->rightNewerFilesActive)
- {
- m_bpButtonRightNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapRightNewerAct);
- m_bpButtonRightNewer->SetToolTip(_("Hide files that are newer on right"));
- }
- else
- {
- m_bpButtonRightNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapRightNewerDeact);
- m_bpButtonRightNewer->SetToolTip(_("Show files that are newer on right"));
- }
-
- if (gridDataView->equalFilesActive)
- {
- m_bpButtonEqual->SetBitmapLabel(*GlobalResources::getInstance().bitmapEqualAct);
- m_bpButtonEqual->SetToolTip(_("Hide files that are equal"));
- }
- else
- {
- m_bpButtonEqual->SetBitmapLabel(*GlobalResources::getInstance().bitmapEqualDeact);
- m_bpButtonEqual->SetToolTip(_("Show files that are equal"));
- }
-
- if (gridDataView->differentFilesActive)
- {
- m_bpButtonDifferent->SetBitmapLabel(*GlobalResources::getInstance().bitmapDifferentAct);
- m_bpButtonDifferent->SetToolTip(_("Hide files that are different"));
- }
- else
- {
- m_bpButtonDifferent->SetBitmapLabel(*GlobalResources::getInstance().bitmapDifferentDeact);
- m_bpButtonDifferent->SetToolTip(_("Show files that are different"));
- }
-
- if (gridDataView->conflictFilesActive)
- {
- m_bpButtonConflict->SetBitmapLabel(*GlobalResources::getInstance().bitmapConflictAct);
- m_bpButtonConflict->SetToolTip(_("Hide conflicts"));
- }
- else
- {
- m_bpButtonConflict->SetBitmapLabel(*GlobalResources::getInstance().bitmapConflictDeact);
- m_bpButtonConflict->SetToolTip(_("Show conflicts"));
- }
+ m_bpButtonLeftOnly->init(*GlobalResources::getInstance().bitmapLeftOnlyAct,
+ _("Hide files that exist on left side only"),
+ *GlobalResources::getInstance().bitmapLeftOnlyDeact,
+ _("Show files that exist on left side only"));
+
+ m_bpButtonRightOnly->init(*GlobalResources::getInstance().bitmapRightOnlyAct,
+ _("Hide files that exist on right side only"),
+ *GlobalResources::getInstance().bitmapRightOnlyDeact,
+ _("Show files that exist on right side only"));
+
+ m_bpButtonLeftNewer->init(*GlobalResources::getInstance().bitmapLeftNewerAct,
+ _("Hide files that are newer on left"),
+ *GlobalResources::getInstance().bitmapLeftNewerDeact,
+ _("Show files that are newer on left"));
+
+ m_bpButtonRightNewer->init(*GlobalResources::getInstance().bitmapRightNewerAct,
+ _("Hide files that are newer on right"),
+ *GlobalResources::getInstance().bitmapRightNewerDeact,
+ _("Show files that are newer on right"));
+
+ m_bpButtonEqual->init(*GlobalResources::getInstance().bitmapEqualAct,
+ _("Hide files that are equal"),
+ *GlobalResources::getInstance().bitmapEqualDeact,
+ _("Show files that are equal"));
+
+ m_bpButtonDifferent->init(*GlobalResources::getInstance().bitmapDifferentAct,
+ _("Hide files that are different"),
+ *GlobalResources::getInstance().bitmapDifferentDeact,
+ _("Show files that are different"));
+
+ m_bpButtonConflict->init(*GlobalResources::getInstance().bitmapConflictAct,
+ _("Hide conflicts"),
+ *GlobalResources::getInstance().bitmapConflictDeact,
+ _("Show conflicts"));
//sync preview buttons
- if (gridDataView->syncCreateLeftActive)
- {
- m_bpButtonSyncCreateLeft->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncCreateLeftAct);
- m_bpButtonSyncCreateLeft->SetToolTip(_("Hide files that will be created on the left side"));
- }
- else
- {
- m_bpButtonSyncCreateLeft->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncCreateLeftDeact);
- m_bpButtonSyncCreateLeft->SetToolTip(_("Show files that will be created on the left side"));
- }
-
- if (gridDataView->syncCreateRightActive)
- {
- m_bpButtonSyncCreateRight->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncCreateRightAct);
- m_bpButtonSyncCreateRight->SetToolTip(_("Hide files that will be created on the right side"));
- }
- else
- {
- m_bpButtonSyncCreateRight->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncCreateRightDeact);
- m_bpButtonSyncCreateRight->SetToolTip(_("Show files that will be created on the right side"));
- }
-
- if (gridDataView->syncDeleteLeftActive)
- {
- m_bpButtonSyncDeleteLeft->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncDeleteLeftAct);
- m_bpButtonSyncDeleteLeft->SetToolTip(_("Hide files that will be deleted on the left side"));
- }
- else
- {
- m_bpButtonSyncDeleteLeft->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncDeleteLeftDeact);
- m_bpButtonSyncDeleteLeft->SetToolTip(_("Show files that will be deleted on the left side"));
- }
-
- if (gridDataView->syncDeleteRightActive)
- {
- m_bpButtonSyncDeleteRight->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncDeleteRightAct);
- m_bpButtonSyncDeleteRight->SetToolTip(_("Hide files that will be deleted on the right side"));
- }
- else
- {
- m_bpButtonSyncDeleteRight->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncDeleteRightDeact);
- m_bpButtonSyncDeleteRight->SetToolTip(_("Show files that will be deleted on the right side"));
- }
+ m_bpButtonSyncCreateLeft->init(*GlobalResources::getInstance().bitmapSyncCreateLeftAct,
+ _("Hide files that will be created on the left side"),
+ *GlobalResources::getInstance().bitmapSyncCreateLeftDeact,
+ _("Show files that will be created on the left side"));
+
+ m_bpButtonSyncCreateRight->init(*GlobalResources::getInstance().bitmapSyncCreateRightAct,
+ _("Hide files that will be created on the right side"),
+ *GlobalResources::getInstance().bitmapSyncCreateRightDeact,
+ _("Show files that will be created on the right side"));
+
+ m_bpButtonSyncDeleteLeft->init(*GlobalResources::getInstance().bitmapSyncDeleteLeftAct,
+ _("Hide files that will be deleted on the left side"),
+ *GlobalResources::getInstance().bitmapSyncDeleteLeftDeact,
+ _("Show files that will be deleted on the left side"));
+
+ m_bpButtonSyncDeleteRight->init(*GlobalResources::getInstance().bitmapSyncDeleteRightAct,
+ _("Hide files that will be deleted on the right side"),
+ *GlobalResources::getInstance().bitmapSyncDeleteRightDeact,
+ _("Show files that will be deleted on the right side"));
+
+ m_bpButtonSyncDirOverwLeft->init(*GlobalResources::getInstance().bitmapSyncDirLeftAct,
+ _("Hide files that will be overwritten on left side"),
+ *GlobalResources::getInstance().bitmapSyncDirLeftDeact,
+ _("Show files that will be overwritten on left side"));
+
+ m_bpButtonSyncDirOverwRight->init(*GlobalResources::getInstance().bitmapSyncDirRightAct,
+ _("Hide files that will be overwritten on right side"),
+ *GlobalResources::getInstance().bitmapSyncDirRightDeact,
+ _("Show files that will be overwritten on right side"));
+
+ m_bpButtonSyncDirNone->init(*GlobalResources::getInstance().bitmapSyncDirNoneAct,
+ _("Hide files that won't be copied"),
+ *GlobalResources::getInstance().bitmapSyncDirNoneDeact,
+ _("Show files that won't be copied"));
- if (gridDataView->syncDirLeftActive)
- {
- m_bpButtonSyncDirLeft->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncDirLeftAct);
- m_bpButtonSyncDirLeft->SetToolTip(_("Hide files that will be copied to the left side"));
- }
- else
- {
- m_bpButtonSyncDirLeft->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncDirLeftDeact);
- m_bpButtonSyncDirLeft->SetToolTip(_("Show files that will be copied to the left side"));
- }
-
- if (gridDataView->syncDirRightActive)
- {
- m_bpButtonSyncDirRight->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncDirRightAct);
- m_bpButtonSyncDirRight->SetToolTip(_("Hide files that will be copied to the right side"));
- }
- else
- {
- m_bpButtonSyncDirRight->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncDirRightDeact);
- m_bpButtonSyncDirRight->SetToolTip(_("Show files that will be copied to the right side"));
- }
+ //compare result buttons
+ m_bpButtonLeftOnly-> setActive(true);
+ m_bpButtonRightOnly-> setActive(true);
+ m_bpButtonLeftNewer-> setActive(true);
+ m_bpButtonRightNewer->setActive(true);
+ m_bpButtonEqual-> setActive(false);
+ m_bpButtonDifferent-> setActive(true);
+ m_bpButtonConflict-> setActive(true);
- if (gridDataView->syncDirNoneActive)
- {
- m_bpButtonSyncDirNone->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncDirNoneAct);
- m_bpButtonSyncDirNone->SetToolTip(_("Hide files that won't be copied"));
- }
- else
- {
- m_bpButtonSyncDirNone->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncDirNoneDeact);
- m_bpButtonSyncDirNone->SetToolTip(_("Show files that won't be copied"));
- }
+ //sync preview buttons
+ m_bpButtonSyncCreateLeft-> setActive(true);
+ m_bpButtonSyncCreateRight-> setActive(true);
+ m_bpButtonSyncDeleteLeft-> setActive(true);
+ m_bpButtonSyncDeleteRight-> setActive(true);
+ m_bpButtonSyncDirOverwLeft-> setActive(true);
+ m_bpButtonSyncDirOverwRight->setActive(true);
+ m_bpButtonSyncDirNone-> setActive(true);
}
@@ -2311,34 +2339,15 @@ void MainDialog::updateFilterButton(wxBitmapButton* filterButton, bool isActive)
}
-std::vector<FolderPair> MainDialog::getFolderPairs() const
-{
- std::vector<FolderPair> output;
-
- //add main pair
- output.push_back(FolderPair(m_directoryLeft->GetValue().c_str(),
- m_directoryRight->GetValue().c_str()));
-
- //add additional pairs
- for (std::vector<FolderPairPanel*>::const_iterator i = additionalFolderPairs.begin(); i != additionalFolderPairs.end(); ++i)
- output.push_back(FolderPair((*i)->m_directoryLeft->GetValue().c_str(),
- (*i)->m_directoryRight->GetValue().c_str()));
- return output;
-}
-
-
void MainDialog::OnCompare(wxCommandEvent &event)
{
//PERF_START;
-
clearStatusBar();
wxBusyCursor dummy; //show hourglass cursor
- //1. prevent temporary memory peak by clearing old result list
- //2. ATTENTION: wxAPP->Yield() will be called in the following!
- // when comparing there will be a mismatch "gridDataView <-> currentGridData": make sure gridDataView does NOT access currentGridData!!!
- currentGridData.clear();
+ //prevent temporary memory peak by clearing old result list
+ gridDataView->clearAllRows();
updateGuiGrid(); //refresh GUI grid
bool aborted = false;
@@ -2346,29 +2355,22 @@ void MainDialog::OnCompare(wxCommandEvent &event)
{ //class handling status display and error messages
CompareStatusHandler statusHandler(this);
- //prepare filter
- std::auto_ptr<FreeFileSync::FilterProcess> filterInstance(NULL);
- if (currentCfg.mainCfg.filterIsActive)
- filterInstance.reset(new FreeFileSync::FilterProcess(currentCfg.mainCfg.includeFilter, currentCfg.mainCfg.excludeFilter));
-
//begin comparison
- FreeFileSync::CompareProcess comparison(globalSettings.traverseDirectorySymlinks,
- globalSettings.fileTimeTolerance,
+ FreeFileSync::CompareProcess comparison(currentCfg.mainCfg.hidden.traverseDirectorySymlinks,
+ currentCfg.mainCfg.hidden.fileTimeTolerance,
globalSettings.ignoreOneHourDiff,
- globalSettings.warnings,
- filterInstance.get(),
+ globalSettings.optDialogs,
&statusHandler);
- comparison.startCompareProcess(getFolderPairs(),
- currentCfg.mainCfg.compareVar,
- currentCfg.mainCfg.syncConfiguration,
- currentGridData);
+ //technical representation of comparison data
+ FreeFileSync::FolderComparison newCompareData;
- //if (output.size < 50000)
- statusHandler.updateStatusText(_("Sorting file list..."));
- statusHandler.forceUiRefresh(); //keep total number of scanned files up to date
+ comparison.startCompareProcess(
+ FreeFileSync::extractCompareCfg(getCurrentConfiguration().mainCfg), //call getCurrentCfg() to get current values for directory pairs!
+ currentCfg.mainCfg.compareVar,
+ newCompareData);
- gridDataView->sortView(GridView::SORT_BY_DIRECTORY, true, true);
+ gridDataView->setData(newCompareData); //newCompareData is invalidated after this call
}
catch (AbortThisProcess&)
{
@@ -2394,9 +2396,9 @@ void MainDialog::OnCompare(wxCommandEvent &event)
lastSortColumn = -1;
lastSortGrid = NULL;
- m_gridLeft->ClearSelection();
+ m_gridLeft-> ClearSelection();
m_gridMiddle->ClearSelection();
- m_gridRight->ClearSelection();
+ m_gridRight-> ClearSelection();
//add to folder history after successful comparison only
addLeftFolderToHistory(m_directoryLeft->GetValue());
@@ -2416,8 +2418,8 @@ void MainDialog::updateGuiGrid()
updateGridViewData(); //update gridDataView and write status information
- //all three grids retrieve their data directly via gridDataView(which knows currentGridData)!!!
- //the only thing left to do is notify the grids to update their sizes (nr of rows), since this has to be communicated by the grids via messages
+ //all three grids retrieve their data directly via gridDataView
+ //the only thing left to do is notify the grids to updafte their sizes (nr of rows), since this has to be communicated by the grids via messages
m_gridLeft ->updateGridSizes();
m_gridMiddle->updateGridSizes();
m_gridRight ->updateGridSizes();
@@ -2454,7 +2456,7 @@ void MainDialog::updateGuiGrid()
void MainDialog::calculatePreview()
{
//update preview of bytes to be transferred:
- const SyncStatistics st(currentGridData);
+ const SyncStatistics st(gridDataView->getDataTentative());
const wxString toCreate = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(st.getCreate()));
const wxString toUpdate = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(st.getOverwrite()));
const wxString toDelete = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(st.getDelete()));
@@ -2476,16 +2478,15 @@ void MainDialog::OnSwitchView(wxCommandEvent& event)
void MainDialog::OnSyncSettings(wxCommandEvent& event)
{
- SyncCfgDialog* syncDlg = new SyncCfgDialog(this, currentGridData, currentCfg.mainCfg, currentCfg.ignoreErrors);
- if (syncDlg->ShowModal() == SyncCfgDialog::BUTTON_OKAY)
+ SyncCfgDialog* syncDlg = new SyncCfgDialog(this,
+ currentCfg.mainCfg.compareVar,
+ currentCfg.mainCfg.syncConfiguration,
+ currentCfg.mainCfg.handleDeletion,
+ currentCfg.mainCfg.customDeletionDirectory,
+ &currentCfg.ignoreErrors);
+ if (syncDlg->ShowModal() == SyncCfgDialog::BUTTON_APPLY)
{
- //update sync variant name
- m_staticTextSyncVariant->SetLabel(wxString(wxT("(")) + currentCfg.mainCfg.syncConfiguration.getVariantName() + wxT(")"));
- bSizer6->Layout(); //adapt layout for variant text
-
- redetermineSyncDirection(currentCfg.mainCfg.syncConfiguration, currentGridData);
-
- updateGuiGrid();
+ updateSyncConfig();
}
}
@@ -2494,7 +2495,11 @@ void MainDialog::OnCmpSettings(wxCommandEvent& event)
{
CompareVariant newCmpVariant = currentCfg.mainCfg.compareVar;
- CompareCfgDialog* syncDlg = new CompareCfgDialog(this, newCmpVariant);
+ //show window right next to the compare-config button
+ wxPoint windowPos = m_bpButtonCmpConfig->GetScreenPosition();
+ windowPos.x += m_bpButtonCmpConfig->GetSize().GetWidth() + 5;
+
+ CompareCfgDialog* syncDlg = new CompareCfgDialog(this, windowPos, newCmpVariant);
if (syncDlg->ShowModal() == CompareCfgDialog::BUTTON_OKAY)
{
if (currentCfg.mainCfg.compareVar != newCmpVariant)
@@ -2509,7 +2514,7 @@ void MainDialog::OnCmpSettings(wxCommandEvent& event)
syncPreview.enableSynchronization(false);
//clear grids
- currentGridData.clear();
+ gridDataView->clearAllRows();
updateGuiGrid();
m_buttonCompare->SetFocus();
@@ -2523,24 +2528,24 @@ void MainDialog::OnStartSync(wxCommandEvent& event)
if (syncPreview.synchronizationIsEnabled())
{
//show sync preview screen
- if (globalSettings.gui.showSummaryBeforeSync)
+ if (globalSettings.optDialogs.showSummaryBeforeSync)
{
bool dontShowAgain = false;
SyncPreviewDlg* preview = new SyncPreviewDlg(
this,
- currentCfg.mainCfg.syncConfiguration.getVariantName(),
- FreeFileSync::SyncStatistics(currentGridData),
+ getCurrentConfiguration().mainCfg.getSyncVariantName(),
+ FreeFileSync::SyncStatistics(gridDataView->getDataTentative()),
dontShowAgain);
if (preview->ShowModal() != SyncPreviewDlg::BUTTON_START)
return;
- globalSettings.gui.showSummaryBeforeSync = !dontShowAgain;
+ globalSettings.optDialogs.showSummaryBeforeSync = !dontShowAgain;
}
//check if there are files/folders to be sync'ed at all
- if (!synchronizationNeeded(currentGridData))
+ if (!synchronizationNeeded(gridDataView->getDataTentative()))
{
wxMessageBox(_("Nothing to synchronize according to configuration!"), _("Information"), wxICON_WARNING);
return;
@@ -2548,62 +2553,60 @@ void MainDialog::OnStartSync(wxCommandEvent& event)
wxBusyCursor dummy; //show hourglass cursor
- //ATTENTION: wxAPP->Yield() will be called in the following!
- //when sync'ing there will be a mismatch "gridDataView <-> currentGridData": make sure gridDataView does NOT access currentGridData!!!
- gridDataView->clearView();
-
clearStatusBar();
try
{
+ //PERF_START;
+
//class handling status updates and error messages
SyncStatusHandler statusHandler(this, currentCfg.ignoreErrors);
- //start synchronization and return elements that were not sync'ed in currentGridData
+ //start synchronization and mark all elements processed
FreeFileSync::SyncProcess synchronization(
- currentCfg.mainCfg.handleDeletion,
- currentCfg.mainCfg.customDeletionDirectory,
- globalSettings.copyFileSymlinks,
- globalSettings.traverseDirectorySymlinks,
- globalSettings.warnings,
+ currentCfg.mainCfg.hidden.copyFileSymlinks,
+ currentCfg.mainCfg.hidden.traverseDirectorySymlinks,
+ globalSettings.optDialogs,
+ currentCfg.mainCfg.hidden.verifyFileCopy,
&statusHandler);
- synchronization.startSynchronizationProcess(currentGridData);
+ const std::vector<FreeFileSync::FolderPairSyncCfg> syncProcessCfg = FreeFileSync::extractSyncCfg(getCurrentConfiguration().mainCfg);
+ FolderComparison& dataToSync = gridDataView->getDataTentative();
+
+ //make sure syncProcessCfg and dataToSync have same size and correspond!
+ if (syncProcessCfg.size() != dataToSync.size())
+ throw std::logic_error("Programming Error: Contract violation!"); //should never happen: sync button is deactivated if they are not in sync
+
+ synchronization.startSynchronizationProcess(syncProcessCfg, dataToSync);
}
catch (AbortThisProcess&)
{ //do NOT disable the sync button: user might want to try to sync the REMAINING rows
} //enableSynchronization(false);
+ //remove rows that empty: just a beautification, invalid rows shouldn't cause issues
+ gridDataView->removeInvalidRows();
- //show remaining files that have not been processed: put DIRECTLY after startSynchronizationProcess() and DON'T call any wxWidgets functions
- //in between! Else CustomGrid might access obsolete data entries in currentGridData!
updateGuiGrid();
- m_gridLeft->ClearSelection();
+ m_gridLeft-> ClearSelection();
m_gridMiddle->ClearSelection();
- m_gridRight->ClearSelection();
-
- if (!gridDataView->refGridIsEmpty())
- pushStatusInformation(_("Not all items have been synchronized! Have a look at the list."));
- else
- {
- pushStatusInformation(_("All items have been synchronized!"));
- syncPreview.enableSynchronization(false);
- }
+ m_gridRight-> ClearSelection();
}
}
void MainDialog::OnLeftGridDoubleClick(wxGridEvent& event)
{
- openWithFileManager(event.GetRow(), true);
- event.Skip();
+ if (!globalSettings.gui.externelApplications.empty())
+ openExternalApplication(event.GetRow(), true, globalSettings.gui.externelApplications[0].second);
+ // event.Skip();
}
void MainDialog::OnRightGridDoubleClick(wxGridEvent& event)
{
- openWithFileManager(event.GetRow(), false);
- event.Skip();
+ if (!globalSettings.gui.externelApplications.empty())
+ openExternalApplication(event.GetRow(), false, globalSettings.gui.externelApplications[0].second);
+// event.Skip();
}
@@ -2743,27 +2746,38 @@ void MainDialog::OnSwapSides(wxCommandEvent& event)
m_directoryRight->SetValue(leftDir);
//additional pairs
- wxString tmp;
for (std::vector<FolderPairPanel*>::const_iterator i = additionalFolderPairs.begin(); i != additionalFolderPairs.end(); ++i)
{
FolderPairPanel* dirPair = *i;
- tmp = dirPair->m_directoryLeft->GetValue();
+ wxString tmp = dirPair->m_directoryLeft->GetValue();
dirPair->m_directoryLeft->SetValue(dirPair->m_directoryRight->GetValue());
dirPair->m_directoryRight->SetValue(tmp);
}
//swap view filter
- std::swap(gridDataView->leftOnlyFilesActive, gridDataView->rightOnlyFilesActive);
- std::swap(gridDataView->leftNewerFilesActive, gridDataView->rightNewerFilesActive);
+ bool tmp = m_bpButtonLeftOnly->isActive();
+ m_bpButtonLeftOnly->setActive(m_bpButtonRightOnly->isActive());
+ m_bpButtonRightOnly->setActive(tmp);
+
+ tmp = m_bpButtonLeftNewer->isActive();
+ m_bpButtonLeftNewer->setActive(m_bpButtonRightNewer->isActive());
+ m_bpButtonRightNewer->setActive(tmp);
+
- std::swap(gridDataView->syncCreateLeftActive, gridDataView->syncCreateRightActive);
- std::swap(gridDataView->syncDirLeftActive, gridDataView->syncDirRightActive);
- std::swap(gridDataView->syncDeleteLeftActive, gridDataView->syncDeleteRightActive);
+ tmp = m_bpButtonSyncCreateLeft->isActive();
+ m_bpButtonSyncCreateLeft->setActive(m_bpButtonSyncCreateRight->isActive());
+ m_bpButtonSyncCreateRight->setActive(tmp);
- updateViewFilterButtons();
+ tmp = m_bpButtonSyncDeleteLeft->isActive();
+ m_bpButtonSyncDeleteLeft->setActive(m_bpButtonSyncDeleteRight->isActive());
+ m_bpButtonSyncDeleteRight->setActive(tmp);
+
+ tmp = m_bpButtonSyncDirOverwLeft->isActive();
+ m_bpButtonSyncDirOverwLeft->setActive(m_bpButtonSyncDirOverwRight->isActive());
+ m_bpButtonSyncDirOverwRight->setActive(tmp);
//swap grid information
- FreeFileSync::swapGrids(currentCfg.mainCfg.syncConfiguration, currentGridData);
+ FreeFileSync::swapGrids2(getCurrentConfiguration().mainCfg, gridDataView->getDataTentative());
updateGuiGrid();
event.Skip();
}
@@ -2771,103 +2785,120 @@ void MainDialog::OnSwapSides(wxCommandEvent& event)
void MainDialog::updateGridViewData()
{
- const GridView::StatusInfo result = gridDataView->update(currentCfg.hideFilteredElements, syncPreview.previewIsEnabled());
-
- //hide or enable view filter buttons
-
- //comparison result view buttons
- if (result.existsLeftOnly)
- m_bpButtonLeftOnly->Show();
- else
- m_bpButtonLeftOnly->Hide();
-
- if (result.existsRightOnly)
- m_bpButtonRightOnly->Show();
- else
- m_bpButtonRightOnly->Hide();
-
- if (result.existsLeftNewer)
- m_bpButtonLeftNewer->Show();
- else
- m_bpButtonLeftNewer->Hide();
-
- if (result.existsRightNewer)
- m_bpButtonRightNewer->Show();
- else
- m_bpButtonRightNewer->Hide();
+ unsigned int filesOnLeftView = 0;
+ unsigned int foldersOnLeftView = 0;
+ unsigned int filesOnRightView = 0;
+ unsigned int foldersOnRightView = 0;
+ wxULongLong filesizeLeftView;
+ wxULongLong filesizeRightView;
- if (result.existsDifferent)
- m_bpButtonDifferent->Show();
- else
- m_bpButtonDifferent->Hide();
-
- if (result.existsEqual)
- m_bpButtonEqual->Show();
- else
- m_bpButtonEqual->Hide();
-
- if (result.existsConflict)
- m_bpButtonConflict->Show();
- else
- m_bpButtonConflict->Hide();
-
- //sync preview buttons
- if (result.existsSyncCreateLeft)
- m_bpButtonSyncCreateLeft->Show();
- else
- m_bpButtonSyncCreateLeft->Hide();
-
- if (result.existsSyncCreateRight)
- m_bpButtonSyncCreateRight->Show();
- else
- m_bpButtonSyncCreateRight->Hide();
+ //disable all buttons per default
+ m_bpButtonLeftOnly-> Show(false);
+ m_bpButtonRightOnly-> Show(false);
+ m_bpButtonLeftNewer-> Show(false);
+ m_bpButtonRightNewer->Show(false);
+ m_bpButtonDifferent-> Show(false);
+ m_bpButtonEqual-> Show(false);
+ m_bpButtonConflict-> Show(false);
- if (result.existsSyncDeleteLeft)
- m_bpButtonSyncDeleteLeft->Show();
- else
- m_bpButtonSyncDeleteLeft->Hide();
+ m_bpButtonSyncCreateLeft-> Show(false);
+ m_bpButtonSyncCreateRight-> Show(false);
+ m_bpButtonSyncDeleteLeft-> Show(false);
+ m_bpButtonSyncDeleteRight-> Show(false);
+ m_bpButtonSyncDirOverwLeft-> Show(false);
+ m_bpButtonSyncDirOverwRight->Show(false);
+ m_bpButtonSyncDirNone-> Show(false);
- if (result.existsSyncDeleteRight)
- m_bpButtonSyncDeleteRight->Show();
- else
- m_bpButtonSyncDeleteRight->Hide();
- if (result.existsSyncDirLeft)
- m_bpButtonSyncDirLeft->Show();
- else
- m_bpButtonSyncDirLeft->Hide();
- if (result.existsSyncDirRight)
- m_bpButtonSyncDirRight->Show();
- else
- m_bpButtonSyncDirRight->Hide();
+ if (syncPreview.previewIsEnabled())
+ {
+ const GridView::StatusSyncPreview result = gridDataView->updateSyncPreview(currentCfg.hideFilteredElements,
+ m_bpButtonSyncCreateLeft-> isActive(),
+ m_bpButtonSyncCreateRight-> isActive(),
+ m_bpButtonSyncDeleteLeft-> isActive(),
+ m_bpButtonSyncDeleteRight-> isActive(),
+ m_bpButtonSyncDirOverwLeft-> isActive(),
+ m_bpButtonSyncDirOverwRight->isActive(),
+ m_bpButtonSyncDirNone-> isActive(),
+ m_bpButtonConflict-> isActive());
+
+ filesOnLeftView = result.filesOnLeftView;
+ foldersOnLeftView = result.foldersOnLeftView;
+ filesOnRightView = result.filesOnRightView;
+ foldersOnRightView = result.foldersOnRightView;
+ filesizeLeftView = result.filesizeLeftView;
+ filesizeRightView = result.filesizeRightView;
+
+
+ //sync preview buttons
+ m_bpButtonSyncCreateLeft-> Show(result.existsSyncCreateLeft);
+ m_bpButtonSyncCreateRight-> Show(result.existsSyncCreateRight);
+ m_bpButtonSyncDeleteLeft-> Show(result.existsSyncDeleteLeft);
+ m_bpButtonSyncDeleteRight-> Show(result.existsSyncDeleteRight);
+ m_bpButtonSyncDirOverwLeft-> Show(result.existsSyncDirLeft);
+ m_bpButtonSyncDirOverwRight->Show(result.existsSyncDirRight);
+ m_bpButtonSyncDirNone-> Show(result.existsSyncDirNone);
+ m_bpButtonConflict-> Show(result.existsConflict);
+
+ if ( m_bpButtonSyncCreateLeft-> IsShown() ||
+ m_bpButtonSyncCreateRight-> IsShown() ||
+ m_bpButtonSyncDeleteLeft-> IsShown() ||
+ m_bpButtonSyncDeleteRight-> IsShown() ||
+ m_bpButtonSyncDirOverwLeft-> IsShown() ||
+ m_bpButtonSyncDirOverwRight->IsShown() ||
+ m_bpButtonSyncDirNone-> IsShown() ||
+ m_bpButtonConflict-> IsShown())
+ {
+ m_panel112->Show();
+ m_panel112->Layout();
+ }
+ else
+ m_panel112->Hide();
- if (result.existsSyncDirNone)
- m_bpButtonSyncDirNone->Show();
- else
- m_bpButtonSyncDirNone->Hide();
-
-
- if ( result.existsLeftOnly ||
- result.existsRightOnly ||
- result.existsLeftNewer ||
- result.existsRightNewer ||
- result.existsDifferent ||
- result.existsEqual ||
- result.existsConflict ||
- result.existsSyncCreateLeft ||
- result.existsSyncCreateRight ||
- result.existsSyncDeleteLeft ||
- result.existsSyncDeleteRight ||
- result.existsSyncDirLeft ||
- result.existsSyncDirRight ||
- result.existsSyncDirNone)
- {
- m_panel112->Show();
- m_panel112->Layout();
}
else
- m_panel112->Hide();
+ {
+ const GridView::StatusCmpResult result = gridDataView->updateCmpResult(currentCfg.hideFilteredElements,
+ m_bpButtonLeftOnly-> isActive(),
+ m_bpButtonRightOnly-> isActive(),
+ m_bpButtonLeftNewer-> isActive(),
+ m_bpButtonRightNewer->isActive(),
+ m_bpButtonDifferent-> isActive(),
+ m_bpButtonEqual-> isActive(),
+ m_bpButtonConflict-> isActive());
+
+ filesOnLeftView = result.filesOnLeftView;
+ foldersOnLeftView = result.foldersOnLeftView;
+ filesOnRightView = result.filesOnRightView;
+ foldersOnRightView = result.foldersOnRightView;
+ filesizeLeftView = result.filesizeLeftView;
+ filesizeRightView = result.filesizeRightView;
+
+ //comparison result view buttons
+ m_bpButtonLeftOnly-> Show(result.existsLeftOnly);
+ m_bpButtonRightOnly-> Show(result.existsRightOnly);
+ m_bpButtonLeftNewer-> Show(result.existsLeftNewer);
+ m_bpButtonRightNewer->Show(result.existsRightNewer);
+ m_bpButtonDifferent-> Show(result.existsDifferent);
+ m_bpButtonEqual-> Show(result.existsEqual);
+ m_bpButtonConflict-> Show(result.existsConflict);
+
+ if ( m_bpButtonLeftOnly-> IsShown() ||
+ m_bpButtonRightOnly-> IsShown() ||
+ m_bpButtonLeftNewer-> IsShown() ||
+ m_bpButtonRightNewer->IsShown() ||
+ m_bpButtonDifferent-> IsShown() ||
+ m_bpButtonEqual-> IsShown() ||
+ m_bpButtonConflict-> IsShown())
+ {
+ m_panel112->Show();
+ m_panel112->Layout();
+ }
+ else
+ m_panel112->Hide();
+ }
+
bSizer3->Layout();
@@ -2884,41 +2915,41 @@ void MainDialog::updateGridViewData()
//format numbers to text:
//show status information on "root" level.
- if (result.foldersOnLeftView)
+ if (foldersOnLeftView)
{
- if (result.foldersOnLeftView == 1)
+ if (foldersOnLeftView == 1)
statusLeftNew += _("1 directory");
else
{
- wxString folderCount = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(result.foldersOnLeftView));
+ wxString folderCount = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(foldersOnLeftView));
wxString outputString = _("%x directories");
outputString.Replace(wxT("%x"), folderCount, false);
statusLeftNew += outputString;
}
- if (result.filesOnLeftView)
+ if (filesOnLeftView)
statusLeftNew += wxT(", ");
}
- if (result.filesOnLeftView)
+ if (filesOnLeftView)
{
- if (result.filesOnLeftView == 1)
+ if (filesOnLeftView == 1)
statusLeftNew += _("1 file,");
else
{
- wxString fileCount = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(result.filesOnLeftView));
+ wxString fileCount = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(filesOnLeftView));
wxString outputString = _("%x files,");
outputString.Replace(wxT("%x"), fileCount, false);
statusLeftNew += outputString;
}
statusLeftNew += wxT(" ");
- statusLeftNew += FreeFileSync::formatFilesizeToShortString(result.filesizeLeftView);
+ statusLeftNew += FreeFileSync::formatFilesizeToShortString(filesizeLeftView);
}
- const wxString objectsView = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(gridDataView->elementsOnView()));
- if (result.objectsTotal == 1)
+ const wxString objectsView = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(gridDataView->rowsOnView()));
+ if (gridDataView->rowsTotal() == 1)
{
wxString outputString = _("%x of 1 row in view");
outputString.Replace(wxT("%x"), objectsView, false);
@@ -2926,7 +2957,7 @@ void MainDialog::updateGridViewData()
}
else
{
- const wxString objectsTotal = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(result.objectsTotal));
+ const wxString objectsTotal = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(gridDataView->rowsTotal()));
wxString outputString = _("%x of %y rows in view");
outputString.Replace(wxT("%x"), objectsView, false);
@@ -2934,30 +2965,30 @@ void MainDialog::updateGridViewData()
statusMiddleNew = outputString;
}
- if (result.foldersOnRightView)
+ if (foldersOnRightView)
{
- if (result.foldersOnRightView == 1)
+ if (foldersOnRightView == 1)
statusRightNew += _("1 directory");
else
{
- wxString folderCount = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(result.foldersOnRightView));
+ wxString folderCount = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(foldersOnRightView));
wxString outputString = _("%x directories");
outputString.Replace(wxT("%x"), folderCount, false);
statusRightNew += outputString;
}
- if (result.filesOnRightView)
+ if (filesOnRightView)
statusRightNew += wxT(", ");
}
- if (result.filesOnRightView)
+ if (filesOnRightView)
{
- if (result.filesOnRightView == 1)
+ if (filesOnRightView == 1)
statusRightNew += _("1 file,");
else
{
- wxString fileCount = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(result.filesOnRightView));
+ wxString fileCount = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(filesOnRightView));
wxString outputString = _("%x files,");
outputString.Replace(wxT("%x"), fileCount, false);
@@ -2965,7 +2996,7 @@ void MainDialog::updateGridViewData()
}
statusRightNew += wxT(" ");
- statusRightNew += FreeFileSync::formatFilesizeToShortString(result.filesizeRightView);
+ statusRightNew += FreeFileSync::formatFilesizeToShortString(filesizeRightView);
}
@@ -2983,93 +3014,88 @@ void MainDialog::updateGridViewData()
void MainDialog::OnAddFolderPair(wxCommandEvent& event)
{
- std::vector<FolderPair> newPairs;
- newPairs.push_back(FolderPair(m_directoryLeft ->GetValue().c_str(),
- m_directoryRight->GetValue().c_str()));
+ wxWindowUpdateLocker dummy(this); //avoid display distortion
+
+ std::vector<FolderPairEnh> newPairs;
+ newPairs.push_back(
+ FolderPairEnh(Zstring(),
+ Zstring(),
+ boost::shared_ptr<AlternateSyncConfig>(),
+ boost::shared_ptr<AlternateFilter>()));
- addFolderPair(newPairs, true); //add pair in front of additonal pairs
+ addFolderPair(newPairs, false); //add pair at the end of additional pairs
- //clear existing pairs
- FreeFileSync::setDirectoryName(wxEmptyString, m_directoryLeft, m_dirPickerLeft);
- FreeFileSync::setDirectoryName(wxEmptyString, m_directoryRight, m_dirPickerRight);
+ FreeFileSync::scrollToBottom(m_scrolledWindowFolderPairs);
//disable the sync button
syncPreview.enableSynchronization(false);
//clear grids
- currentGridData.clear();
+ gridDataView->clearAllRows();
updateGuiGrid();
}
-void MainDialog::OnRemoveFolderPair(wxCommandEvent& event)
+void MainDialog::updateFilterConfig(bool activateFilter) //true: activate filter false: stay as it is
{
- //find folder pair originating the event
- const wxObject* const eventObj = event.GetEventObject();
- for (std::vector<FolderPairPanel*>::const_iterator i = additionalFolderPairs.begin(); i != additionalFolderPairs.end(); ++i)
+ if (activateFilter)
{
- if (eventObj == static_cast<wxObject*>((*i)->m_bpButtonRemovePair))
+ //activate filter (if not yet active)
+ if (!currentCfg.mainCfg.filterIsActive)
{
- removeAddFolderPair(i - additionalFolderPairs.begin());
-
- //disable the sync button
- syncPreview.enableSynchronization(false);
-
- //clear grids
- currentGridData.clear();
- updateGuiGrid();
- return;
+ currentCfg.mainCfg.filterIsActive = true;
+ updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive);
}
}
-}
-
-void MainDialog::OnRemoveTopFolderPair(wxCommandEvent& event)
-{
- if (additionalFolderPairs.size() > 0)
+ if (currentCfg.mainCfg.filterIsActive)
{
- const wxString leftDir = (*additionalFolderPairs.begin())->m_directoryLeft->GetValue().c_str();
- const wxString rightDir = (*additionalFolderPairs.begin())->m_directoryRight->GetValue().c_str();
-
- FreeFileSync::setDirectoryName(leftDir, m_directoryLeft, m_dirPickerLeft);
- FreeFileSync::setDirectoryName(rightDir, m_directoryRight, m_dirPickerRight);
+ applyFiltering(getCurrentConfiguration().mainCfg, gridDataView->getDataTentative());
+ refreshGridAfterFilterChange(400);
+ }
+ else
+ {
+ FilterProcess::setActiveStatus(true, gridDataView->getDataTentative());
+ refreshGridAfterFilterChange(0);
+ }
+}
- removeAddFolderPair(0); //remove first of additional folder pairs
- //disable the sync button
- syncPreview.enableSynchronization(false);
+void MainDialog::updateSyncConfig()
+{
+ //update sync variant name
+ m_staticTextSyncVariant->SetLabel(wxString(wxT("(")) + getCurrentConfiguration().mainCfg.getSyncVariantName() + wxT(")"));
+ bSizer6->Layout(); //adapt layout for variant text
- //clear grids
- currentGridData.clear();
- updateGuiGrid();
- }
+ FreeFileSync::redetermineSyncDirection(getCurrentConfiguration().mainCfg, gridDataView->getDataTentative());
+ updateGuiGrid();
}
-void scrollToBottom(wxScrolledWindow* scrWindow)
+void MainDialog::OnRemoveFolderPair(wxCommandEvent& event)
{
- int height = 0;
- scrWindow->GetClientSize(NULL, &height);
+ const wxObject* const eventObj = event.GetEventObject(); //find folder pair originating the event
+ for (std::vector<FolderPairPanel*>::const_iterator i = additionalFolderPairs.begin(); i != additionalFolderPairs.end(); ++i)
+ if (eventObj == static_cast<wxObject*>((*i)->m_bpButtonRemovePair))
+ {
+ removeAddFolderPair(i - additionalFolderPairs.begin());
- int pixelPerLine = 0;
- scrWindow->GetScrollPixelsPerUnit(NULL, &pixelPerLine);
+ //disable the sync button
+ syncPreview.enableSynchronization(false);
- if (height > 0 && pixelPerLine > 0)
- {
- const int scrollLinesTotal = scrWindow->GetScrollLines(wxVERTICAL);
- const int scrollLinesOnScreen = height / pixelPerLine;
- const int scrollPosBottom = scrollLinesTotal - scrollLinesOnScreen;
+ //clear grids
+ gridDataView->clearAllRows();
- if (0 <= scrollPosBottom)
- scrWindow->Scroll(0, scrollPosBottom);
- }
+ updateSyncConfig();
+ return;
+ }
}
const size_t MAX_ADD_FOLDER_PAIRS = 5;
-void MainDialog::addFolderPair(const std::vector<FolderPair>& newPairs, bool addFront)
+void MainDialog::addFolderPair(const std::vector<FolderPairEnh>& newPairs, bool addFront)
{
if (newPairs.size() == 0)
return;
@@ -3077,12 +3103,13 @@ void MainDialog::addFolderPair(const std::vector<FolderPair>& newPairs, bool add
wxWindowUpdateLocker dummy(this); //avoid display distortion
int pairHeight = 0;
- for (std::vector<FolderPair>::const_iterator i = newPairs.begin(); i != newPairs.end(); ++i)
+ for (std::vector<FolderPairEnh>::const_iterator i = newPairs.begin(); i != newPairs.end(); ++i)
{
//add new folder pair
- FolderPairPanel* newPair = new FolderPairPanel(m_scrolledWindowFolderPairs);
- newPair->m_bitmap23->SetBitmap(*GlobalResources::getInstance().bitmapLink);
- newPair->m_bpButtonRemovePair->SetBitmapLabel(*GlobalResources::getInstance().bitmapRemoveFolderPair);
+ FolderPairPanel* newPair = new FolderPairPanel(m_scrolledWindowFolderPairs, this);
+
+ //correct width of middle block
+ newPair->m_panel21->SetMinSize(wxSize(m_gridMiddle->GetSize().GetWidth(), -1));
//set width of left folder panel
const int width = m_panelTopLeft->GetSize().GetWidth();
@@ -3104,21 +3131,22 @@ void MainDialog::addFolderPair(const std::vector<FolderPair>& newPairs, bool add
pairHeight = newPair->GetSize().GetHeight();
//register events
- newPair->m_bpButtonRemovePair->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainDialog::OnRemoveFolderPair), NULL, this );
+ newPair->m_bpButtonRemovePair->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainDialog::OnRemoveFolderPair), NULL, this);
//insert directory names
FreeFileSync::setDirectoryName(i->leftDirectory.c_str(), newPair->m_directoryLeft, newPair->m_dirPickerLeft);
FreeFileSync::setDirectoryName(i->rightDirectory.c_str(), newPair->m_directoryRight, newPair->m_dirPickerRight);
+
+ //set alternate configuration
+ newPair->altSyncConfig = i->altSyncConfig;
+ newPair->altFilter = i->altFilter;
+ newPair->updateAltButtonColor();
}
//set size of scrolled window
const int visiblePairs = std::min(additionalFolderPairs.size(), MAX_ADD_FOLDER_PAIRS); //up to MAX_ADD_FOLDER_PAIRS additional pairs shall be shown
m_scrolledWindowFolderPairs->SetMinSize(wxSize( -1, pairHeight * visiblePairs));
- //adapt delete top folder pair button
- m_bpButtonRemoveTopPair->Show();
- m_panelTopRight->Layout();
-
//update controls
m_scrolledWindowFolderPairs->Fit(); //adjust scrolled window size
m_scrolledWindowFolderPairs->Layout(); //adjust stuff inside scrolled window
@@ -3129,11 +3157,11 @@ void MainDialog::addFolderPair(const std::vector<FolderPair>& newPairs, bool add
}
-void MainDialog::removeAddFolderPair(const int pos)
+void MainDialog::removeAddFolderPair(const unsigned int pos)
{
wxWindowUpdateLocker dummy(this); //avoid display distortion
- if (0 <= pos && pos < int(additionalFolderPairs.size()))
+ if (pos < additionalFolderPairs.size())
{
//remove folder pairs from window
FolderPairPanel* pairToDelete = additionalFolderPairs[pos];
@@ -3148,13 +3176,6 @@ void MainDialog::removeAddFolderPair(const int pos)
if (additionalRows <= MAX_ADD_FOLDER_PAIRS) //up to MAX_ADD_FOLDER_PAIRS additional pairs shall be shown
m_scrolledWindowFolderPairs->SetMinSize(wxSize(-1, pairHeight * additionalRows));
- //adapt delete top folder pair button
- if (additionalFolderPairs.size() == 0)
- {
- m_bpButtonRemoveTopPair->Hide();
- m_panelTopRight->Layout();
- }
-
//update controls
m_scrolledWindowFolderPairs->Fit(); //adjust scrolled window size
m_scrolledWindowFolderPairs->Layout(); //adjust stuff inside scrolled window
@@ -3170,9 +3191,6 @@ void MainDialog::clearAddFolderPairs()
additionalFolderPairs.clear();
bSizerAddFolderPairs->Clear(true);
- m_bpButtonRemoveTopPair->Hide();
- m_panelTopRight->Layout();
-
m_scrolledWindowFolderPairs->SetMinSize(wxSize(-1, 0));
bSizer1->Layout();
}
@@ -3209,25 +3227,71 @@ void MainDialog::OnMenuExportFileList(wxCommandEvent& event)
}
}
- //begin work
wxString exportString;
+ //write legend
+ exportString += wxString(_("Legend")) + wxT('\n');
+ if (syncPreview.previewIsEnabled())
+ {
+ exportString += wxString(wxT("\"")) + getDescription(SO_CREATE_NEW_LEFT) + wxT("\";") + getSymbol(SO_CREATE_NEW_LEFT) + wxT('\n');
+ exportString += wxString(wxT("\"")) + getDescription(SO_CREATE_NEW_RIGHT) + wxT("\";") + getSymbol(SO_CREATE_NEW_RIGHT) + wxT('\n');
+ exportString += wxString(wxT("\"")) + getDescription(SO_DELETE_LEFT) + wxT("\";") + getSymbol(SO_DELETE_LEFT) + wxT('\n');
+ exportString += wxString(wxT("\"")) + getDescription(SO_DELETE_RIGHT) + wxT("\";") + getSymbol(SO_DELETE_RIGHT) + wxT('\n');
+ exportString += wxString(wxT("\"")) + getDescription(SO_OVERWRITE_LEFT) + wxT("\";") + getSymbol(SO_OVERWRITE_LEFT) + wxT('\n');
+ exportString += wxString(wxT("\"")) + getDescription(SO_OVERWRITE_RIGHT) + wxT("\";") + getSymbol(SO_OVERWRITE_RIGHT) + wxT('\n');
+ exportString += wxString(wxT("\"")) + getDescription(SO_DO_NOTHING) + wxT("\";") + getSymbol(SO_DO_NOTHING) + wxT('\n');
+ exportString += wxString(wxT("\"")) + getDescription(SO_UNRESOLVED_CONFLICT) + wxT("\";") + getSymbol(SO_UNRESOLVED_CONFLICT) + wxT('\n');
+ }
+ else
+ {
+ exportString += wxString(wxT("\"")) + getDescription(FILE_LEFT_SIDE_ONLY) + wxT("\";") + getSymbol(FILE_LEFT_SIDE_ONLY) + wxT('\n');
+ exportString += wxString(wxT("\"")) + getDescription(FILE_RIGHT_SIDE_ONLY) + wxT("\";") + getSymbol(FILE_RIGHT_SIDE_ONLY) + wxT('\n');
+ exportString += wxString(wxT("\"")) + getDescription(FILE_LEFT_NEWER) + wxT("\";") + getSymbol(FILE_LEFT_NEWER) + wxT('\n');
+ exportString += wxString(wxT("\"")) + getDescription(FILE_RIGHT_NEWER) + wxT("\";") + getSymbol(FILE_RIGHT_NEWER) + wxT('\n');
+ exportString += wxString(wxT("\"")) + getDescription(FILE_DIFFERENT) + wxT("\";") + getSymbol(FILE_DIFFERENT) + wxT('\n');
+ exportString += wxString(wxT("\"")) + getDescription(FILE_EQUAL) + wxT("\";") + getSymbol(FILE_EQUAL) + wxT('\n');
+ exportString += wxString(wxT("\"")) + getDescription(FILE_CONFLICT) + wxT("\";") + getSymbol(FILE_CONFLICT) + wxT('\n');
+ }
+ exportString += '\n';
+
+ //write header
+ for (int k = 0; k < m_gridLeft->GetNumberCols(); ++k)
+ {
+ exportString += m_gridLeft->GetColLabelValue(k);
+ exportString += ';';
+ }
+
+ for (int k = 0; k < m_gridMiddle->GetNumberCols(); ++k)
+ {
+ exportString += m_gridMiddle->GetColLabelValue(k);
+ exportString += ';';
+ }
+
+ for (int k = 0; k < m_gridRight->GetNumberCols(); ++k)
+ {
+ exportString += m_gridRight->GetColLabelValue(k);
+ if (k != m_gridRight->GetNumberCols() - 1)
+ exportString += ';';
+ }
+ exportString += '\n';
+
+ //begin work
for (int i = 0; i < m_gridLeft->GetNumberRows(); ++i)
{
for (int k = 0; k < m_gridLeft->GetNumberCols(); ++k)
{
- exportString+= m_gridLeft->GetCellValue(i, k);
- exportString+= ';';
+ exportString += m_gridLeft->GetCellValue(i, k);
+ exportString += ';';
}
for (int k = 0; k < m_gridMiddle->GetNumberCols(); ++k)
{
- exportString+= m_gridMiddle->GetCellValue(i, k);
- exportString+= ';';
+ exportString += m_gridMiddle->GetCellValue(i, k);
+ exportString += ';';
}
for (int k = 0; k < m_gridRight->GetNumberCols(); ++k)
{
- exportString+= m_gridRight->GetCellValue(i, k);
+ exportString += m_gridRight->GetCellValue(i, k);
if (k != m_gridRight->GetNumberCols() - 1)
exportString+= ';';
}
@@ -3252,10 +3316,10 @@ void MainDialog::OnMenuExportFileList(wxCommandEvent& event)
void MainDialog::OnMenuBatchJob(wxCommandEvent& event)
{
//fill batch config structure
+ xmlAccess::XmlGuiConfig currCfg = getCurrentConfiguration(); //get UP TO DATE config, with updated values for main and additional folders!
+
xmlAccess::XmlBatchConfig batchCfg;
- batchCfg.mainCfg = currentCfg.mainCfg;
- batchCfg.directoryPairs = getFolderPairs();
- batchCfg.silent = false;
+ batchCfg.mainCfg = currCfg.mainCfg;
if (currentCfg.ignoreErrors)
batchCfg.handleError = xmlAccess::ON_ERROR_IGNORE;
@@ -3307,7 +3371,10 @@ void MainDialog::OnMenuAbout(wxCommandEvent& event)
void MainDialog::OnMenuQuit(wxCommandEvent& event)
{
- requestShutdown();
+ if (!saveOldConfig()) //notify user about changed settings
+ return;
+
+ Destroy();
}
//#########################################################################################################
@@ -3387,7 +3454,7 @@ void MainDialog::SyncPreview::enableSynchronization(bool value)
else
{
synchronizationEnabled = false;
- mainDlg_->m_buttonStartSync->SetForegroundColour(wxColor(94, 94, 94)); //grey
+ mainDlg_->m_buttonStartSync->SetForegroundColour(wxColor(128, 128, 128)); //Some colors seem to have problems with 16Bit color depth, well this one hasn't!
mainDlg_->m_buttonStartSync->setBitmapFront(*GlobalResources::getInstance().bitmapSyncDisabled);
}
}
diff --git a/ui/MainDialog.h b/ui/MainDialog.h
index b6a49b17..a4c1d897 100644
--- a/ui/MainDialog.h
+++ b/ui/MainDialog.h
@@ -13,16 +13,18 @@
#include "../library/processXml.h"
#include <memory>
#include <map>
+#include <set>
class CompareStatusHandler;
class CompareStatus;
class MainFolderDragDrop;
-class FolderPairPanel;
class CustomGrid;
class FFSCheckRowsEvent;
class FFSSyncDirectionEvent;
class IconUpdater;
class ManualDeletionHandler;
+class FolderPairPanel;
+
namespace FreeFileSync
{
@@ -36,6 +38,7 @@ class MainDialog : public MainDialogGenerated
friend class CompareStatusHandler;
friend class ManualDeletionHandler;
friend class MainFolderDragDrop;
+ friend class FolderPairPanel;
//IDs for context menu items
enum ContextIDRim //context menu for left and right grids
@@ -44,7 +47,7 @@ class MainDialog : public MainDialogGenerated
CONTEXT_EXCLUDE_EXT,
CONTEXT_EXCLUDE_OBJ,
CONTEXT_CLIPBOARD,
- CONTEXT_EXPLORER,
+ CONTEXT_EXTERNAL_APP,
CONTEXT_DELETE_FILES,
CONTEXT_SYNC_DIR_LEFT,
CONTEXT_SYNC_DIR_NONE,
@@ -85,39 +88,45 @@ private:
//configuration load/save
bool readConfigurationFromXml(const wxString& filename, bool programStartup = false);
bool writeConfigurationToXml(const wxString& filename);
+
xmlAccess::XmlGuiConfig getCurrentConfiguration() const;
+ void setCurrentConfiguration(const xmlAccess::XmlGuiConfig& newGuiCfg);
+
static const wxString& lastConfigFileName();
xmlAccess::XmlGuiConfig lastConfigurationSaved; //support for: "Save changed configuration?" dialog
+ //used when saving configuration
+ wxString currentConfigFileName;
void readGlobalSettings();
void writeGlobalSettings();
- void updateViewFilterButtons();
+ void initViewFilterButtons();
void updateFilterButton(wxBitmapButton* filterButton, bool isActive);
void addFileToCfgHistory(const wxString& filename);
void addLeftFolderToHistory(const wxString& leftFolder);
void addRightFolderToHistory(const wxString& rightFolder);
- void addFolderPair(const std::vector<FreeFileSync::FolderPair>& newPairs, bool addFront = false);
- void removeAddFolderPair(const int pos); //keep it an int, allow negative values!
+ void addFolderPair(const std::vector<FreeFileSync::FolderPairEnh>& newPairs, bool addFront = false);
+ void removeAddFolderPair(const unsigned int pos);
void clearAddFolderPairs();
//main method for putting gridDataView on UI: updates data respecting current view settings
void updateGuiGrid();
-
void updateGridViewData();
//context menu functions
- std::set<int> getSelectedRows(const CustomGrid* grid) const;
- std::set<int> getSelectedRows() const;
- void setSyncDirManually(const std::set<int>& rowsToSetOnUiTable, const FreeFileSync::SyncDirection dir);
- void filterRangeManually(const std::set<int>& rowsToFilterOnUiTable, const int leadingRow);
+ std::set<unsigned int> getSelectedRows(const CustomGrid* grid) const;
+ std::set<unsigned int> getSelectedRows() const;
+ void setSyncDirManually(const std::set<unsigned int>& rowsToSetOnUiTable, const FreeFileSync::SyncDirection dir);
+ void filterRangeManually(const std::set<unsigned int>& rowsToFilterOnUiTable, const int leadingRow);
void copySelectionToClipboard(const CustomGrid* selectedGrid);
- void openWithFileManager(const int rowNumber, const bool leftSide);
void deleteSelectedFiles();
+ void openExternalApplication(unsigned int rowNumber, bool leftSide, const wxString& commandline);
+ static const int externalAppIDFirst = 1000; //id of first external app item
+
//work to be done in idle time
void OnIdleEvent(wxEvent& event);
@@ -133,18 +142,31 @@ private:
void onGridRightButtonEvent( wxKeyEvent& event);
void onGridMiddleButtonEvent( wxKeyEvent& event);
void OnContextRim( wxGridEvent& event);
- void OnContextRimSelection( wxCommandEvent& event);
void OnContextRimLabelLeft( wxGridEvent& event);
void OnContextRimLabelRight( wxGridEvent& event);
- void OnContextRimLabelSelection( wxCommandEvent& event);
void OnContextMiddle( wxGridEvent& event);
- void OnContextMiddleSelection( wxCommandEvent& event);
void OnContextMiddleLabel( wxGridEvent& event);
- void OnContextMiddleLabelSelection(wxCommandEvent& event);
- void OnDirSelected(wxFileDirPickerEvent& event);
+ //context menu handler methods
+ void OnContextFilterTemp(wxCommandEvent& event);
+ void OnContextExcludeExtension(wxCommandEvent& event);
+ void OnContextExcludeObject(wxCommandEvent& event);
+ void OnContextCopyClipboard(wxCommandEvent& event);
+ void OnContextOpenWith(wxCommandEvent& event);
+ void OnContextDeleteFiles(wxCommandEvent& event);
+ void OnContextSyncDirLeft(wxCommandEvent& event);
+ void OnContextSyncDirNone(wxCommandEvent& event);
+ void OnContextSyncDirRight(wxCommandEvent& event);
+ void OnContextCustColumnLeft(wxCommandEvent& event);
+ void OnContextCustColumnRight(wxCommandEvent& event);
+ void OnContextAutoAdjustLeft(wxCommandEvent& event);
+ void OnContextAutoAdjustRight(wxCommandEvent& event);
+ void OnContextIncludeAll(wxCommandEvent& event);
+ void OnContextExcludeAll(wxCommandEvent& event);
+ void OnContextComparisonView(wxCommandEvent& event);
+ void OnContextSyncView(wxCommandEvent& event);
- void requestShutdown(); //try to exit application
+ void OnDirSelected(wxFileDirPickerEvent& event);
void OnCheckRows(FFSCheckRowsEvent& event);
void OnSetSyncDirection(FFSSyncDirectionEvent& event);
@@ -171,10 +193,13 @@ private:
void OnSyncDirRight( wxCommandEvent& event);
void OnSyncDirNone( wxCommandEvent& event);
+ void OnNewConfig( wxCommandEvent& event);
void OnSaveConfig( wxCommandEvent& event);
void OnLoadConfig( wxCommandEvent& event);
void OnLoadFromHistory( wxCommandEvent& event);
bool trySaveConfig(); //return true if saved successfully
+ bool saveOldConfig(); //return false on user abort
+
void loadConfiguration(const wxString& filename);
void OnCfgHistoryKeyEvent( wxKeyEvent& event);
@@ -202,7 +227,9 @@ private:
void OnAddFolderPair( wxCommandEvent& event);
void OnRemoveFolderPair( wxCommandEvent& event);
- void OnRemoveTopFolderPair( wxCommandEvent& event);
+
+ void updateFilterConfig(bool activateFilter);
+ void updateSyncConfig();
//menu events
void OnMenuGlobalSettings( wxCommandEvent& event);
@@ -225,10 +252,7 @@ private:
//global settings used by GUI and batch mode
xmlAccess::XmlGlobalSettings& globalSettings;
- //technical representation of grid-data
- FreeFileSync::FolderComparison currentGridData;
-
- //UI view of currentGridData
+ //UI view of FolderComparison structure
std::auto_ptr<FreeFileSync::GridView> gridDataView;
//-------------------------------------
@@ -246,9 +270,6 @@ private:
int posYNotMaximized;
//-------------------------------------
- //convenience method to get all folder pairs (unformatted)
- std::vector<FreeFileSync::FolderPair> getFolderPairs() const;
-
//***********************************************
std::auto_ptr<wxMenu> contextMenu;
@@ -263,17 +284,6 @@ private:
//save the last used config filename history
std::vector<wxString> cfgFileNames;
- //used when saving configuration
- wxString currentConfigFileName;
-
- //temporal variables used by exclude via context menu
- wxString exFilterCandidateExtension;
- struct FilterObject
- {
- wxString relativeName;
- FreeFileSync::FileDescrLine::ObjectType type;
- };
- std::vector<FilterObject> exFilterCandidateObj;
bool cleanedUp; //determines if destructor code was already executed
diff --git a/ui/SmallDialogs.cpp b/ui/SmallDialogs.cpp
index beb2d975..39f805ba 100644
--- a/ui/SmallDialogs.cpp
+++ b/ui/SmallDialogs.cpp
@@ -1,5 +1,4 @@
#include "smallDialogs.h"
-#include "../shared/globalFunctions.h"
#include "../library/resources.h"
#include "../algorithm.h"
#include "../synchronization.h"
@@ -11,6 +10,7 @@
#include "../shared/fileHandling.h"
#include "../library/statusHandler.h"
#include <wx/wupdlock.h>
+#include "../shared/globalFunctions.h"
using namespace FreeFileSync;
@@ -168,14 +168,14 @@ void FilterDlg::OnDefault(wxCommandEvent& event)
}
-void FilterDlg::OnOK(wxCommandEvent& event)
+void FilterDlg::OnApply(wxCommandEvent& event)
{
//only if user presses ApplyFilter, he wants the changes to be committed
includeFilter = m_textCtrlInclude->GetValue();
excludeFilter = m_textCtrlExclude->GetValue();
//when leaving dialog: filter and redraw grid, if filter is active
- EndModal(BUTTON_OKAY);
+ EndModal(BUTTON_APPLY);
}
@@ -193,14 +193,12 @@ void FilterDlg::OnClose(wxCloseEvent& event)
//########################################################################################
DeleteDialog::DeleteDialog(wxWindow* main,
- const FreeFileSync::FolderComparison& folderCmp,
- const FreeFileSync::FolderCompRef& rowsOnLeft,
- const FreeFileSync::FolderCompRef& rowsOnRight,
+ const std::vector<FileSystemObject*>& rowsOnLeft,
+ const std::vector<FileSystemObject*>& rowsOnRight,
bool& deleteOnBothSides,
bool& useRecycleBin,
int& totalDeleteCount) :
DeleteDlgGenerated(main),
- m_folderCmp(folderCmp),
rowsToDeleteOnLeft(rowsOnLeft),
rowsToDeleteOnRight(rowsOnRight),
m_deleteOnBothSides(deleteOnBothSides),
@@ -217,41 +215,25 @@ DeleteDialog::DeleteDialog(wxWindow* main,
void DeleteDialog::updateTexts()
{
- wxString headerText;
if (m_checkBoxUseRecycler->GetValue())
{
- headerText = _("Do you really want to move the following objects(s) to the Recycle Bin?");
+ m_staticTextHeader->SetLabel(_("Do you really want to move the following objects(s) to the Recycle Bin?"));
m_bitmap12->SetBitmap(*GlobalResources::getInstance().bitmapRecycler);
}
else
{
- headerText = _("Do you really want to delete the following objects(s)?");
+ m_staticTextHeader->SetLabel(_("Do you really want to delete the following objects(s)?"));
m_bitmap12->SetBitmap(*GlobalResources::getInstance().bitmapDeleteFile);
}
- m_staticTextHeader->SetLabel(headerText);
- assert(m_folderCmp.size() == rowsToDeleteOnLeft.size());
- assert(m_folderCmp.size() == rowsToDeleteOnRight.size());
-
- wxString filesToDelete;
- totalDelCount = 0;
- for (FolderComparison::const_iterator j = m_folderCmp.begin(); j != m_folderCmp.end(); ++j)
- {
- const FileComparison& fileCmp = j->fileCmp;
+ const std::pair<wxString, int> delInfo = FreeFileSync::deleteFromGridAndHDPreview(
+ rowsToDeleteOnLeft,
+ rowsToDeleteOnRight,
+ m_checkBoxDeleteBothSides->GetValue());
- const int pairIndex = j - m_folderCmp.begin();
- if ( pairIndex < int(rowsToDeleteOnLeft.size()) && //just to be sure
- pairIndex < int(rowsToDeleteOnRight.size()))
- {
- const std::pair<wxString, int> delInfo = FreeFileSync::deleteFromGridAndHDPreview(fileCmp,
- rowsToDeleteOnLeft[pairIndex],
- rowsToDeleteOnRight[pairIndex],
- m_checkBoxDeleteBothSides->GetValue());
+ const wxString filesToDelete = delInfo.first;
+ totalDelCount = delInfo.second;
- filesToDelete += delInfo.first;
- totalDelCount += delInfo.second;
- }
- }
m_textCtrlMessage->SetValue(filesToDelete);
Layout();
@@ -636,10 +618,13 @@ void SyncPreviewDlg::OnStartSync(wxCommandEvent& event)
//########################################################################################
-CompareCfgDialog::CompareCfgDialog(wxWindow* parentWindow, CompareVariant& cmpVar) :
+CompareCfgDialog::CompareCfgDialog(wxWindow* parentWindow, const wxPoint& position, CompareVariant& cmpVar) :
CmpCfgDlgGenerated(parentWindow),
m_cmpVar(cmpVar)
{
+ //move dialog up so that compare-config button and first config-variant are on same level
+ Move(wxPoint(position.x, std::max(0, position.y - (m_buttonTimeSize->GetScreenPosition() - GetScreenPosition()).y)));
+
m_bpButtonHelp->SetBitmapLabel(*GlobalResources::getInstance().bitmapHelp);
switch (cmpVar)
@@ -695,21 +680,22 @@ GlobalSettingsDlg::GlobalSettingsDlg(wxWindow* window, xmlAccess::XmlGlobalSetti
settings(globalSettings)
{
m_bitmapSettings->SetBitmap(*GlobalResources::getInstance().bitmapSettings);
- m_buttonResetWarnings->setBitmapFront(*GlobalResources::getInstance().bitmapWarningSmall, 5);
+ m_buttonResetDialogs->setBitmapFront(*GlobalResources::getInstance().bitmapWarningSmall, 5);
+ m_bpButtonAddRow->SetBitmapLabel(*GlobalResources::getInstance().bitmapAddFolderPair);
+ m_bpButtonRemoveRow->SetBitmapLabel(*GlobalResources::getInstance().bitmapRemoveFolderPair);
- m_spinCtrlFileTimeTolerance->SetValue(globalSettings.fileTimeTolerance);
m_checkBoxIgnoreOneHour->SetValue(globalSettings.ignoreOneHourDiff);
- m_textCtrlCommand->SetValue(globalSettings.gui.commandLineFileManager);
+ set(globalSettings.gui.externelApplications);
- const wxString toolTip = wxString(_("This commandline will be executed on each doubleclick. The following macros are available:")) + wxT("\n\n") +
+ const wxString toolTip = wxString(_("Integrate external applications into context menu. The following macros are available:")) + wxT("\n\n") +
wxT("%name \t") + _("- full file or directory name") + wxT("\n") +
- wxT("%dir \t") + _("- directory part only") + wxT("\n") +
- wxT("%nameCo \t") + _("- sibling of %name") + wxT("\n") +
- wxT("%dirCo \t") + _("- sibling of %dir");
+ wxT("%dir \t") + _("- directory part only") + wxT("\n") +
+ wxT("%nameCo \t") + _("- Other side's counterpart to %name") + wxT("\n") +
+ wxT("%dirCo \t") + _("- Other side's counterpart to %dir");
- m_staticTextCommand->SetToolTip(toolTip);
- m_textCtrlCommand->SetToolTip(toolTip);
+ m_gridCustomCommand->GetGridWindow()->SetToolTip(toolTip);
+ m_gridCustomCommand->GetGridColLabelWindow()->SetToolTip(toolTip);
m_buttonOkay->SetFocus();
@@ -720,32 +706,29 @@ GlobalSettingsDlg::GlobalSettingsDlg(wxWindow* window, xmlAccess::XmlGlobalSetti
void GlobalSettingsDlg::OnOkay(wxCommandEvent& event)
{
//write global settings only when okay-button is pressed!
- settings.fileTimeTolerance = m_spinCtrlFileTimeTolerance->GetValue();
settings.ignoreOneHourDiff = m_checkBoxIgnoreOneHour->GetValue();
- settings.gui.commandLineFileManager = m_textCtrlCommand->GetValue();
+ settings.gui.externelApplications = getExtApp();
EndModal(BUTTON_OKAY);
}
-void GlobalSettingsDlg::OnResetWarnings(wxCommandEvent& event)
+void GlobalSettingsDlg::OnResetDialogs(wxCommandEvent& event)
{
- wxMessageDialog* messageDlg = new wxMessageDialog(this, _("Reset all warning messages?"), _("Warning") , wxOK | wxCANCEL);
+ wxMessageDialog* messageDlg = new wxMessageDialog(this, _("Re-enable all hidden dialogs?"), _("Warning") , wxOK | wxCANCEL);
if (messageDlg->ShowModal() == wxID_OK)
- settings.warnings.resetWarnings();
+ settings.optDialogs.resetDialogs();
}
void GlobalSettingsDlg::OnDefault(wxCommandEvent& event)
{
- m_spinCtrlFileTimeTolerance->SetValue(2);
- m_checkBoxIgnoreOneHour->SetValue(true);
-#ifdef FFS_WIN
- m_textCtrlCommand->SetValue(wxT("explorer /select, %name"));
-#elif defined FFS_LINUX
- m_textCtrlCommand->SetValue(wxT("konqueror \"%dir\""));
-#endif
+ xmlAccess::XmlGlobalSettings defaultCfg;
+
+ m_checkBoxIgnoreOneHour->SetValue(defaultCfg.ignoreOneHourDiff);
+
+ set(defaultCfg.gui.externelApplications);
}
@@ -761,6 +744,54 @@ void GlobalSettingsDlg::OnClose(wxCloseEvent& event)
}
+void GlobalSettingsDlg::set(const xmlAccess::ExternalApps& extApp)
+{
+ const int rowCount = m_gridCustomCommand->GetNumberRows();
+ if (rowCount > 0)
+ m_gridCustomCommand->DeleteRows(0, rowCount);
+
+ m_gridCustomCommand->AppendRows(extApp.size());
+ for (xmlAccess::ExternalApps::const_iterator i = extApp.begin(); i != extApp.end(); ++i)
+ {
+ const int row = i - extApp.begin();
+ m_gridCustomCommand->SetCellValue(row, 0, i->first); //description
+ m_gridCustomCommand->SetCellValue(row, 1, i->second); //commandline
+ }
+ Fit();
+}
+
+
+xmlAccess::ExternalApps GlobalSettingsDlg::getExtApp()
+{
+ xmlAccess::ExternalApps output;
+ for (int i = 0; i < m_gridCustomCommand->GetNumberRows(); ++i)
+ output.push_back(
+ std::make_pair(m_gridCustomCommand->GetCellValue(i, 0), //description
+ m_gridCustomCommand->GetCellValue(i, 1))); //commandline
+ return output;
+}
+
+
+void GlobalSettingsDlg::OnAddRow(wxCommandEvent& event)
+{
+ wxWindowUpdateLocker dummy(this); //avoid display distortion
+
+ m_gridCustomCommand->AppendRows();
+ Fit();
+}
+
+
+void GlobalSettingsDlg::OnRemoveRow(wxCommandEvent& event)
+{
+ if (m_gridCustomCommand->GetNumberRows() > 0)
+ {
+ wxWindowUpdateLocker dummy(this); //avoid display distortion
+
+ m_gridCustomCommand->DeleteRows(m_gridCustomCommand->GetNumberRows() - 1);
+ Fit();
+ }
+}
+
//########################################################################################
CompareStatus::CompareStatus(wxWindow* parentWindow) :
@@ -1058,7 +1089,7 @@ void SyncStatus::updateStatusDialogNow()
}
//time elapsed
- const wxString timeElapsedTmp = (wxTimeSpan::Milliseconds(timeElapsed.Time())).Format();
+ const wxString timeElapsedTmp = wxTimeSpan::Milliseconds(timeElapsed.Time()).Format();
if (m_staticTextTimeElapsed->GetLabel() != timeElapsedTmp && (screenChanged = true)) //avoid screen flicker
m_staticTextTimeElapsed->SetLabel(timeElapsedTmp);
diff --git a/ui/SmallDialogs.h b/ui/SmallDialogs.h
index f5ea53df..6e9d0414 100644
--- a/ui/SmallDialogs.h
+++ b/ui/SmallDialogs.h
@@ -1,7 +1,7 @@
#ifndef SMALLDIALOGS_H_INCLUDED
#define SMALLDIALOGS_H_INCLUDED
-#include "../structures.h"
+#include "../fileHierarchy.h"
#include "../library/processXml.h"
#include "guiGenerated.h"
#include <wx/stopwatch.h>
@@ -48,13 +48,13 @@ public:
enum
{
- BUTTON_OKAY
+ BUTTON_APPLY = 1
};
private:
void OnHelp(wxCommandEvent& event);
void OnDefault(wxCommandEvent& event);
- void OnOK(wxCommandEvent& event);
+ void OnApply(wxCommandEvent& event);
void OnCancel(wxCommandEvent& event);
void OnClose(wxCloseEvent& event);
@@ -67,9 +67,8 @@ class DeleteDialog : public DeleteDlgGenerated
{
public:
DeleteDialog(wxWindow* main,
- const FreeFileSync::FolderComparison& folderCmp,
- const FreeFileSync::FolderCompRef& rowsOnLeft,
- const FreeFileSync::FolderCompRef& rowsOnRight,
+ const std::vector<FreeFileSync::FileSystemObject*>& rowsOnLeft,
+ const std::vector<FreeFileSync::FileSystemObject*>& rowsOnRight,
bool& deleteOnBothSides,
bool& useRecycleBin,
int& totalDeleteCount);
@@ -78,7 +77,7 @@ public:
enum
{
- BUTTON_OKAY,
+ BUTTON_OKAY = 1,
BUTTON_CANCEL
};
@@ -91,9 +90,8 @@ private:
void updateTexts();
- const FreeFileSync::FolderComparison& m_folderCmp;
- const FreeFileSync::FolderCompRef& rowsToDeleteOnLeft;
- const FreeFileSync::FolderCompRef& rowsToDeleteOnRight;
+ const std::vector<FreeFileSync::FileSystemObject*>& rowsToDeleteOnLeft;
+ const std::vector<FreeFileSync::FileSystemObject*>& rowsToDeleteOnRight;
bool& m_deleteOnBothSides;
bool& m_useRecycleBin;
int& totalDelCount;
@@ -218,7 +216,7 @@ private:
class CompareCfgDialog : public CmpCfgDlgGenerated
{
public:
- CompareCfgDialog(wxWindow* parentWindow, FreeFileSync::CompareVariant& cmpVar);
+ CompareCfgDialog(wxWindow* parentWindow, const wxPoint& position, FreeFileSync::CompareVariant& cmpVar);
enum
{
@@ -249,10 +247,15 @@ public:
private:
void OnOkay(wxCommandEvent& event);
- void OnResetWarnings(wxCommandEvent& event);
+ void OnResetDialogs(wxCommandEvent& event);
void OnDefault(wxCommandEvent& event);
void OnCancel(wxCommandEvent& event);
void OnClose(wxCloseEvent& event);
+ void OnAddRow(wxCommandEvent& event);
+ void OnRemoveRow(wxCommandEvent& event);
+
+ void set(const xmlAccess::ExternalApps& extApp);
+ xmlAccess::ExternalApps getExtApp();
xmlAccess::XmlGlobalSettings& settings;
};
diff --git a/ui/SyncDialog.cpp b/ui/SyncDialog.cpp
index 3172a548..8f5066c5 100644
--- a/ui/SyncDialog.cpp
+++ b/ui/SyncDialog.cpp
@@ -1,5 +1,5 @@
#include "syncDialog.h"
-#include "../shared/globalFunctions.h"
+#include "../shared/systemConstants.h"
#include "../library/resources.h"
#include <wx/msgdlg.h>
#include "../shared/customButton.h"
@@ -10,31 +10,40 @@
#include "../shared/fileHandling.h"
#include "../shared/xmlBase.h"
#include <wx/wupdlock.h>
+#include "folderPair.h"
using namespace FreeFileSync;
SyncCfgDialog::SyncCfgDialog(wxWindow* window,
- const FolderComparison& folderCmpRef,
- MainConfiguration& config,
- bool& ignoreErrors) :
+ const CompareVariant compareVar,
+ SyncConfiguration& syncConfiguration,
+ DeletionPolicy& handleDeletion,
+ wxString& customDeletionDirectory,
+ bool* ignoreErrors) :
SyncCfgDlgGenerated(window),
- folderCmp(folderCmpRef),
- cfg(config),
- m_ignoreErrors(ignoreErrors),
+ cmpVariant(compareVar),
+ localSyncConfiguration(syncConfiguration), //make working copy of syncConfiguration
+ refSyncConfiguration(syncConfiguration),
+ refHandleDeletion(handleDeletion),
+ refCustomDeletionDirectory(customDeletionDirectory),
+ refIgnoreErrors(ignoreErrors),
dragDropCustomDelFolder(new DragDropOnDlg(m_panelCustomDeletionDir, m_dirPickerCustomDelFolder, m_textCtrlCustomDelFolder))
{
- //make working copy of mainDialog.cfg.syncConfiguration and recycler setting
- localSyncConfiguration = config.syncConfiguration;
-
- setDeletionHandling(cfg.handleDeletion);
- m_textCtrlCustomDelFolder->SetValue(cfg.customDeletionDirectory);
+ setDeletionHandling(handleDeletion);
+ m_textCtrlCustomDelFolder->SetValue(customDeletionDirectory);
//error handling
- setErrorHandling(m_ignoreErrors);
+ if (ignoreErrors)
+ setErrorHandling(*ignoreErrors);
+ else
+ {
+ sbSizerErrorHandling->Show(false);
+ Layout();
+ }
//set sync config icons
- updateConfigIcons(cfg.compareVar, localSyncConfiguration);
+ updateConfigIcons(cmpVariant, localSyncConfiguration);
//set icons for this dialog
m_bitmapLeftOnly->SetBitmap(*GlobalResources::getInstance().bitmapLeftOnly);
@@ -42,6 +51,7 @@ SyncCfgDialog::SyncCfgDialog(wxWindow* window,
m_bitmapLeftNewer->SetBitmap(*GlobalResources::getInstance().bitmapLeftNewer);
m_bitmapRightNewer->SetBitmap(*GlobalResources::getInstance().bitmapRightNewer);
m_bitmapDifferent->SetBitmap(*GlobalResources::getInstance().bitmapDifferent);
+ m_bitmapConflict->SetBitmap(*GlobalResources::getInstance().bitmapConflictGrey);
bSizer201->Layout(); //wxButtonWithImage size might have changed
@@ -81,11 +91,13 @@ void SyncCfgDialog::updateConfigIcons(const FreeFileSync::CompareVariant cmpVar,
m_bpButtonLeftNewer,
m_bpButtonRightNewer,
m_bpButtonDifferent,
+ m_bpButtonConflict,
m_bitmapLeftOnly,
m_bitmapRightOnly,
m_bitmapLeftNewer,
m_bitmapRightNewer,
- m_bitmapDifferent);
+ m_bitmapDifferent,
+ m_bitmapConflict);
}
@@ -96,11 +108,13 @@ void SyncCfgDialog::updateConfigIcons(const CompareVariant compareVar,
wxBitmapButton* buttonLeftNewer,
wxBitmapButton* buttonRightNewer,
wxBitmapButton* buttonDifferent,
+ wxBitmapButton* buttonConflict,
wxStaticBitmap* bitmapLeftOnly,
wxStaticBitmap* bitmapRightOnly,
wxStaticBitmap* bitmapLeftNewer,
wxStaticBitmap* bitmapRightNewer,
- wxStaticBitmap* bitmapDifferent)
+ wxStaticBitmap* bitmapDifferent,
+ wxStaticBitmap* bitmapConflict)
{
//display only relevant sync options
switch (compareVar)
@@ -111,12 +125,14 @@ void SyncCfgDialog::updateConfigIcons(const CompareVariant compareVar,
buttonLeftNewer ->Show();
buttonRightNewer->Show();
buttonDifferent ->Hide();
+ buttonConflict ->Show();
bitmapLeftOnly ->Show();
bitmapRightOnly ->Show();
bitmapLeftNewer ->Show();
bitmapRightNewer->Show();
bitmapDifferent ->Hide();
+ bitmapConflict ->Show();
break;
case CMP_BY_CONTENT:
@@ -125,12 +141,14 @@ void SyncCfgDialog::updateConfigIcons(const CompareVariant compareVar,
buttonLeftNewer ->Hide();
buttonRightNewer->Hide();
buttonDifferent ->Show();
+ buttonConflict ->Show();
bitmapLeftOnly ->Show();
bitmapRightOnly ->Show();
bitmapLeftNewer ->Hide();
bitmapRightNewer->Hide();
bitmapDifferent ->Show();
+ bitmapConflict ->Show();
break;
}
@@ -139,15 +157,15 @@ void SyncCfgDialog::updateConfigIcons(const CompareVariant compareVar,
{
case SYNC_DIR_RIGHT:
buttonLeftOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowRightCr);
- buttonLeftOnly->SetToolTip(_("Copy from left to right"));
+ buttonLeftOnly->SetToolTip(getDescription(SO_CREATE_NEW_RIGHT));
break;
case SYNC_DIR_LEFT:
buttonLeftOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapDeleteLeft);
- buttonLeftOnly->SetToolTip(_("Delete files/folders existing on left side only"));
+ buttonLeftOnly->SetToolTip(getDescription(SO_DELETE_LEFT));
break;
case SYNC_DIR_NONE:
buttonLeftOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowNone);
- buttonLeftOnly->SetToolTip(_("Do nothing"));
+ buttonLeftOnly->SetToolTip(getDescription(SO_DO_NOTHING));
break;
}
@@ -155,15 +173,15 @@ void SyncCfgDialog::updateConfigIcons(const CompareVariant compareVar,
{
case SYNC_DIR_RIGHT:
buttonRightOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapDeleteRight);
- buttonRightOnly->SetToolTip(_("Delete files/folders existing on right side only"));
+ buttonRightOnly->SetToolTip(getDescription(SO_DELETE_RIGHT));
break;
case SYNC_DIR_LEFT:
buttonRightOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowLeftCr);
- buttonRightOnly->SetToolTip(_("Copy from right to left"));
+ buttonRightOnly->SetToolTip(getDescription(SO_CREATE_NEW_LEFT));
break;
case SYNC_DIR_NONE:
buttonRightOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowNone);
- buttonRightOnly->SetToolTip(_("Do nothing"));
+ buttonRightOnly->SetToolTip(getDescription(SO_DO_NOTHING));
break;
}
@@ -171,15 +189,15 @@ void SyncCfgDialog::updateConfigIcons(const CompareVariant compareVar,
{
case SYNC_DIR_RIGHT:
buttonLeftNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowRight);
- buttonLeftNewer->SetToolTip(_("Copy from left to right overwriting"));
+ buttonLeftNewer->SetToolTip(getDescription(SO_OVERWRITE_RIGHT));
break;
case SYNC_DIR_LEFT:
buttonLeftNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowLeft);
- buttonLeftNewer->SetToolTip(_("Copy from right to left overwriting"));
+ buttonLeftNewer->SetToolTip(getDescription(SO_OVERWRITE_LEFT));
break;
case SYNC_DIR_NONE:
buttonLeftNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowNone);
- buttonLeftNewer->SetToolTip(_("Do nothing"));
+ buttonLeftNewer->SetToolTip(getDescription(SO_DO_NOTHING));
break;
}
@@ -187,15 +205,15 @@ void SyncCfgDialog::updateConfigIcons(const CompareVariant compareVar,
{
case SYNC_DIR_RIGHT:
buttonRightNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowRight);
- buttonRightNewer->SetToolTip(_("Copy from left to right overwriting"));
+ buttonRightNewer->SetToolTip(getDescription(SO_OVERWRITE_RIGHT));
break;
case SYNC_DIR_LEFT:
buttonRightNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowLeft);
- buttonRightNewer->SetToolTip(_("Copy from right to left overwriting"));
+ buttonRightNewer->SetToolTip(getDescription(SO_OVERWRITE_LEFT));
break;
case SYNC_DIR_NONE:
buttonRightNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowNone);
- buttonRightNewer->SetToolTip(_("Do nothing"));
+ buttonRightNewer->SetToolTip(getDescription(SO_DO_NOTHING));
break;
}
@@ -203,15 +221,31 @@ void SyncCfgDialog::updateConfigIcons(const CompareVariant compareVar,
{
case SYNC_DIR_RIGHT:
buttonDifferent->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowRight);
- buttonDifferent->SetToolTip(_("Copy from left to right overwriting"));
+ buttonDifferent->SetToolTip(getDescription(SO_OVERWRITE_RIGHT));
break;
case SYNC_DIR_LEFT:
buttonDifferent->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowLeft);
- buttonDifferent->SetToolTip(_("Copy from right to left overwriting"));
+ buttonDifferent->SetToolTip(getDescription(SO_OVERWRITE_LEFT));
break;
case SYNC_DIR_NONE:
buttonDifferent->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowNone);
- buttonDifferent->SetToolTip(_("Do nothing"));
+ buttonDifferent->SetToolTip(getDescription(SO_DO_NOTHING));
+ break;
+ }
+
+ switch (syncConfig.conflict)
+ {
+ case SYNC_DIR_RIGHT:
+ buttonConflict->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowRight);
+ buttonConflict->SetToolTip(getDescription(SO_OVERWRITE_RIGHT));
+ break;
+ case SYNC_DIR_LEFT:
+ buttonConflict->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowLeft);
+ buttonConflict->SetToolTip(getDescription(SO_OVERWRITE_LEFT));
+ break;
+ case SYNC_DIR_NONE:
+ buttonConflict->SetBitmapLabel(*GlobalResources::getInstance().bitmapConflict);
+ buttonConflict->SetToolTip(_("Leave as unresolved conflict"));
break;
}
}
@@ -232,13 +266,13 @@ void SyncCfgDialog::OnCancel(wxCommandEvent& event)
void SyncCfgDialog::OnApply(wxCommandEvent& event)
{
//write configuration to main dialog
- cfg.syncConfiguration = localSyncConfiguration;
- cfg.handleDeletion = getDeletionHandling();
- cfg.customDeletionDirectory = m_textCtrlCustomDelFolder->GetValue();
+ refSyncConfiguration = localSyncConfiguration;
+ refHandleDeletion = getDeletionHandling();
+ refCustomDeletionDirectory = m_textCtrlCustomDelFolder->GetValue();
+ if (refIgnoreErrors)
+ *refIgnoreErrors = getErrorHandling();
- m_ignoreErrors = getErrorHandling();
-
- EndModal(BUTTON_OKAY);
+ EndModal(BUTTON_APPLY);
}
@@ -308,7 +342,7 @@ void updateToolTipDeletionHandling(wxChoice* choiceHandleError, wxPanel* customD
break;
case FreeFileSync::MOVE_TO_CUSTOM_DIRECTORY:
- choiceHandleError->SetToolTip(_("Move files to a custom directory."));
+ choiceHandleError->SetToolTip(_("Move files to a user-defined directory."));
customDir->Enable();
break;
}
@@ -337,7 +371,7 @@ void SyncCfgDialog::setDeletionHandling(FreeFileSync::DeletionPolicy newValue)
m_choiceHandleDeletion->Clear();
m_choiceHandleDeletion->Append(_("Delete permanently"));
m_choiceHandleDeletion->Append(_("Use Recycle Bin"));
- m_choiceHandleDeletion->Append(_("Move to custom directory"));
+ m_choiceHandleDeletion->Append(_("User-defined directory"));
switch (newValue)
{
@@ -366,7 +400,7 @@ void SyncCfgDialog::OnSyncLeftToRight(wxCommandEvent& event)
{
localSyncConfiguration.setVariant(SyncConfiguration::MIRROR);
- updateConfigIcons(cfg.compareVar, localSyncConfiguration);
+ updateConfigIcons(cmpVariant, localSyncConfiguration);
//if event is triggered by button
m_radioBtn1->SetValue(true);
@@ -377,7 +411,7 @@ void SyncCfgDialog::OnSyncUpdate(wxCommandEvent& event)
{
localSyncConfiguration.setVariant(SyncConfiguration::UPDATE);
- updateConfigIcons(cfg.compareVar, localSyncConfiguration);
+ updateConfigIcons(cmpVariant, localSyncConfiguration);
//if event is triggered by button
m_radioBtnUpdate->SetValue(true);
@@ -388,7 +422,7 @@ void SyncCfgDialog::OnSyncBothSides(wxCommandEvent& event)
{
localSyncConfiguration.setVariant(SyncConfiguration::TWOWAY);
- updateConfigIcons(cfg.compareVar, localSyncConfiguration);
+ updateConfigIcons(cmpVariant, localSyncConfiguration);
//if event is triggered by button
m_radioBtn2->SetValue(true);
@@ -415,7 +449,7 @@ void toggleSyncDirection(SyncDirectionCfg& current)
void SyncCfgDialog::OnExLeftSideOnly( wxCommandEvent& event )
{
toggleSyncDirection(localSyncConfiguration.exLeftSideOnly);
- updateConfigIcons(cfg.compareVar, localSyncConfiguration);
+ updateConfigIcons(cmpVariant, localSyncConfiguration);
//set custom config button
m_radioBtn3->SetValue(true);
}
@@ -424,7 +458,7 @@ void SyncCfgDialog::OnExLeftSideOnly( wxCommandEvent& event )
void SyncCfgDialog::OnExRightSideOnly( wxCommandEvent& event )
{
toggleSyncDirection(localSyncConfiguration.exRightSideOnly);
- updateConfigIcons(cfg.compareVar, localSyncConfiguration);
+ updateConfigIcons(cmpVariant, localSyncConfiguration);
//set custom config button
m_radioBtn3->SetValue(true);
}
@@ -433,7 +467,7 @@ void SyncCfgDialog::OnExRightSideOnly( wxCommandEvent& event )
void SyncCfgDialog::OnLeftNewer( wxCommandEvent& event )
{
toggleSyncDirection(localSyncConfiguration.leftNewer);
- updateConfigIcons(cfg.compareVar, localSyncConfiguration);
+ updateConfigIcons(cmpVariant, localSyncConfiguration);
//set custom config button
m_radioBtn3->SetValue(true);
}
@@ -442,7 +476,7 @@ void SyncCfgDialog::OnLeftNewer( wxCommandEvent& event )
void SyncCfgDialog::OnRightNewer( wxCommandEvent& event )
{
toggleSyncDirection(localSyncConfiguration.rightNewer);
- updateConfigIcons(cfg.compareVar, localSyncConfiguration);
+ updateConfigIcons(cmpVariant, localSyncConfiguration);
//set custom config button
m_radioBtn3->SetValue(true);
}
@@ -451,27 +485,54 @@ void SyncCfgDialog::OnRightNewer( wxCommandEvent& event )
void SyncCfgDialog::OnDifferent( wxCommandEvent& event )
{
toggleSyncDirection(localSyncConfiguration.different);
- updateConfigIcons(cfg.compareVar, localSyncConfiguration);
+ updateConfigIcons(cmpVariant, localSyncConfiguration);
+ //set custom config button
+ m_radioBtn3->SetValue(true);
+}
+
+
+void SyncCfgDialog::OnConflict(wxCommandEvent& event)
+{
+ toggleSyncDirection(localSyncConfiguration.conflict);
+ updateConfigIcons(cmpVariant, localSyncConfiguration);
//set custom config button
m_radioBtn3->SetValue(true);
}
//###################################################################################################################################
-class BatchFolderPairPanel : public BatchFolderPairGenerated
+typedef FreeFileSync::FolderPairPanelBasic<BatchFolderPairGenerated> FolderPairParent;
+
+class BatchFolderPairPanel : public FolderPairParent
{
public:
- BatchFolderPairPanel(wxWindow* parent) :
- BatchFolderPairGenerated(parent),
- dragDropOnLeft(m_panelLeft, m_dirPickerLeft, m_directoryLeft),
- dragDropOnRight(m_panelRight, m_dirPickerRight, m_directoryRight) {}
+ BatchFolderPairPanel(wxWindow* parent, BatchDialog* batchDialog) :
+ FolderPairParent(parent),
+ batchDlg(batchDialog) {}
private:
- //support for drag and drop
- DragDropOnDlg dragDropOnLeft;
- DragDropOnDlg dragDropOnRight;
-};
+ virtual wxWindow* getParentWindow()
+ {
+ return batchDlg;
+ }
+
+ virtual MainConfiguration getMainConfig() const
+ {
+ return batchDlg->getCurrentConfiguration().mainCfg;
+ }
+ virtual void OnAltFilterCfgChange(bool defaultValueSet)
+ {
+ if (!defaultValueSet)
+ {
+ //activate filter
+ batchDlg->m_checkBoxFilter->SetValue(true);
+ batchDlg->updateVisibleTabs();
+ }
+ }
+
+ BatchDialog* batchDlg;
+};
//###################################################################################################################################
@@ -538,12 +599,12 @@ void BatchDialog::init()
//set icons for this dialog
m_bpButtonAddPair->SetBitmapLabel(*GlobalResources::getInstance().bitmapAddFolderPair);
- m_bpButtonRemoveTopPair->SetBitmapLabel(*GlobalResources::getInstance().bitmapRemoveFolderPair);
m_bitmapLeftOnly->SetBitmap(*GlobalResources::getInstance().bitmapLeftOnly);
m_bitmapRightOnly->SetBitmap(*GlobalResources::getInstance().bitmapRightOnly);
m_bitmapLeftNewer->SetBitmap(*GlobalResources::getInstance().bitmapLeftNewer);
m_bitmapRightNewer->SetBitmap(*GlobalResources::getInstance().bitmapRightNewer);
m_bitmapDifferent->SetBitmap(*GlobalResources::getInstance().bitmapDifferent);
+ m_bitmapConflict->SetBitmap(*GlobalResources::getInstance().bitmapConflictGrey);
m_bitmap8->SetBitmap(*GlobalResources::getInstance().bitmapInclude);
m_bitmap9->SetBitmap(*GlobalResources::getInstance().bitmapExclude);
m_bitmap27->SetBitmap(*GlobalResources::getInstance().bitmapBatch);
@@ -553,7 +614,7 @@ void BatchDialog::init()
//------------------- error handling --------------------------
-xmlAccess::OnError BatchDialog::getSelectionHandleError()
+xmlAccess::OnError BatchDialog::getSelectionHandleError() const
{
switch (m_choiceHandleError->GetSelection())
{
@@ -612,7 +673,7 @@ void BatchDialog::OnExLeftSideOnly(wxCommandEvent& event)
//------------------- deletion handling --------------------------
-FreeFileSync::DeletionPolicy BatchDialog::getDeletionHandling()
+FreeFileSync::DeletionPolicy BatchDialog::getDeletionHandling() const
{
switch (m_choiceHandleDeletion->GetSelection())
{
@@ -634,7 +695,7 @@ void BatchDialog::setDeletionHandling(FreeFileSync::DeletionPolicy newValue)
m_choiceHandleDeletion->Clear();
m_choiceHandleDeletion->Append(_("Delete permanently"));
m_choiceHandleDeletion->Append(_("Use Recycle Bin"));
- m_choiceHandleDeletion->Append(_("Move to custom directory"));
+ m_choiceHandleDeletion->Append(_("User-defined directory"));
switch (newValue)
{
@@ -688,6 +749,13 @@ void BatchDialog::OnDifferent(wxCommandEvent& event)
}
+void BatchDialog::OnConflict(wxCommandEvent& event)
+{
+ toggleSyncDirection(localSyncConfiguration.conflict);
+ updateConfigIcons(getCurrentCompareVar(), localSyncConfiguration);
+}
+
+
void BatchDialog::OnCheckFilter(wxCommandEvent& event)
{
updateVisibleTabs();
@@ -737,7 +805,7 @@ void BatchDialog::showNotebookpage(wxWindow* page, const wxString& pageName, boo
}
-CompareVariant BatchDialog::getCurrentCompareVar()
+CompareVariant BatchDialog::getCurrentCompareVar() const
{
if (m_radioBtnSizeDate->GetValue())
return CMP_BY_TIME_SIZE;
@@ -760,11 +828,13 @@ void BatchDialog::updateConfigIcons(const FreeFileSync::CompareVariant cmpVar, c
m_bpButtonLeftNewer,
m_bpButtonRightNewer,
m_bpButtonDifferent,
+ m_bpButtonConflict,
m_bitmapLeftOnly,
m_bitmapRightOnly,
m_bitmapLeftNewer,
m_bitmapRightNewer,
- m_bitmapDifferent);
+ m_bitmapDifferent,
+ m_bitmapConflict);
}
@@ -824,7 +894,18 @@ void BatchDialog::OnLoadBatchJob(wxCommandEvent& event)
}
-bool BatchDialog::saveBatchFile(const wxString& filename)
+
+inline
+FolderPairEnh getEnahncedPair(const BatchFolderPairPanel* panel)
+{
+ return FolderPairEnh(panel->m_directoryLeft->GetValue().c_str(),
+ panel->m_directoryRight->GetValue().c_str(),
+ panel->altSyncConfig,
+ panel->altFilter);
+}
+
+
+xmlAccess::XmlBatchConfig BatchDialog::getCurrentConfiguration() const
{
xmlAccess::XmlBatchConfig batchCfg;
@@ -837,14 +918,29 @@ bool BatchDialog::saveBatchFile(const wxString& filename)
batchCfg.mainCfg.handleDeletion = getDeletionHandling();
batchCfg.mainCfg.customDeletionDirectory = m_textCtrlCustomDelFolder->GetValue();
- batchCfg.handleError = getSelectionHandleError();
+ //main pair
+ batchCfg.mainCfg.mainFolderPair.leftDirectory = m_directoryLeft->GetValue().c_str();
+ batchCfg.mainCfg.mainFolderPair.rightDirectory = m_directoryRight->GetValue().c_str();
+
+ //add additional pairs
+ batchCfg.mainCfg.additionalPairs.clear();
+ std::transform(additionalFolderPairs.begin(), additionalFolderPairs.end(),
+ std::back_inserter(batchCfg.mainCfg.additionalPairs), getEnahncedPair);
- batchCfg.directoryPairs = getFolderPairs();
//load structure with batch settings "batchCfg"
- batchCfg.silent = m_checkBoxSilent->GetValue();
+ batchCfg.silent = m_checkBoxSilent->GetValue();
+ batchCfg.handleError = getSelectionHandleError();
batchCfg.logFileDirectory = m_textCtrlLogfileDir->GetValue();
+ return batchCfg;
+}
+
+
+bool BatchDialog::saveBatchFile(const wxString& filename)
+{
+ const xmlAccess::XmlBatchConfig batchCfg = getCurrentConfiguration();
+
//write config to XML
try
{
@@ -919,26 +1015,16 @@ void BatchDialog::loadBatchCfg(const xmlAccess::XmlBatchConfig& batchCfg)
m_checkBoxSilent->SetValue(batchCfg.silent);
m_textCtrlLogfileDir->SetValue(batchCfg.logFileDirectory);
- //remove existing folder pairs
- FreeFileSync::setDirectoryName(wxEmptyString, m_directoryLeft, m_dirPickerLeft);
- FreeFileSync::setDirectoryName(wxEmptyString, m_directoryRight, m_dirPickerRight);
- clearAddFolderPairs();
- //add folder pairs
- if (batchCfg.directoryPairs.size() > 0)
- {
- //set main folder pair
- std::vector<FolderPair>::const_iterator main = batchCfg.directoryPairs.begin();
+ //set main folder pair
+ FreeFileSync::setDirectoryName(batchCfg.mainCfg.mainFolderPair.leftDirectory.c_str(), m_directoryLeft, m_dirPickerLeft);
+ FreeFileSync::setDirectoryName(batchCfg.mainCfg.mainFolderPair.rightDirectory.c_str(), m_directoryRight, m_dirPickerRight);
- FreeFileSync::setDirectoryName(main->leftDirectory.c_str(), m_directoryLeft, m_dirPickerLeft);
- FreeFileSync::setDirectoryName(main->rightDirectory.c_str(), m_directoryRight, m_dirPickerRight);
+ //remove existing additional folder pairs
+ clearAddFolderPairs();
- //set additional pairs
- std::vector<FolderPair> additionalPairs; //don't modify batchCfg.directoryPairs!
- for (std::vector<FolderPair>::const_iterator i = batchCfg.directoryPairs.begin() + 1; i != batchCfg.directoryPairs.end(); ++i)
- additionalPairs.push_back(*i);
- addFolderPair(additionalPairs);
- }
+ //set additional pairs
+ addFolderPair(batchCfg.mainCfg.additionalPairs);
updateVisibleTabs();
@@ -950,14 +1036,14 @@ void BatchDialog::loadBatchCfg(const xmlAccess::XmlBatchConfig& batchCfg)
void BatchDialog::OnAddFolderPair(wxCommandEvent& event)
{
- std::vector<FolderPair> newPairs;
- newPairs.push_back(FolderPair(m_directoryLeft->GetValue().c_str(),
- m_directoryRight->GetValue().c_str()));
- addFolderPair(newPairs, true); //add pair in front of additional pairs
-
- //clear top folder pair
- FreeFileSync::setDirectoryName(wxEmptyString, m_directoryLeft, m_dirPickerLeft);
- FreeFileSync::setDirectoryName(wxEmptyString, m_directoryRight, m_dirPickerRight);
+ std::vector<FolderPairEnh> newPairs;
+ newPairs.push_back(
+ FolderPairEnh(Zstring(),
+ Zstring(),
+ boost::shared_ptr<AlternateSyncConfig>(),
+ boost::shared_ptr<AlternateFilter>()));
+
+ addFolderPair(newPairs, false); //add pair at the end of additional pairs
}
@@ -994,7 +1080,7 @@ void BatchDialog::OnRemoveTopFolderPair(wxCommandEvent& event)
const size_t MAX_FOLDER_PAIRS = 3;
-void BatchDialog::addFolderPair(const std::vector<FolderPair>& newPairs, bool addFront)
+void BatchDialog::addFolderPair(const std::vector<FreeFileSync::FolderPairEnh>& newPairs, bool addFront)
{
if (newPairs.size() == 0)
return;
@@ -1003,10 +1089,9 @@ void BatchDialog::addFolderPair(const std::vector<FolderPair>& newPairs, bool ad
//add folder pairs
int pairHeight = 0;
- for (std::vector<FolderPair>::const_iterator i = newPairs.begin(); i != newPairs.end(); ++i)
+ for (std::vector<FreeFileSync::FolderPairEnh>::const_iterator i = newPairs.begin(); i != newPairs.end(); ++i)
{
- BatchFolderPairPanel* newPair = new BatchFolderPairPanel(m_scrolledWindow6);
- newPair->m_bpButtonRemovePair->SetBitmapLabel(*GlobalResources::getInstance().bitmapRemoveFolderPair);
+ BatchFolderPairPanel* newPair = new BatchFolderPairPanel(m_scrolledWindow6, this);
if (addFront)
{
@@ -1028,15 +1113,16 @@ void BatchDialog::addFolderPair(const std::vector<FolderPair>& newPairs, bool ad
//insert directory names
FreeFileSync::setDirectoryName(i->leftDirectory.c_str(), newPair->m_directoryLeft, newPair->m_dirPickerLeft);
FreeFileSync::setDirectoryName(i->rightDirectory.c_str(), newPair->m_directoryRight, newPair->m_dirPickerRight);
+
+ //set alternate configuration
+ newPair->altSyncConfig = i->altSyncConfig;
+ newPair->altFilter = i->altFilter;
+ newPair->updateAltButtonColor();
}
//set size of scrolled window
const int visiblePairs = std::min(additionalFolderPairs.size() + 1, MAX_FOLDER_PAIRS); //up to MAX_FOLDER_PAIRS pairs shall be shown
m_scrolledWindow6->SetMinSize(wxSize( -1, pairHeight * visiblePairs));
- //adapt delete top folder pair button
- m_bpButtonRemoveTopPair->Show();
- m_panelMainPair->Layout();
-
//update controls
m_scrolledWindow6->Fit(); //adjust scrolled window size
m_panelOverview->Layout(); //adjust stuff inside scrolled window
@@ -1065,12 +1151,6 @@ void BatchDialog::removeAddFolderPair(const int pos)
const int visiblePairs = std::min(additionalFolderPairs.size() + 1, MAX_FOLDER_PAIRS); //up to MAX_FOLDER_PAIRS pairs shall be shown
m_scrolledWindow6->SetMinSize(wxSize(-1, pairHeight * visiblePairs));
- if (additionalFolderPairs.size() == 0)
- {
- m_bpButtonRemoveTopPair->Hide();
- m_panelMainPair->Layout();
- }
-
//update controls
m_scrolledWindow6->Fit(); //adjust scrolled window size
m_panelOverview->Layout(); //adjust stuff inside scrolled window
@@ -1091,29 +1171,10 @@ void BatchDialog::clearAddFolderPairs()
additionalFolderPairs.clear();
bSizerAddFolderPairs->Clear(true);
- m_bpButtonRemoveTopPair->Hide();
- m_panelMainPair->Layout();
-
m_scrolledWindow6->SetMinSize(wxSize(-1, sbSizerMainPair->GetSize().GetHeight())); //respect height of main pair
}
-std::vector<FreeFileSync::FolderPair> BatchDialog::getFolderPairs() const
-{
- std::vector<FolderPair> output;
-
- //add main pair
- output.push_back(FolderPair(m_directoryLeft->GetValue().c_str(),
- m_directoryRight->GetValue().c_str()));
-
- //add additional pairs
- for (std::vector<BatchFolderPairPanel*>::const_iterator i = additionalFolderPairs.begin(); i != additionalFolderPairs.end(); ++i)
- output.push_back(FolderPair((*i)->m_directoryLeft->GetValue().c_str(),
- (*i)->m_directoryRight->GetValue().c_str()));
- return output;
-}
-
-
/*
#ifdef FFS_WIN
#include <wx/msw/wrapwin.h> //includes "windows.h"
diff --git a/ui/SyncDialog.h b/ui/SyncDialog.h
index 57d220d3..53ab1b5a 100644
--- a/ui/SyncDialog.h
+++ b/ui/SyncDialog.h
@@ -18,15 +18,17 @@ class SyncCfgDialog : public SyncCfgDlgGenerated
{
public:
SyncCfgDialog(wxWindow* window,
- const FreeFileSync::FolderComparison& folderCmpRef,
- FreeFileSync::MainConfiguration& config,
- bool& ignoreErrors);
+ const FreeFileSync::CompareVariant compareVar,
+ FreeFileSync::SyncConfiguration& syncConfiguration,
+ FreeFileSync::DeletionPolicy& handleDeletion,
+ wxString& customDeletionDirectory,
+ bool* ignoreErrors); //optional input parameter
~SyncCfgDialog();
enum
{
- BUTTON_OKAY = 10
+ BUTTON_APPLY = 10
};
static void updateConfigIcons(const FreeFileSync::CompareVariant compareVar,
@@ -36,28 +38,31 @@ public:
wxBitmapButton* buttonLeftNewer,
wxBitmapButton* buttonRightNewer,
wxBitmapButton* buttonDifferent,
+ wxBitmapButton* buttonConflict,
wxStaticBitmap* bitmapLeftOnly,
wxStaticBitmap* bitmapRightOnly,
wxStaticBitmap* bitmapLeftNewer,
wxStaticBitmap* bitmapRightNewer,
- wxStaticBitmap* bitmapDifferent);
+ wxStaticBitmap* bitmapDifferent,
+ wxStaticBitmap* bitmapConflict);
//some syntax relaxation
void updateConfigIcons(const FreeFileSync::CompareVariant cmpVar, const FreeFileSync::SyncConfiguration& syncConfig);
private:
- void OnSyncLeftToRight( wxCommandEvent& event);
- void OnSyncUpdate( wxCommandEvent& event);
- void OnSyncBothSides( wxCommandEvent& event);
+ virtual void OnSyncLeftToRight( wxCommandEvent& event);
+ virtual void OnSyncUpdate( wxCommandEvent& event);
+ virtual void OnSyncBothSides( wxCommandEvent& event);
- void OnExLeftSideOnly( wxCommandEvent& event);
- void OnExRightSideOnly( wxCommandEvent& event);
- void OnLeftNewer( wxCommandEvent& event);
- void OnRightNewer( wxCommandEvent& event);
- void OnDifferent( wxCommandEvent& event);
+ virtual void OnExLeftSideOnly( wxCommandEvent& event);
+ virtual void OnExRightSideOnly( wxCommandEvent& event);
+ virtual void OnLeftNewer( wxCommandEvent& event);
+ virtual void OnRightNewer( wxCommandEvent& event);
+ virtual void OnDifferent( wxCommandEvent& event);
+ virtual void OnConflict( wxCommandEvent& event);
- void OnClose( wxCloseEvent& event);
- void OnCancel( wxCommandEvent& event);
- void OnApply( wxCommandEvent& event);
+ virtual void OnClose( wxCloseEvent& event);
+ virtual void OnCancel( wxCommandEvent& event);
+ virtual void OnApply( wxCommandEvent& event);
//error handling
bool getErrorHandling();
@@ -69,11 +74,16 @@ private:
void setDeletionHandling(FreeFileSync::DeletionPolicy newValue);
void OnChangeDeletionHandling(wxCommandEvent& event);
+ const FreeFileSync::CompareVariant cmpVariant;
+
//temporal copy of maindialog.cfg.syncConfiguration
FreeFileSync::SyncConfiguration localSyncConfiguration;
- const FreeFileSync::FolderComparison& folderCmp;
- FreeFileSync::MainConfiguration& cfg;
- bool& m_ignoreErrors;
+
+ //changing data
+ FreeFileSync::SyncConfiguration& refSyncConfiguration;
+ FreeFileSync::DeletionPolicy& refHandleDeletion;
+ wxString& refCustomDeletionDirectory;
+ bool* refIgnoreErrors;
std::auto_ptr<FreeFileSync::DragDropOnDlg> dragDropCustomDelFolder;
};
@@ -82,6 +92,7 @@ private:
class BatchDialog: public BatchDlgGenerated
{
friend class BatchFileDropEvent;
+ friend class BatchFolderPairPanel;
public:
BatchDialog(wxWindow* window, const xmlAccess::XmlBatchConfig& batchCfg);
@@ -101,6 +112,7 @@ private:
virtual void OnLeftNewer( wxCommandEvent& event);
virtual void OnRightNewer( wxCommandEvent& event);
virtual void OnDifferent( wxCommandEvent& event);
+ virtual void OnConflict( wxCommandEvent& event);
virtual void OnCheckFilter( wxCommandEvent& event);
virtual void OnCheckLogging( wxCommandEvent& event);
@@ -113,12 +125,11 @@ private:
virtual void OnRemoveFolderPair( wxCommandEvent& event);
virtual void OnRemoveTopFolderPair(wxCommandEvent& event);
- void addFolderPair(const std::vector<FreeFileSync::FolderPair>& newPairs, bool addFront = false);
+ void addFolderPair(const std::vector<FreeFileSync::FolderPairEnh>& newPairs, bool addFront = false);
void removeAddFolderPair(const int pos);
void clearAddFolderPairs();
- std::vector<FreeFileSync::FolderPair> getFolderPairs() const;
- FreeFileSync::CompareVariant getCurrentCompareVar();
+ FreeFileSync::CompareVariant getCurrentCompareVar() const;
void updateConfigIcons(const FreeFileSync::CompareVariant cmpVar, const FreeFileSync::SyncConfiguration& syncConfig);
@@ -126,12 +137,12 @@ private:
void showNotebookpage(wxWindow* page, const wxString& pageName, bool show);
//error handling
- xmlAccess::OnError getSelectionHandleError();
+ xmlAccess::OnError getSelectionHandleError() const;
void setSelectionHandleError(const xmlAccess::OnError value);
void OnChangeErrorHandling(wxCommandEvent& event);
//deletion handling
- FreeFileSync::DeletionPolicy getDeletionHandling();
+ FreeFileSync::DeletionPolicy getDeletionHandling() const;
void setDeletionHandling(FreeFileSync::DeletionPolicy newValue);
void OnChangeDeletionHandling(wxCommandEvent& event);
@@ -140,6 +151,7 @@ private:
void loadBatchFile(const wxString& filename);
void loadBatchCfg(const xmlAccess::XmlBatchConfig& batchCfg);
+ xmlAccess::XmlBatchConfig getCurrentConfiguration() const;
FreeFileSync::SyncConfiguration localSyncConfiguration;
std::vector<BatchFolderPairPanel*> additionalFolderPairs;
diff --git a/ui/batchStatusHandler.cpp b/ui/batchStatusHandler.cpp
index 294613dd..4abc49eb 100644
--- a/ui/batchStatusHandler.cpp
+++ b/ui/batchStatusHandler.cpp
@@ -4,10 +4,11 @@
#include "../algorithm.h"
#include <wx/ffile.h>
#include <wx/msgdlg.h>
-#include "../shared/globalFunctions.h"
+#include "../shared/systemConstants.h"
#include "../shared/standardPaths.h"
#include "../shared/fileHandling.h"
#include "../library/resources.h"
+#include "../shared/globalFunctions.h"
class LogFile
@@ -259,12 +260,14 @@ private:
//##############################################################################################################################
BatchStatusHandlerSilent::BatchStatusHandlerSilent(const xmlAccess::OnError handleError, const wxString& logfileDirectory, int& returnVal) :
- m_handleError(handleError),
+ m_handleError(xmlAccess::ON_ERROR_POPUP),
currentProcess(StatusHandler::PROCESS_NONE),
returnValue(returnVal),
trayIcon(new FfsTrayIcon(this)),
m_log(new LogFile(logfileDirectory))
{
+ setErrorStrategy(handleError);
+
//test if log was instantiated successfully
if (!m_log->isOkay())
{ //handle error: file load
@@ -446,6 +449,12 @@ void BatchStatusHandlerSilent::addFinalInfo(const wxString& infoMessage)
}
+void BatchStatusHandlerSilent::setErrorStrategy(xmlAccess::OnError handleError)
+{
+ m_handleError = handleError;
+}
+
+
void BatchStatusHandlerSilent::forceUiRefresh()
{
trayIcon->updateSysTray(); //needed by sys-tray icon only
@@ -466,21 +475,7 @@ BatchStatusHandlerGui::BatchStatusHandlerGui(const xmlAccess::OnError handleErro
currentProcess(StatusHandler::PROCESS_NONE),
returnValue(returnVal)
{
- switch (handleError)
- {
- case xmlAccess::ON_ERROR_POPUP:
- showPopups = true;
- break;
-
- case xmlAccess::ON_ERROR_EXIT: //doesn't make much sense for "batch gui"-mode
- showPopups = true;
- break;
-
- case xmlAccess::ON_ERROR_IGNORE:
- showPopups = false;
- break;
- }
-
+ setErrorStrategy(handleError);
syncStatusFrame = new SyncStatus(this, NULL);
syncStatusFrame->Show();
@@ -684,3 +679,22 @@ void BatchStatusHandlerGui::addFinalInfo(const wxString& infoMessage)
{
finalInfo = infoMessage;
}
+
+
+void BatchStatusHandlerGui::setErrorStrategy(xmlAccess::OnError handleError) //change error handling during process
+{
+ switch (handleError)
+ {
+ case xmlAccess::ON_ERROR_POPUP:
+ showPopups = true;
+ break;
+
+ case xmlAccess::ON_ERROR_EXIT: //doesn't make much sense for "batch gui"-mode
+ showPopups = true;
+ break;
+
+ case xmlAccess::ON_ERROR_IGNORE:
+ showPopups = false;
+ break;
+ }
+}
diff --git a/ui/batchStatusHandler.h b/ui/batchStatusHandler.h
index a075d7d7..811ab63c 100644
--- a/ui/batchStatusHandler.h
+++ b/ui/batchStatusHandler.h
@@ -15,6 +15,7 @@ class BatchStatusHandler : public StatusHandler
{
public:
virtual void addFinalInfo(const wxString& infoMessage) = 0;
+virtual void setErrorStrategy(xmlAccess::OnError handleError) = 0; //change error handling during process
};
@@ -35,6 +36,8 @@ public:
virtual void reportWarning(const wxString& warningMessage, bool& warningActive);
virtual void addFinalInfo(const wxString& infoMessage);
+virtual void setErrorStrategy(xmlAccess::OnError handleError); //change error handling during process
+
private:
virtual void abortThisProcess();
@@ -64,6 +67,8 @@ public:
virtual void reportWarning(const wxString& warningMessage, bool& warningActive);
virtual void addFinalInfo(const wxString& infoMessage);
+virtual void setErrorStrategy(xmlAccess::OnError handleError); //change error handling during process
+
private:
virtual void abortThisProcess();
diff --git a/ui/dragAndDrop.cpp b/ui/dragAndDrop.cpp
deleted file mode 100644
index 2989e544..00000000
--- a/ui/dragAndDrop.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-#include "dragAndDrop.h"
-#include <wx/dnd.h>
-#include <wx/window.h>
-#include <wx/combobox.h>
-#include <wx/textctrl.h>
-#include <wx/filepicker.h>
-#include <wx/filename.h>
-#include "../algorithm.h"
-
-
-//define new event type
-const wxEventType FFS_DROP_FILE_EVENT = wxNewEventType();
-
-typedef void (wxEvtHandler::*FFSFileDropEventFunction)(FFSFileDropEvent&);
-
-#define FFSFileDropEventHandler(func) \
- (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(FFSFileDropEventFunction, &func)
-
-class FFSFileDropEvent : public wxCommandEvent
-{
-public:
- FFSFileDropEvent(const wxString& nameDropped, const wxWindow* dropWindow) :
- wxCommandEvent(FFS_DROP_FILE_EVENT),
- nameDropped_(nameDropped),
- dropWindow_(dropWindow) {}
-
- virtual wxEvent* Clone() const
- {
- return new FFSFileDropEvent(nameDropped_, dropWindow_);
- }
-
- const wxString nameDropped_;
- const wxWindow* dropWindow_;
-};
-
-//##############################################################################################################
-
-
-class WindowDropTarget : public wxFileDropTarget
-{
-public:
- WindowDropTarget(wxWindow* dropWindow) :
- dropWindow_(dropWindow) {}
-
- virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames)
- {
- if (!filenames.IsEmpty())
- {
- const wxString droppedFileName = filenames[0];
-
- //create a custom event on drop window: execute event after file dropping is completed! (e.g. after mouse is released)
- FFSFileDropEvent evt(droppedFileName, dropWindow_);
- dropWindow_->AddPendingEvent(evt);
- }
- return false;
- }
-
-private:
- wxWindow* dropWindow_;
-};
-
-
-
-//##############################################################################################################
-
-using FreeFileSync::DragDropOnMainDlg;
-
-DragDropOnMainDlg::DragDropOnMainDlg(wxWindow* dropWindow1,
- wxWindow* dropWindow2,
- wxDirPickerCtrl* dirPicker,
- wxComboBox* dirName) :
- dropWindow1_(dropWindow1),
- dropWindow2_(dropWindow2),
- dirPicker_(dirPicker),
- dirName_(dirName)
-{
- //prepare drag & drop
- dropWindow1->SetDropTarget(new WindowDropTarget(dropWindow1)); //takes ownership
- dropWindow2->SetDropTarget(new WindowDropTarget(dropWindow2)); //takes ownership
-
- //redirect drag & drop event back to this class
- dropWindow1->Connect(FFS_DROP_FILE_EVENT, FFSFileDropEventHandler(DragDropOnMainDlg::OnFilesDropped), NULL, this);
- dropWindow2->Connect(FFS_DROP_FILE_EVENT, FFSFileDropEventHandler(DragDropOnMainDlg::OnFilesDropped), NULL, this);
-
- //keep dirPicker and dirName synchronous
- dirName->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DragDropOnMainDlg::OnWriteDirManually ), NULL, this );
- dirPicker->Connect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( DragDropOnMainDlg::OnDirSelected ), NULL, this );
-}
-
-
-void DragDropOnMainDlg::OnFilesDropped(FFSFileDropEvent& event)
-{
- if ( this->dropWindow1_ == event.dropWindow_ || //file may be dropped on window 1 or 2
- this->dropWindow2_ == event.dropWindow_)
- {
- if (AcceptDrop(event.nameDropped_))
- {
- wxString fileName = event.nameDropped_;
- if (wxDirExists(fileName))
- {
- dirName_->SetSelection(wxNOT_FOUND);
- dirName_->SetValue(fileName);
- dirPicker_->SetPath(fileName);
- }
- else
- {
- fileName = wxFileName(fileName).GetPath();
- if (wxDirExists(fileName))
- {
- dirName_->SetSelection(wxNOT_FOUND);
- dirName_->SetValue(fileName);
- dirPicker_->SetPath(fileName);
- }
- }
- }
- }
- else //should never be reached
- event.Skip();
-};
-
-
-void DragDropOnMainDlg::OnWriteDirManually(wxCommandEvent& event)
-{
- const wxString newDir = FreeFileSync::getFormattedDirectoryName(event.GetString().c_str()).c_str();
- if (wxDirExists(newDir))
- dirPicker_->SetPath(newDir);
-
- event.Skip();
-}
-
-
-void DragDropOnMainDlg::OnDirSelected(wxFileDirPickerEvent& event)
-{
- const wxString newPath = event.GetPath();
- dirName_->SetSelection(wxNOT_FOUND);
- dirName_->SetValue(newPath);
-
- event.Skip();
-}
-
-//##############################################################################################################
-
-
-using FreeFileSync::DragDropOnDlg;
-
-DragDropOnDlg::DragDropOnDlg(wxWindow* dropWindow,
- wxDirPickerCtrl* dirPicker,
- wxTextCtrl* dirName) :
- dropWindow_(dropWindow),
- dirPicker_(dirPicker),
- dirName_(dirName)
-{
- //prepare drag & drop
- dropWindow->SetDropTarget(new WindowDropTarget(dropWindow)); //takes ownership
-
- //redirect drag & drop event back to this class
- dropWindow->Connect(FFS_DROP_FILE_EVENT, FFSFileDropEventHandler(DragDropOnDlg::OnFilesDropped), NULL, this);
-
- //keep dirPicker and dirName synchronous
- dirName->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DragDropOnDlg::OnWriteDirManually ), NULL, this );
- dirPicker->Connect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( DragDropOnDlg::OnDirSelected ), NULL, this );
-}
-
-
-void DragDropOnDlg::OnFilesDropped(FFSFileDropEvent& event)
-{
- if (this->dropWindow_ == event.dropWindow_)
- {
- wxString fileName = event.nameDropped_;
- if (wxDirExists(fileName))
- {
- dirName_->SetValue(fileName);
- dirPicker_->SetPath(fileName);
- }
- else
- {
- fileName = wxFileName(fileName).GetPath();
- if (wxDirExists(fileName))
- {
- dirName_->SetValue(fileName);
- dirPicker_->SetPath(fileName);
- }
- }
- }
- else //should never be reached
- event.Skip();
-};
-
-
-void DragDropOnDlg::OnWriteDirManually(wxCommandEvent& event)
-{
- const wxString newDir = FreeFileSync::getFormattedDirectoryName(event.GetString().c_str()).c_str();
- if (wxDirExists(newDir))
- dirPicker_->SetPath(newDir);
-
- event.Skip();
-}
-
-
-void DragDropOnDlg::OnDirSelected(wxFileDirPickerEvent& event)
-{
- const wxString newPath = event.GetPath();
- dirName_->SetValue(newPath);
-
- event.Skip();
-}
-
diff --git a/ui/dragAndDrop.h b/ui/dragAndDrop.h
deleted file mode 100644
index cca6f865..00000000
--- a/ui/dragAndDrop.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef DRAGANDDROP_H_INCLUDED
-#define DRAGANDDROP_H_INCLUDED
-
-#include <wx/event.h>
-
-class wxWindow;
-class wxDirPickerCtrl;
-class wxComboBox;
-class wxTextCtrl;
-class wxString;
-class FFSFileDropEvent;
-class wxCommandEvent;
-class wxFileDirPickerEvent;
-
-
-namespace FreeFileSync
-{
- //add drag and drop functionality, coordinating a wxWindow, wxDirPickerCtrl, and wxComboBox/wxTextCtrl
-
- class DragDropOnMainDlg : public wxEvtHandler
- {
- public:
- DragDropOnMainDlg(wxWindow* dropWindow1,
- wxWindow* dropWindow2,
- wxDirPickerCtrl* dirPicker,
- wxComboBox* dirName);
-
- virtual ~DragDropOnMainDlg() {}
-
- virtual bool AcceptDrop(const wxString& dropName) = 0; //return true if drop should be processed
-
- private:
- void OnFilesDropped(FFSFileDropEvent& event);
- void OnWriteDirManually(wxCommandEvent& event);
- void OnDirSelected(wxFileDirPickerEvent& event);
-
- const wxWindow* dropWindow1_;
- const wxWindow* dropWindow2_;
- wxDirPickerCtrl* dirPicker_;
- wxComboBox* dirName_;
- };
-
-
- class DragDropOnDlg: public wxEvtHandler
- {
- public:
- DragDropOnDlg(wxWindow* dropWindow,
- wxDirPickerCtrl* dirPicker,
- wxTextCtrl* dirName);
-
- private:
- void OnFilesDropped(FFSFileDropEvent& event);
- void OnWriteDirManually(wxCommandEvent& event);
- void OnDirSelected(wxFileDirPickerEvent& event);
-
- const wxWindow* dropWindow_;
- wxDirPickerCtrl* dirPicker_;
- wxTextCtrl* dirName_;
- };
-}
-
-
-#endif // DRAGANDDROP_H_INCLUDED
diff --git a/ui/folderPair.h b/ui/folderPair.h
new file mode 100644
index 00000000..f2b57ea7
--- /dev/null
+++ b/ui/folderPair.h
@@ -0,0 +1,147 @@
+#ifndef FOLDERPAIR_H_INCLUDED
+#define FOLDERPAIR_H_INCLUDED
+
+#include "../structures.h"
+#include "../shared/dragAndDrop.h"
+#include "../library/resources.h"
+#include "smallDialogs.h"
+#include "syncDialog.h"
+
+
+namespace FreeFileSync
+{
+ //basic functionality for changing alternate folder pair configuration: adaptable to generated gui class
+
+ template <class GuiPanel>
+ class FolderPairPanelBasic : public GuiPanel
+ {
+ using GuiPanel::m_bpButtonAltSyncCfg;
+ using GuiPanel::m_bpButtonAltFilter;
+
+ public:
+ FolderPairPanelBasic(wxWindow* parent) :
+ GuiPanel(parent),
+ dragDropOnLeft(new DragDropOnDlg(GuiPanel::m_panelLeft, GuiPanel::m_dirPickerLeft, GuiPanel::m_directoryLeft)),
+ dragDropOnRight(new DragDropOnDlg(GuiPanel::m_panelRight, GuiPanel::m_dirPickerRight, GuiPanel::m_directoryRight))
+ {
+ //register events for removal of alternate configuration
+ m_bpButtonAltFilter->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(FolderPairPanelBasic::OnAltFilterCfgRemove), NULL, this);
+ m_bpButtonAltSyncCfg->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(FolderPairPanelBasic::OnAltSyncCfgRemove), NULL, this);
+
+ m_bpButtonAltSyncCfg->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FolderPairPanelBasic::OnAltSyncCfg), NULL, this);
+ m_bpButtonAltFilter-> Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FolderPairPanelBasic::OnAltFilterCfg), NULL, this);
+
+ GuiPanel::m_bpButtonRemovePair->SetBitmapLabel(*GlobalResources::getInstance().bitmapRemoveFolderPair);
+ }
+
+ //alternate configuration attached to it
+ boost::shared_ptr<const FreeFileSync::AlternateSyncConfig> altSyncConfig; //optional
+ boost::shared_ptr<const FreeFileSync::AlternateFilter> altFilter; //optional
+
+
+ void updateAltButtonColor()
+ {
+ if (altSyncConfig.get())
+ m_bpButtonAltSyncCfg->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncCfgSmall);
+ else
+ m_bpButtonAltSyncCfg->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncCfgSmallGrey);
+
+ if (altFilter.get())
+ m_bpButtonAltFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterSmall);
+ else
+ m_bpButtonAltFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterSmallGrey);
+ }
+
+ protected:
+ virtual void OnAltFilterCfgRemoveConfirm(wxCommandEvent& event)
+ {
+ altFilter.reset();
+ updateAltButtonColor();
+ }
+
+ virtual void OnAltSyncCfgRemoveConfirm(wxCommandEvent& event)
+ {
+ altSyncConfig.reset();
+ updateAltButtonColor();
+ }
+
+
+ private:
+ void OnAltFilterCfgRemove(wxCommandEvent& event)
+ {
+ contextMenu.reset(new wxMenu); //re-create context menu
+ contextMenu->Append(wxID_ANY, _("Remove alternate settings"));
+ contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(FolderPairPanelBasic::OnAltFilterCfgRemoveConfirm), NULL, this);
+ GuiPanel::PopupMenu(contextMenu.get()); //show context menu
+ }
+
+ void OnAltSyncCfgRemove(wxCommandEvent& event)
+ {
+ contextMenu.reset(new wxMenu); //re-create context menu
+ contextMenu->Append(wxID_ANY, _("Remove alternate settings"));
+ contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(FolderPairPanelBasic::OnAltSyncCfgRemoveConfirm), NULL, this);
+ GuiPanel::PopupMenu(contextMenu.get()); //show context menu
+ }
+
+ virtual MainConfiguration getMainConfig() const = 0;
+ virtual wxWindow* getParentWindow() = 0;
+
+ virtual void OnAltSyncCfgChange() {};
+
+ void OnAltSyncCfg(wxCommandEvent& event)
+ {
+ const MainConfiguration& mainCfg = getMainConfig();
+
+ AlternateSyncConfig altSyncCfg = altSyncConfig.get() ?
+ *altSyncConfig :
+ AlternateSyncConfig(mainCfg.syncConfiguration,
+ mainCfg.handleDeletion,
+ mainCfg.customDeletionDirectory);
+ SyncCfgDialog* syncDlg = new SyncCfgDialog(getParentWindow(),
+ mainCfg.compareVar,
+ altSyncCfg.syncConfiguration,
+ altSyncCfg.handleDeletion,
+ altSyncCfg.customDeletionDirectory,
+ NULL);
+ if (syncDlg->ShowModal() == SyncCfgDialog::BUTTON_APPLY)
+ {
+ altSyncConfig.reset(new AlternateSyncConfig(altSyncCfg));
+ updateAltButtonColor();
+
+ OnAltSyncCfgChange();
+ }
+ }
+
+ virtual void OnAltFilterCfgChange(bool defaultValueSet) {};
+
+ void OnAltFilterCfg(wxCommandEvent& event)
+ {
+ const MainConfiguration& mainCfg = getMainConfig();
+
+ AlternateFilter altFilt = altFilter.get() ?
+ *altFilter :
+ AlternateFilter(mainCfg.includeFilter, mainCfg.excludeFilter);
+
+ FilterDlg* filterDlg = new FilterDlg(getParentWindow(), altFilt.includeFilter, altFilt.excludeFilter);
+ if (filterDlg->ShowModal() == FilterDlg::BUTTON_APPLY)
+ {
+ altFilter.reset(new AlternateFilter(altFilt));
+ updateAltButtonColor();
+
+ if (altFilt.includeFilter == wxT("*") && altFilt.excludeFilter.empty()) //default
+ OnAltFilterCfgChange(true);
+ else
+ OnAltFilterCfgChange(false);
+ }
+ }
+
+ std::auto_ptr<wxMenu> contextMenu;
+
+ //support for drag and drop
+ std::auto_ptr<DragDropOnDlg> dragDropOnLeft;
+ std::auto_ptr<DragDropOnDlg> dragDropOnRight;
+ };
+}
+
+
+#endif // FOLDERPAIR_H_INCLUDED
diff --git a/ui/gridView.cpp b/ui/gridView.cpp
index 5406422b..9d9e9a1c 100644
--- a/ui/gridView.cpp
+++ b/ui/gridView.cpp
@@ -1,29 +1,12 @@
#include "gridView.h"
#include "sorting.h"
#include "../synchronization.h"
+#include <boost/bind.hpp>
-using FreeFileSync::GridView;
+using namespace FreeFileSync;
-GridView::GridView(FreeFileSync::FolderComparison& results) :
- leftOnlyFilesActive(false),
- rightOnlyFilesActive(false),
- leftNewerFilesActive(false),
- rightNewerFilesActive(false),
- differentFilesActive(false),
- equalFilesActive(false),
- conflictFilesActive(false),
- syncCreateLeftActive(false),
- syncCreateRightActive(false),
- syncDeleteLeftActive(false),
- syncDeleteRightActive(false),
- syncDirLeftActive(false),
- syncDirRightActive(false),
- syncDirNoneActive(false),
- folderCmp(results) {}
-
-
-GridView::StatusInfo::StatusInfo() :
+GridView::StatusCmpResult::StatusCmpResult() :
existsLeftOnly(false),
existsRightOnly(false),
existsLeftNewer(false),
@@ -31,6 +14,104 @@ GridView::StatusInfo::StatusInfo() :
existsDifferent(false),
existsEqual(false),
existsConflict(false),
+
+ filesOnLeftView(0),
+ foldersOnLeftView(0),
+ filesOnRightView(0),
+ foldersOnRightView(0) {}
+
+
+GridView::StatusCmpResult GridView::updateCmpResult(bool hideFiltered, //maps sortedRef to viewRef
+ bool leftOnlyFilesActive,
+ bool rightOnlyFilesActive,
+ bool leftNewerFilesActive,
+ bool rightNewerFilesActive,
+ bool differentFilesActive,
+ bool equalFilesActive,
+ bool conflictFilesActive)
+{
+ StatusCmpResult output;
+
+ viewRef.clear();
+
+ for (std::vector<RefIndex>::const_iterator j = sortedRef.begin(); j != sortedRef.end(); ++j)
+ {
+ const FileSystemObject* fsObj = getReferencedRow(*j);
+ if (fsObj)
+ {
+ //hide filtered row, if corresponding option is set
+ if (hideFiltered && !fsObj->selectedForSynchronization)
+ continue;
+
+ switch (fsObj->getCategory())
+ {
+ case FILE_LEFT_SIDE_ONLY:
+ output.existsLeftOnly = true;
+ if (!leftOnlyFilesActive) continue;
+ break;
+ case FILE_RIGHT_SIDE_ONLY:
+ output.existsRightOnly = true;
+ if (!rightOnlyFilesActive) continue;
+ break;
+ case FILE_LEFT_NEWER:
+ output.existsLeftNewer = true;
+ if (!leftNewerFilesActive) continue;
+ break;
+ case FILE_RIGHT_NEWER:
+ output.existsRightNewer = true;
+ if (!rightNewerFilesActive) continue;
+ break;
+ case FILE_DIFFERENT:
+ output.existsDifferent = true;
+ if (!differentFilesActive) continue;
+ break;
+ case FILE_EQUAL:
+ output.existsEqual = true;
+ if (!equalFilesActive) continue;
+ break;
+ case FILE_CONFLICT:
+ output.existsConflict = true;
+ if (!conflictFilesActive) continue;
+ break;
+ }
+
+ //calculate total number of bytes for each side
+ const FileMapping* fileObj = dynamic_cast<const FileMapping*>(fsObj);
+ if (fileObj)
+ {
+ if (!fileObj->isEmpty<LEFT_SIDE>())
+ {
+ output.filesizeLeftView += fileObj->getFileSize<LEFT_SIDE>();
+ ++output.filesOnLeftView;
+ }
+ if (!fileObj->isEmpty<RIGHT_SIDE>())
+ {
+ output.filesizeRightView += fileObj->getFileSize<RIGHT_SIDE>();
+ ++output.filesOnRightView;
+ }
+ }
+ else
+ {
+ const DirMapping* dirObj = dynamic_cast<const DirMapping*>(fsObj);
+ if (dirObj)
+ {
+ if (!dirObj->isEmpty<LEFT_SIDE>())
+ ++output.foldersOnLeftView;
+
+ if (!dirObj->isEmpty<RIGHT_SIDE>())
+ ++output.foldersOnRightView;
+ }
+ }
+
+ viewRef.push_back(*j);
+ }
+ }
+
+ return output;
+}
+
+
+GridView::StatusSyncPreview::StatusSyncPreview() :
existsSyncCreateLeft(false),
existsSyncCreateRight(false),
existsSyncDeleteLeft(false),
@@ -38,308 +119,398 @@ GridView::StatusInfo::StatusInfo() :
existsSyncDirLeft(false),
existsSyncDirRight(false),
existsSyncDirNone(false),
+ existsConflict(false),
filesOnLeftView(0),
foldersOnLeftView(0),
filesOnRightView(0),
- foldersOnRightView(0),
- objectsTotal(0) {}
-
-template <bool syncPreviewActive>
-GridView::StatusInfo GridView::update_sub(const bool hideFiltered)
+ foldersOnRightView(0) {}
+
+
+GridView::StatusSyncPreview GridView::updateSyncPreview(bool hideFiltered, //maps sortedRef to viewRef
+ bool syncCreateLeftActive,
+ bool syncCreateRightActive,
+ bool syncDeleteLeftActive,
+ bool syncDeleteRightActive,
+ bool syncDirOverwLeftActive,
+ bool syncDirOverwRightActive,
+ bool syncDirNoneActive,
+ bool conflictFilesActive)
{
- StatusInfo output;
+ StatusSyncPreview output;
- refView.clear();
+ viewRef.clear();
- for (FolderComparison::const_iterator j = folderCmp.begin(); j != folderCmp.end(); ++j)
+ for (std::vector<RefIndex>::const_iterator j = sortedRef.begin(); j != sortedRef.end(); ++j)
{
- const FileComparison& fileCmp = j->fileCmp;
-
- RefIndex newEntry;
- newEntry.folderIndex = j - folderCmp.begin();
-
- for (FileComparison::const_iterator i = fileCmp.begin(); i != fileCmp.end(); ++i)
+ const FileSystemObject* fsObj = getReferencedRow(*j);
+ if (fsObj)
{
- //process UI filter settings
- if (syncPreviewActive) //synchronization preview
- {
- //exclude result "=="
- if (i->cmpResult == FILE_EQUAL) //note: consider "objectsTotal"
- continue;
+ //synchronization preview
- output.objectsTotal++;
+ //exclude result "=="
+//#warning na dann consider mal!
+ if (fsObj->getCategory() == FILE_EQUAL) //note: consider "objectsTotal"
+ continue;
- //hide filtered row, if corresponding option is set
- if (hideFiltered && !i->selectedForSynchronization) //keep AFTER "objectsTotal++"
- continue;
+ //hide filtered row, if corresponding option is set
+ if (hideFiltered && !fsObj->selectedForSynchronization)
+ continue;
- switch (FreeFileSync::getSyncOperation(*i)) //evaluate comparison result and sync direction
- {
- case SO_CREATE_NEW_LEFT:
- output.existsSyncCreateLeft = true;
- if (!syncCreateLeftActive) continue;
- break;
- case SO_CREATE_NEW_RIGHT:
- output.existsSyncCreateRight = true;
- if (!syncCreateRightActive) continue;
- break;
- case SO_DELETE_LEFT:
- output.existsSyncDeleteLeft = true;
- if (!syncDeleteLeftActive) continue;
- break;
- case SO_DELETE_RIGHT:
- output.existsSyncDeleteRight = true;
- if (!syncDeleteRightActive) continue;
- break;
- case SO_OVERWRITE_RIGHT:
- output.existsSyncDirRight = true;
- if (!syncDirRightActive) continue;
- break;
- case SO_OVERWRITE_LEFT:
- output.existsSyncDirLeft = true;
- if (!syncDirLeftActive) continue;
- break;
- case SO_DO_NOTHING:
- output.existsSyncDirNone = true;
- if (!syncDirNoneActive) continue;
- break;
- case SO_UNRESOLVED_CONFLICT:
- output.existsConflict = true;
- if (!conflictFilesActive) continue;
- break;
- }
- }
- else //comparison results view
+ switch (FreeFileSync::getSyncOperation(*fsObj)) //evaluate comparison result and sync direction
{
- output.objectsTotal++;
-
- //hide filtered row, if corresponding option is set
- if (hideFiltered && !i->selectedForSynchronization)
- continue;
-
- switch (i->cmpResult)
- {
- case FILE_LEFT_SIDE_ONLY:
- output.existsLeftOnly = true;
- if (!leftOnlyFilesActive) continue;
- break;
- case FILE_RIGHT_SIDE_ONLY:
- output.existsRightOnly = true;
- if (!rightOnlyFilesActive) continue;
- break;
- case FILE_LEFT_NEWER:
- output.existsLeftNewer = true;
- if (!leftNewerFilesActive) continue;
- break;
- case FILE_RIGHT_NEWER:
- output.existsRightNewer = true;
- if (!rightNewerFilesActive) continue;
- break;
- case FILE_DIFFERENT:
- output.existsDifferent = true;
- if (!differentFilesActive) continue;
- break;
- case FILE_EQUAL:
- output.existsEqual = true;
- if (!equalFilesActive) continue;
- break;
- case FILE_CONFLICT:
- output.existsConflict = true;
- if (!conflictFilesActive) continue;
- break;
- }
+ case SO_CREATE_NEW_LEFT:
+ output.existsSyncCreateLeft = true;
+ if (!syncCreateLeftActive) continue;
+ break;
+ case SO_CREATE_NEW_RIGHT:
+ output.existsSyncCreateRight = true;
+ if (!syncCreateRightActive) continue;
+ break;
+ case SO_DELETE_LEFT:
+ output.existsSyncDeleteLeft = true;
+ if (!syncDeleteLeftActive) continue;
+ break;
+ case SO_DELETE_RIGHT:
+ output.existsSyncDeleteRight = true;
+ if (!syncDeleteRightActive) continue;
+ break;
+ case SO_OVERWRITE_RIGHT:
+ output.existsSyncDirRight = true;
+ if (!syncDirOverwRightActive) continue;
+ break;
+ case SO_OVERWRITE_LEFT:
+ output.existsSyncDirLeft = true;
+ if (!syncDirOverwLeftActive) continue;
+ break;
+ case SO_DO_NOTHING:
+ output.existsSyncDirNone = true;
+ if (!syncDirNoneActive) continue;
+ break;
+ case SO_UNRESOLVED_CONFLICT:
+ output.existsConflict = true;
+ if (!conflictFilesActive) continue;
+ break;
}
//calculate total number of bytes for each side
- if (i->fileDescrLeft.objType == FileDescrLine::TYPE_FILE)
+ const FileMapping* fileObj = dynamic_cast<const FileMapping*>(fsObj);
+ if (fileObj)
{
- output.filesizeLeftView += i->fileDescrLeft.fileSize;
- ++output.filesOnLeftView;
+ if (!fileObj->isEmpty<LEFT_SIDE>())
+ {
+ output.filesizeLeftView += fileObj->getFileSize<LEFT_SIDE>();
+ ++output.filesOnLeftView;
+ }
+ if (!fileObj->isEmpty<RIGHT_SIDE>())
+ {
+ output.filesizeRightView += fileObj->getFileSize<RIGHT_SIDE>();
+ ++output.filesOnRightView;
+ }
}
- else if (i->fileDescrLeft.objType == FileDescrLine::TYPE_DIRECTORY)
- ++output.foldersOnLeftView;
-
- if (i->fileDescrRight.objType == FileDescrLine::TYPE_FILE)
+ else
{
- output.filesizeRightView += i->fileDescrRight.fileSize;
- ++output.filesOnRightView;
+ const DirMapping* dirObj = dynamic_cast<const DirMapping*>(fsObj);
+ if (dirObj)
+ {
+ if (!dirObj->isEmpty<LEFT_SIDE>())
+ ++output.foldersOnLeftView;
+
+ if (!dirObj->isEmpty<RIGHT_SIDE>())
+ ++output.foldersOnRightView;
+ }
}
- else if (i->fileDescrRight.objType == FileDescrLine::TYPE_DIRECTORY)
- ++output.foldersOnRightView;
- newEntry.rowIndex = i - fileCmp.begin();
- refView.push_back(newEntry);
+ viewRef.push_back(*j);
}
-
-// //add some empty line after each folder pair
-// RefIndex emptyLine;
-// emptyLine.folderIndex = -1;
-// emptyLine.rowIndex = 0;
-// refView.push_back(emptyLine);
}
return output;
}
-GridView::StatusInfo GridView::update(const bool hideFiltered, const bool syncPreviewActive)
+void GridView::getAllFileRef(const std::set<unsigned int>& guiRows, std::vector<FileSystemObject*>& output)
{
- return syncPreviewActive ?
- update_sub<true>(hideFiltered) :
- update_sub<false>(hideFiltered);
+ std::set<unsigned int>::const_iterator upperEnd = guiRows.lower_bound(rowsOnView()); //loop over valid rows only!
+
+ output.clear();
+ output.reserve(guiRows.size());
+ for (std::set<unsigned int>::const_iterator i = guiRows.begin(); i != upperEnd; ++i)
+ {
+ FileSystemObject* fsObj = getReferencedRow(viewRef[*i]);
+ if (fsObj)
+ output.push_back(fsObj);
+ }
}
-void GridView::resetSettings()
+inline
+bool GridView::isInvalidRow(const RefIndex& ref) const
{
- leftOnlyFilesActive = true;
- leftNewerFilesActive = true;
- differentFilesActive = true;
- rightNewerFilesActive = true; //do not save/load these bool values from harddisk!
- rightOnlyFilesActive = true; //it's more convenient to have them defaulted at startup
- equalFilesActive = false;
-
- conflictFilesActive = true;
-
- syncCreateLeftActive = true;
- syncCreateRightActive = true;
- syncDeleteLeftActive = true;
- syncDeleteRightActive = true;
- syncDirLeftActive = true;
- syncDirRightActive = true;
- syncDirNoneActive = true;
+ return getReferencedRow(ref) == NULL;
}
-void GridView::clearView()
+void GridView::removeInvalidRows()
{
- refView.clear();
+ viewRef.clear();
+
+ //remove rows that have been deleted meanwhile
+ sortedRef.erase(std::remove_if(sortedRef.begin(), sortedRef.end(),
+ boost::bind(&GridView::isInvalidRow, this, _1)), sortedRef.end());
}
-void GridView::viewRefToFolderRef(const std::set<int>& viewRef, FreeFileSync::FolderCompRef& output)
+void GridView::clearAllRows()
{
- output.clear();
- for (int i = 0; i < int(folderCmp.size()); ++i)
- output.push_back(std::set<int>()); //avoid copy by value for full set<int>
+ viewRef.clear();
+ sortedRef.clear();
+ folderCmp.clear();
+}
- for (std::set<int>::const_iterator i = viewRef.begin(); i != viewRef.end(); ++i)
+
+class GridView::SerializeHierarchy
+{
+public:
+ SerializeHierarchy(std::vector<GridView::RefIndex>& sortedRef, unsigned int index) :
+ index_(index),
+ sortedRef_(sortedRef) {}
+
+ void execute(const HierarchyObject& hierObj)
{
- const unsigned int folder = refView[*i].folderIndex;
- const unsigned int row = refView[*i].rowIndex;
+ //add file references
+ std::for_each(hierObj.subFiles.begin(), hierObj.subFiles.end(), *this);
- output[folder].insert(row);
+ //add dir references
+ std::for_each(hierObj.subDirs.begin(), hierObj.subDirs.end(), *this);
}
-}
+ void operator()(const FileMapping& fileObj)
+ {
+ sortedRef_.push_back(RefIndex(index_, fileObj.getId()));
+ }
+
+ void operator()(const DirMapping& dirObj)
+ {
+ sortedRef_.push_back(RefIndex(index_, dirObj.getId()));
+ execute(dirObj); //add recursion here to list sub-objects directly below parent!
+ }
+
+private:
+ unsigned int index_;
+ std::vector<GridView::RefIndex>& sortedRef_;
+};
-bool GridView::refGridIsEmpty() const
+
+void GridView::setData(FolderComparison& newData)
{
- for (FolderComparison::const_iterator j = folderCmp.begin(); j != folderCmp.end(); ++j)
- if (!j->fileCmp.empty()) return false;
+ viewRef.clear();
+ sortedRef.clear();
+ folderCmp.swap(newData);
- return true;
+ unsigned int index = 0;
+
+ //fill sortedRef
+ for (FolderComparison::const_iterator j = folderCmp.begin(); j != folderCmp.end(); ++j)
+ SerializeHierarchy(sortedRef, index++).execute(*j);
}
-template <typename CompareFct>
-void bubbleSort(FreeFileSync::FolderComparison& folderCmp, CompareFct compare)
+//------------------------------------ SORTING TEMPLATES ------------------------------------------------
+template <bool ascending>
+class GridView::SortByDirectory : public std::binary_function<RefIndex, RefIndex, bool>
{
- for (int i = folderCmp.size() - 2; i >= 0; --i)
+public:
+ bool operator()(const RefIndex a, const RefIndex b) const
{
- bool swapped = false;
- for (int j = 0; j <= i; ++j)
- if (compare(folderCmp[j + 1], folderCmp[j]))
- {
- folderCmp[j + 1].swap(folderCmp[j]);
- swapped = true;
- }
+ return ascending ?
+ a.folderIndex < b.folderIndex :
+ a.folderIndex > b.folderIndex;
+ }
+};
- if (!swapped)
- return;
+
+template <bool ascending, FreeFileSync::SelectedSide side>
+class GridView::SortByRelName : public std::binary_function<RefIndex, RefIndex, bool>
+{
+public:
+ SortByRelName(const GridView& view) : m_view(view) {}
+
+ bool operator()(const RefIndex a, const RefIndex b) const
+ {
+ //presort by folder pair
+ if (a.folderIndex != b.folderIndex)
+ return ascending ?
+ a.folderIndex < b.folderIndex :
+ a.folderIndex > b.folderIndex;
+
+ const FileSystemObject* fsObjA = m_view.getReferencedRow(a);
+ const FileSystemObject* fsObjB = m_view.getReferencedRow(b);
+ if (fsObjA == NULL) //invalid rows shall appear at the end
+ return false;
+ else if (fsObjB == NULL)
+ return true;
+
+ return sortByRelativeName<ascending, side>(*fsObjA, *fsObjB);
}
-}
+private:
+ const GridView& m_view;
+};
-template <class T>
-struct CompareGreater
+template <bool ascending, FreeFileSync::SelectedSide side>
+class GridView::SortByFileName : public std::binary_function<RefIndex, RefIndex, bool>
{
- typedef bool (*CmpLess) (const T& a, const T& b);
- CompareGreater(CmpLess cmpFct) : m_cmpFct(cmpFct) {}
+public:
+ SortByFileName(const GridView& view) : m_view(view) {}
- bool operator()(const T& a, const T& b) const
+ bool operator()(const RefIndex a, const RefIndex b) const
{
- return m_cmpFct(b, a);
+ const FileSystemObject* fsObjA = m_view.getReferencedRow(a);
+ const FileSystemObject* fsObjB = m_view.getReferencedRow(b);
+ if (fsObjA == NULL) //invalid rows shall appear at the end
+ return false;
+ else if (fsObjB == NULL)
+ return true;
+
+ return sortByFileName<ascending, side>(*fsObjA, *fsObjB);
}
private:
- CmpLess m_cmpFct;
+ const GridView& m_view;
};
-void GridView::sortView(const SortType type, const bool onLeft, const bool ascending)
+template <bool ascending, FreeFileSync::SelectedSide side>
+class GridView::SortByFileSize : public std::binary_function<RefIndex, RefIndex, bool>
{
- using namespace FreeFileSync;
- typedef CompareGreater<FolderCompareLine> FolderReverse;
+public:
+ SortByFileSize(const GridView& view) : m_view(view) {}
- if (type == SORT_BY_DIRECTORY)
+ bool operator()(const RefIndex a, const RefIndex b) const
{
- //specialization: use custom sorting function based on FolderComparison::swap()
- //bubble sort is no performance issue since number of folder pairs should be "very small"
- if (ascending && onLeft) bubbleSort(folderCmp, sortByDirectory<SORT_ON_LEFT>);
- else if (ascending && !onLeft) bubbleSort(folderCmp, sortByDirectory<SORT_ON_RIGHT>);
- else if (!ascending && onLeft) bubbleSort(folderCmp, FolderReverse(sortByDirectory<SORT_ON_LEFT>));
- else if (!ascending && !onLeft) bubbleSort(folderCmp, FolderReverse(sortByDirectory<SORT_ON_RIGHT>));
-
- //then sort by relative name
- GridView::sortView(SORT_BY_REL_NAME, onLeft, ascending);
- return;
+ const FileSystemObject* fsObjA = m_view.getReferencedRow(a);
+ const FileSystemObject* fsObjB = m_view.getReferencedRow(b);
+ if (fsObjA == NULL) //invalid rows shall appear at the end
+ return false;
+ else if (fsObjB == NULL)
+ return true;
+
+ return sortByFileSize<ascending, side>(*fsObjA, *fsObjB);
}
+private:
+ const GridView& m_view;
+};
+
- typedef CompareGreater<FileCompareLine> FileReverse;
+template <bool ascending, FreeFileSync::SelectedSide side>
+class GridView::SortByDate : public std::binary_function<RefIndex, RefIndex, bool>
+{
+public:
+ SortByDate(const GridView& view) : m_view(view) {}
- for (FolderComparison::iterator j = folderCmp.begin(); j != folderCmp.end(); ++j)
+ bool operator()(const RefIndex a, const RefIndex b) const
{
- FileComparison& fileCmp = j->fileCmp;
+ const FileSystemObject* fsObjA = m_view.getReferencedRow(a);
+ const FileSystemObject* fsObjB = m_view.getReferencedRow(b);
+ if (fsObjA == NULL) //invalid rows shall appear at the end
+ return false;
+ else if (fsObjB == NULL)
+ return true;
+
+ return sortByDate<ascending, side>(*fsObjA, *fsObjB);
+ }
+private:
+ const GridView& m_view;
+};
- switch (type)
- {
- case SORT_BY_REL_NAME:
- if ( ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByRelativeName<SORT_ON_LEFT>);
- else if ( ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByRelativeName<SORT_ON_RIGHT>);
- else if (!ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), FileReverse(sortByRelativeName<SORT_ON_LEFT>));
- else if (!ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), FileReverse(sortByRelativeName<SORT_ON_RIGHT>));
- break;
- case SORT_BY_FILENAME:
- if ( ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByFileName<SORT_ON_LEFT>);
- else if ( ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByFileName<SORT_ON_RIGHT>);
- else if (!ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), FileReverse(sortByFileName<SORT_ON_LEFT>));
- else if (!ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), FileReverse(sortByFileName<SORT_ON_RIGHT>));
- break;
- case SORT_BY_FILESIZE:
- if ( ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByFileSize<SORT_ON_LEFT>);
- else if ( ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByFileSize<SORT_ON_RIGHT>);
- else if (!ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), FileReverse(sortByFileSize<SORT_ON_LEFT>));
- else if (!ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), FileReverse(sortByFileSize<SORT_ON_RIGHT>));
- break;
- case SORT_BY_DATE:
- if ( ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByDate<SORT_ON_LEFT>);
- else if ( ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByDate<SORT_ON_RIGHT>);
- else if (!ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), FileReverse(sortByDate<SORT_ON_LEFT>));
- else if (!ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), FileReverse(sortByDate<SORT_ON_RIGHT>));
- break;
- case SORT_BY_CMP_RESULT:
- if ( ascending) std::sort(fileCmp.begin(), fileCmp.end(), sortByCmpResult);
- else if (!ascending) std::sort(fileCmp.begin(), fileCmp.end(), FileReverse(sortByCmpResult));
- break;
- case SORT_BY_SYNC_DIRECTION:
- if ( ascending) std::sort(fileCmp.begin(), fileCmp.end(), sortBySyncDirection);
- else if (!ascending) std::sort(fileCmp.begin(), fileCmp.end(), FileReverse(sortBySyncDirection));
- break;
- case SORT_BY_DIRECTORY:
- assert(false);
- }
+
+template <bool ascending>
+class GridView::SortByCmpResult : public std::binary_function<RefIndex, RefIndex, bool>
+{
+public:
+ SortByCmpResult(const GridView& view) : m_view(view) {}
+
+ bool operator()(const RefIndex a, const RefIndex b) const
+ {
+ const FileSystemObject* fsObjA = m_view.getReferencedRow(a);
+ const FileSystemObject* fsObjB = m_view.getReferencedRow(b);
+ if (fsObjA == NULL) //invalid rows shall appear at the end
+ return false;
+ else if (fsObjB == NULL)
+ return true;
+
+ return sortByCmpResult<ascending>(*fsObjA, *fsObjB);
+ }
+private:
+ const GridView& m_view;
+};
+
+
+template <bool ascending>
+class GridView::SortBySyncDirection : public std::binary_function<RefIndex, RefIndex, bool>
+{
+public:
+ SortBySyncDirection(const GridView& view) : m_view(view) {}
+
+ bool operator()(const RefIndex a, const RefIndex b) const
+ {
+ const FileSystemObject* fsObjA = m_view.getReferencedRow(a);
+ const FileSystemObject* fsObjB = m_view.getReferencedRow(b);
+ if (fsObjA == NULL) //invalid rows shall appear at the end
+ return false;
+ else if (fsObjB == NULL)
+ return true;
+
+ return sortBySyncDirection<ascending>(*fsObjA, *fsObjB);
+ }
+private:
+ const GridView& m_view;
+};
+
+//-------------------------------------------------------------------------------------------------------
+void GridView::sortView(const SortType type, const bool onLeft, const bool ascending)
+{
+ viewRef.clear();
+
+ switch (type)
+ {
+ case SORT_BY_REL_NAME:
+ if ( ascending && onLeft) std::sort(sortedRef.begin(), sortedRef.end(), SortByRelName<true, LEFT_SIDE>(*this));
+ else if ( ascending && !onLeft) std::sort(sortedRef.begin(), sortedRef.end(), SortByRelName<true, RIGHT_SIDE>(*this));
+ else if (!ascending && onLeft) std::sort(sortedRef.begin(), sortedRef.end(), SortByRelName<false, LEFT_SIDE >(*this));
+ else if (!ascending && !onLeft) std::sort(sortedRef.begin(), sortedRef.end(), SortByRelName<false, RIGHT_SIDE>(*this));
+ break;
+ case SORT_BY_FILENAME:
+ if ( ascending && onLeft) std::sort(sortedRef.begin(), sortedRef.end(), SortByFileName<true, LEFT_SIDE >(*this));
+ else if ( ascending && !onLeft) std::sort(sortedRef.begin(), sortedRef.end(), SortByFileName<true, RIGHT_SIDE>(*this));
+ else if (!ascending && onLeft) std::sort(sortedRef.begin(), sortedRef.end(), SortByFileName<false, LEFT_SIDE >(*this));
+ else if (!ascending && !onLeft) std::sort(sortedRef.begin(), sortedRef.end(), SortByFileName<false, RIGHT_SIDE>(*this));
+ break;
+ case SORT_BY_FILESIZE:
+ if ( ascending && onLeft) std::sort(sortedRef.begin(), sortedRef.end(), SortByFileSize<true, LEFT_SIDE >(*this));
+ else if ( ascending && !onLeft) std::sort(sortedRef.begin(), sortedRef.end(), SortByFileSize<true, RIGHT_SIDE>(*this));
+ else if (!ascending && onLeft) std::sort(sortedRef.begin(), sortedRef.end(), SortByFileSize<false, LEFT_SIDE >(*this));
+ else if (!ascending && !onLeft) std::sort(sortedRef.begin(), sortedRef.end(), SortByFileSize<false, RIGHT_SIDE>(*this));
+ break;
+ case SORT_BY_DATE:
+ if ( ascending && onLeft) std::sort(sortedRef.begin(), sortedRef.end(), SortByDate<true, LEFT_SIDE >(*this));
+ else if ( ascending && !onLeft) std::sort(sortedRef.begin(), sortedRef.end(), SortByDate<true, RIGHT_SIDE>(*this));
+ else if (!ascending && onLeft) std::sort(sortedRef.begin(), sortedRef.end(), SortByDate<false, LEFT_SIDE >(*this));
+ else if (!ascending && !onLeft) std::sort(sortedRef.begin(), sortedRef.end(), SortByDate<false, RIGHT_SIDE>(*this));
+ break;
+ case SORT_BY_CMP_RESULT:
+ if ( ascending) std::stable_sort(sortedRef.begin(), sortedRef.end(), SortByCmpResult<true >(*this));
+ else if (!ascending) std::stable_sort(sortedRef.begin(), sortedRef.end(), SortByCmpResult<false>(*this));
+ break;
+ case SORT_BY_SYNC_DIRECTION:
+ if ( ascending) std::stable_sort(sortedRef.begin(), sortedRef.end(), SortBySyncDirection<true >(*this));
+ else if (!ascending) std::stable_sort(sortedRef.begin(), sortedRef.end(), SortBySyncDirection<false>(*this));
+ break;
+ case SORT_BY_DIRECTORY:
+ if ( ascending) std::stable_sort(sortedRef.begin(), sortedRef.end(), SortByDirectory<true>());
+ else if (!ascending) std::stable_sort(sortedRef.begin(), sortedRef.end(), SortByDirectory<false>());
+ break;
}
}
diff --git a/ui/gridView.h b/ui/gridView.h
index 8603bbd2..c7728b06 100644
--- a/ui/gridView.h
+++ b/ui/gridView.h
@@ -1,7 +1,7 @@
#ifndef GRIDVIEW_H_INCLUDED
#define GRIDVIEW_H_INCLUDED
-#include "../structures.h"
+#include "../fileHierarchy.h"
namespace FreeFileSync
@@ -10,23 +10,18 @@ namespace FreeFileSync
class GridView
{
public:
- GridView(FolderComparison& results);
+ //direct data access via row number
+ const FileSystemObject* getObject(unsigned int row) const; //returns NULL if object is not found; logarithmic complexity
+ FileSystemObject* getObject(unsigned int row); //
+ unsigned int rowsOnView() const; //only the currently visible elements
+ unsigned int rowsTotal() const; //total number of rows available
- const FileCompareLine& operator[] (unsigned row) const;
- FileCompareLine& operator[] (unsigned row);
+ //get references to FileSystemObject: no NULL-check needed! Everything's bound.
+ void getAllFileRef(const std::set<unsigned int>& guiRows, std::vector<FileSystemObject*>& output);
- unsigned int elementsOnView() const; //only the currently visible elements
-
- bool refGridIsEmpty() const;
-
- //convert view references to FolderCompRef
- void viewRefToFolderRef(const std::set<int>& viewRef, FolderCompRef& output);
-
- const FolderPair getFolderPair(const unsigned int row) const;
-
- struct StatusInfo
+ struct StatusCmpResult
{
- StatusInfo();
+ StatusCmpResult();
bool existsLeftOnly;
bool existsRightOnly;
@@ -36,6 +31,29 @@ namespace FreeFileSync
bool existsEqual;
bool existsConflict;
+ unsigned int filesOnLeftView;
+ unsigned int foldersOnLeftView;
+ unsigned int filesOnRightView;
+ unsigned int foldersOnRightView;
+
+ wxULongLong filesizeLeftView;
+ wxULongLong filesizeRightView;
+ };
+
+ //comparison results view
+ StatusCmpResult updateCmpResult(bool hideFiltered,
+ bool leftOnlyFilesActive,
+ bool rightOnlyFilesActive,
+ bool leftNewerFilesActive,
+ bool rightNewerFilesActive,
+ bool differentFilesActive,
+ bool equalFilesActive,
+ bool conflictFilesActive);
+
+ struct StatusSyncPreview
+ {
+ StatusSyncPreview();
+
bool existsSyncCreateLeft;
bool existsSyncCreateRight;
bool existsSyncDeleteLeft;
@@ -43,41 +61,34 @@ namespace FreeFileSync
bool existsSyncDirLeft;
bool existsSyncDirRight;
bool existsSyncDirNone;
+ bool existsConflict;
unsigned int filesOnLeftView;
unsigned int foldersOnLeftView;
unsigned int filesOnRightView;
unsigned int foldersOnRightView;
- unsigned int objectsTotal;
-
wxULongLong filesizeLeftView;
wxULongLong filesizeRightView;
};
- StatusInfo update(const bool hideFiltered, const bool syncPreviewActive);
-
- void clearView(); //clear all references on compare results table: needed if there is a mismatch between references and actual data
-
- //UI View Filter settings
- //compare result
- bool leftOnlyFilesActive;
- bool rightOnlyFilesActive;
- bool leftNewerFilesActive;
- bool rightNewerFilesActive;
- bool differentFilesActive;
- bool equalFilesActive;
- bool conflictFilesActive;
- //sync preview
- bool syncCreateLeftActive;
- bool syncCreateRightActive;
- bool syncDeleteLeftActive;
- bool syncDeleteRightActive;
- bool syncDirLeftActive;
- bool syncDirRightActive;
- bool syncDirNoneActive;
-
- void resetSettings();
+ //synchronization preview
+ StatusSyncPreview updateSyncPreview(bool hideFiltered,
+ bool syncCreateLeftActive,
+ bool syncCreateRightActive,
+ bool syncDeleteLeftActive,
+ bool syncDeleteRightActive,
+ bool syncDirOverwLeftActive,
+ bool syncDirOverwRightActive,
+ bool syncDirNoneActive,
+ bool conflictFilesActive);
+
+
+
+ FolderComparison& getDataTentative(); //get data for operation that does NOT add or reorder rows! (deletion is okay)
+ void setData(FolderComparison& newData); //set data, taking ownership: warning std::swap() is used!!!
+ void removeInvalidRows(); //remove rows that have been deleted meanwhile: call after manual deletion and synchronization!
+ void clearAllRows(); //clears everything
//sorting...
enum SortType
@@ -91,55 +102,120 @@ namespace FreeFileSync
SORT_BY_SYNC_DIRECTION
};
- void sortView(const SortType type, const bool onLeft, const bool ascending);
+ void sortView(const SortType type, const bool onLeft, const bool ascending); //always call this method for sorting, never sort externally!
private:
- template <bool syncPreviewActive>
- StatusInfo update_sub(const bool hideFiltered);
+ class SerializeHierarchy;
struct RefIndex
{
+ RefIndex(unsigned int folderInd, FileSystemObject::ObjectID id) :
+ folderIndex(folderInd),
+ objId(id) {}
unsigned int folderIndex;
- unsigned int rowIndex;
+ FileSystemObject::ObjectID objId;
};
- std::vector<RefIndex> refView;
- FolderComparison& folderCmp;
+ FileSystemObject* getReferencedRow(const RefIndex ref); //returns NULL if not found
+ const FileSystemObject* getReferencedRow(const RefIndex ref) const; //returns NULL if not found
+ bool isInvalidRow(const RefIndex& ref) const;
+
+
+ std::vector<RefIndex> viewRef; //partial view on sortedRef
+ // |
+ // | (update...)
+ // \|/
+ std::vector<RefIndex> sortedRef; //equivalent to folerCmp, but may be sorted
+ // |
+ // | (setData)
+ // \|/
+ FolderComparison folderCmp; //actual comparison data: owned by GridView!
+
+
+ //sorting classes
+ template <bool ascending>
+ class SortByDirectory;
+
+ template <bool ascending, SelectedSide side>
+ class SortByRelName;
+
+ template <bool ascending, SelectedSide side>
+ class SortByFileName;
+
+ template <bool ascending, SelectedSide side>
+ class SortByFileSize;
+
+ template <bool ascending, SelectedSide side>
+ class SortByDate;
+
+ template <bool ascending>
+ class SortByCmpResult;
+
+ template <bool ascending>
+ class SortBySyncDirection;
};
+
+
+
+
+
+
+
+
//############################################################################
//inline implementation
+
inline
- const FileCompareLine& GridView::operator[] (unsigned row) const
+ const FileSystemObject* GridView::getObject(unsigned int row) const
{
- const unsigned int folderInd = refView[row].folderIndex;
- const unsigned int rowInd = refView[row].rowIndex;
-
- return folderCmp[folderInd].fileCmp[rowInd];
+ if (row < rowsOnView())
+ return getReferencedRow(viewRef[row]);
+ else
+ return NULL;
}
inline
- FileCompareLine& GridView::operator[] (unsigned row)
+ FileSystemObject* GridView::getObject(unsigned int row)
{
//code re-use of const method: see Meyers Effective C++
- return const_cast<FileCompareLine&>(static_cast<const GridView&>(*this).operator[](row));
+ return const_cast<FileSystemObject*>(static_cast<const GridView&>(*this).getObject(row));
}
inline
- unsigned int GridView::elementsOnView() const
+ unsigned int GridView::rowsOnView() const
{
- return refView.size();
+ return viewRef.size();
}
inline
- const FolderPair GridView::getFolderPair(const unsigned int row) const
+ FolderComparison& GridView::getDataTentative()
{
- const unsigned int folderInd = refView[row].folderIndex;
- const FolderCompareLine& folderCmpLine = folderCmp[folderInd];
- return folderCmpLine.syncPair;
+ return folderCmp;
+ }
+
+ inline
+ unsigned int GridView::rowsTotal() const //total number of rows available
+ {
+ return sortedRef.size();
+ }
+
+
+ inline
+ const FreeFileSync::FileSystemObject* GridView::getReferencedRow(const RefIndex ref) const
+ {
+ return folderCmp[ref.folderIndex].retrieveById(ref.objId);
+ }
+
+
+ inline
+ FreeFileSync::FileSystemObject* GridView::getReferencedRow(const RefIndex ref)
+ {
+ //code re-use of const method: see Meyers Effective C++
+ return const_cast<FileSystemObject*>(static_cast<const GridView&>(*this).getReferencedRow(ref));
}
}
diff --git a/ui/guiGenerated.cpp b/ui/guiGenerated.cpp
index a3db4dd8..61fc95d3 100644
--- a/ui/guiGenerated.cpp
+++ b/ui/guiGenerated.cpp
@@ -7,6 +7,7 @@
#include "../library/customGrid.h"
#include "../shared/customButton.h"
+#include "../shared/toggleButton.h"
#include "guiGenerated.h"
@@ -31,13 +32,14 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const
m_menuFile->AppendSeparator();
- wxMenuItem* m_menuItem14;
- m_menuItem14 = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("S&ave configuration") ) + wxT('\t') + wxT("CTRL-S"), wxEmptyString, wxITEM_NORMAL );
- m_menuFile->Append( m_menuItem14 );
+ m_menuItemNew = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("&New") ) + wxT('\t') + wxT("CTRL-N"), wxEmptyString, wxITEM_NORMAL );
+ m_menuFile->Append( m_menuItemNew );
- wxMenuItem* m_menuItem13;
- m_menuItem13 = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("&Load configuration") ) + wxT('\t') + wxT("CTRL-L"), wxEmptyString, wxITEM_NORMAL );
- m_menuFile->Append( m_menuItem13 );
+ m_menuItemSave = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("S&ave configuration") ) + wxT('\t') + wxT("CTRL-S"), wxEmptyString, wxITEM_NORMAL );
+ m_menuFile->Append( m_menuItemSave );
+
+ m_menuItemLoad = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("&Load configuration") ) + wxT('\t') + wxT("CTRL-L"), wxEmptyString, wxITEM_NORMAL );
+ m_menuFile->Append( m_menuItemLoad );
m_menuFile->AppendSeparator();
@@ -235,13 +237,6 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const
sbSizer3->Add( m_bpButtonAddPair, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 3 );
- m_bpButtonRemoveTopPair = new wxBitmapButton( m_panelTopRight, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 19,21 ), wxBU_AUTODRAW );
- m_bpButtonRemoveTopPair->SetToolTip( _("Remove folder pair") );
-
- m_bpButtonRemoveTopPair->SetToolTip( _("Remove folder pair") );
-
- sbSizer3->Add( m_bpButtonRemoveTopPair, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 );
-
m_directoryRight = new wxComboBox( m_panelTopRight, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
sbSizer3->Add( m_directoryRight, 1, wxALIGN_CENTER_VERTICAL, 5 );
@@ -411,7 +406,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const
bSizer139->Add( m_bpButtonLoad, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
wxArrayString m_choiceHistoryChoices;
- m_choiceHistory = new wxChoice( m_panel30, wxID_ANY, wxDefaultPosition, wxSize( 150,-1 ), m_choiceHistoryChoices, 0 );
+ m_choiceHistory = new wxChoice( m_panel30, wxID_ANY, wxDefaultPosition, wxSize( 170,-1 ), m_choiceHistoryChoices, 0 );
m_choiceHistory->SetSelection( 0 );
m_choiceHistory->SetToolTip( _("Load configuration history (press DEL to delete items)") );
@@ -465,46 +460,46 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const
sbSizer31->Add( 0, 0, 1, wxEXPAND, 5 );
- m_bpButtonLeftOnly = new wxBitmapButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
+ m_bpButtonLeftOnly = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
sbSizer31->Add( m_bpButtonLeftOnly, 0, wxALIGN_CENTER_VERTICAL, 5 );
- m_bpButtonLeftNewer = new wxBitmapButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
+ m_bpButtonLeftNewer = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
sbSizer31->Add( m_bpButtonLeftNewer, 0, wxALIGN_CENTER_VERTICAL, 5 );
- m_bpButtonEqual = new wxBitmapButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
+ m_bpButtonEqual = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
sbSizer31->Add( m_bpButtonEqual, 0, wxALIGN_CENTER_VERTICAL, 5 );
- m_bpButtonDifferent = new wxBitmapButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
+ m_bpButtonDifferent = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
sbSizer31->Add( m_bpButtonDifferent, 0, wxALIGN_CENTER_VERTICAL, 5 );
- m_bpButtonRightNewer = new wxBitmapButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
+ m_bpButtonRightNewer = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
sbSizer31->Add( m_bpButtonRightNewer, 0, wxALIGN_CENTER_VERTICAL, 5 );
- m_bpButtonRightOnly = new wxBitmapButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
+ m_bpButtonRightOnly = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
sbSizer31->Add( m_bpButtonRightOnly, 0, wxALIGN_CENTER_VERTICAL, 5 );
- m_bpButtonSyncCreateLeft = new wxBitmapButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
+ m_bpButtonSyncCreateLeft = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
sbSizer31->Add( m_bpButtonSyncCreateLeft, 0, wxALIGN_CENTER_VERTICAL, 5 );
- m_bpButtonSyncDirLeft = new wxBitmapButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
- sbSizer31->Add( m_bpButtonSyncDirLeft, 0, wxALIGN_CENTER_VERTICAL, 5 );
+ m_bpButtonSyncDirOverwLeft = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
+ sbSizer31->Add( m_bpButtonSyncDirOverwLeft, 0, wxALIGN_CENTER_VERTICAL, 5 );
- m_bpButtonSyncDeleteLeft = new wxBitmapButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
+ m_bpButtonSyncDeleteLeft = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
sbSizer31->Add( m_bpButtonSyncDeleteLeft, 0, wxALIGN_CENTER_VERTICAL, 5 );
- m_bpButtonSyncDirNone = new wxBitmapButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
+ m_bpButtonSyncDirNone = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
sbSizer31->Add( m_bpButtonSyncDirNone, 0, wxALIGN_CENTER_VERTICAL, 5 );
- m_bpButtonSyncDeleteRight = new wxBitmapButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
+ m_bpButtonSyncDeleteRight = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
sbSizer31->Add( m_bpButtonSyncDeleteRight, 0, wxALIGN_CENTER_VERTICAL, 5 );
- m_bpButtonSyncDirRight = new wxBitmapButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
- sbSizer31->Add( m_bpButtonSyncDirRight, 0, wxALIGN_CENTER_VERTICAL, 5 );
+ m_bpButtonSyncDirOverwRight = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
+ sbSizer31->Add( m_bpButtonSyncDirOverwRight, 0, wxALIGN_CENTER_VERTICAL, 5 );
- m_bpButtonSyncCreateRight = new wxBitmapButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
+ m_bpButtonSyncCreateRight = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
sbSizer31->Add( m_bpButtonSyncCreateRight, 0, wxALIGN_CENTER_VERTICAL, 5 );
- m_bpButtonConflict = new wxBitmapButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
+ m_bpButtonConflict = new ToggleButton( m_panel112, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW );
sbSizer31->Add( m_bpButtonConflict, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
@@ -690,8 +685,9 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const
this->Connect( m_menuItem10->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnCompare ) );
this->Connect( m_menuItem11->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnStartSync ) );
this->Connect( m_menuItemSwitchView->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnSwitchView ) );
- this->Connect( m_menuItem14->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnSaveConfig ) );
- this->Connect( m_menuItem13->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnLoadConfig ) );
+ this->Connect( m_menuItemNew->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnNewConfig ) );
+ this->Connect( m_menuItemSave->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnSaveConfig ) );
+ this->Connect( m_menuItemLoad->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnLoadConfig ) );
this->Connect( m_menuItem4->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuQuit ) );
this->Connect( m_menuItemGlobSett->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuGlobalSettings ) );
this->Connect( m_menuItem7->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuBatchJob ) );
@@ -706,7 +702,6 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const
m_dirPickerLeft->Connect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( MainDialogGenerated::OnDirSelected ), NULL, this );
m_bpButtonSwapSides->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSwapSides ), NULL, this );
m_bpButtonAddPair->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnAddFolderPair ), NULL, this );
- m_bpButtonRemoveTopPair->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnRemoveTopFolderPair ), NULL, this );
m_directoryRight->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( MainDialogGenerated::OnFolderHistoryKeyEvent ), NULL, this );
m_dirPickerRight->Connect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( MainDialogGenerated::OnDirSelected ), NULL, this );
m_gridLeft->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( MainDialogGenerated::OnLeftGridDoubleClick ), NULL, this );
@@ -734,11 +729,11 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const
m_bpButtonRightNewer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnRightNewerFiles ), NULL, this );
m_bpButtonRightOnly->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnRightOnlyFiles ), NULL, this );
m_bpButtonSyncCreateLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncCreateLeft ), NULL, this );
- m_bpButtonSyncDirLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirLeft ), NULL, this );
+ m_bpButtonSyncDirOverwLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirLeft ), NULL, this );
m_bpButtonSyncDeleteLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDeleteLeft ), NULL, this );
m_bpButtonSyncDirNone->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirNone ), NULL, this );
m_bpButtonSyncDeleteRight->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDeleteRight ), NULL, this );
- m_bpButtonSyncDirRight->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirRight ), NULL, this );
+ m_bpButtonSyncDirOverwRight->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirRight ), NULL, this );
m_bpButtonSyncCreateRight->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncCreateRight ), NULL, this );
m_bpButtonConflict->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnConflictFiles ), NULL, this );
m_bpButton10->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnQuit ), NULL, this );
@@ -751,6 +746,7 @@ MainDialogGenerated::~MainDialogGenerated()
this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnCompare ) );
this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnStartSync ) );
this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnSwitchView ) );
+ this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnNewConfig ) );
this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnSaveConfig ) );
this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnLoadConfig ) );
this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuQuit ) );
@@ -767,7 +763,6 @@ MainDialogGenerated::~MainDialogGenerated()
m_dirPickerLeft->Disconnect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( MainDialogGenerated::OnDirSelected ), NULL, this );
m_bpButtonSwapSides->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSwapSides ), NULL, this );
m_bpButtonAddPair->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnAddFolderPair ), NULL, this );
- m_bpButtonRemoveTopPair->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnRemoveTopFolderPair ), NULL, this );
m_directoryRight->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( MainDialogGenerated::OnFolderHistoryKeyEvent ), NULL, this );
m_dirPickerRight->Disconnect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( MainDialogGenerated::OnDirSelected ), NULL, this );
m_gridLeft->Disconnect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( MainDialogGenerated::OnLeftGridDoubleClick ), NULL, this );
@@ -795,11 +790,11 @@ MainDialogGenerated::~MainDialogGenerated()
m_bpButtonRightNewer->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnRightNewerFiles ), NULL, this );
m_bpButtonRightOnly->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnRightOnlyFiles ), NULL, this );
m_bpButtonSyncCreateLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncCreateLeft ), NULL, this );
- m_bpButtonSyncDirLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirLeft ), NULL, this );
+ m_bpButtonSyncDirOverwLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirLeft ), NULL, this );
m_bpButtonSyncDeleteLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDeleteLeft ), NULL, this );
m_bpButtonSyncDirNone->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirNone ), NULL, this );
m_bpButtonSyncDeleteRight->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDeleteRight ), NULL, this );
- m_bpButtonSyncDirRight->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirRight ), NULL, this );
+ m_bpButtonSyncDirOverwRight->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncDirRight ), NULL, this );
m_bpButtonSyncCreateRight->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncCreateRight ), NULL, this );
m_bpButtonConflict->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnConflictFiles ), NULL, this );
m_bpButton10->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnQuit ), NULL, this );
@@ -837,20 +832,32 @@ FolderPairGenerated::FolderPairGenerated( wxWindow* parent, wxWindowID id, const
m_panel21->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) );
wxBoxSizer* bSizer96;
- bSizer96 = new wxBoxSizer( wxVERTICAL );
+ bSizer96 = new wxBoxSizer( wxHORIZONTAL );
+
+ bSizer96->Add( 0, 0, 1, wxEXPAND, 5 );
- bSizer96->Add( 0, 5, 0, 0, 5 );
+ m_bpButtonAltFilter = new wxBitmapButton( m_panel21, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW );
+ m_bpButtonAltFilter->SetToolTip( _("Select alternate filter settings") );
- m_bitmap23 = new wxStaticBitmap( m_panel21, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 44,17 ), 0 );
- m_bitmap23->SetToolTip( _("Folder pair") );
+ m_bpButtonAltFilter->SetToolTip( _("Select alternate filter settings") );
- bSizer96->Add( m_bitmap23, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 8 );
+ bSizer96->Add( m_bpButtonAltFilter, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 );
+
+ m_bpButtonAltSyncCfg = new wxBitmapButton( m_panel21, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW );
+ m_bpButtonAltSyncCfg->SetToolTip( _("Select alternate synchronization settings") );
+
+ m_bpButtonAltSyncCfg->SetToolTip( _("Select alternate synchronization settings") );
+
+ bSizer96->Add( m_bpButtonAltSyncCfg, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bSizer96->Add( 0, 0, 1, wxEXPAND, 5 );
m_panel21->SetSizer( bSizer96 );
m_panel21->Layout();
bSizer96->Fit( m_panel21 );
- bSizer95->Add( m_panel21, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT|wxEXPAND, 5 );
+ bSizer95->Add( m_panel21, 0, wxRIGHT|wxLEFT|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
m_panel20->SetSizer( bSizer95 );
m_panel20->Layout();
@@ -961,6 +968,13 @@ BatchFolderPairGenerated::BatchFolderPairGenerated( wxWindow* parent, wxWindowID
bSizer114->Add( m_dirPickerLeft, 0, wxALIGN_CENTER_VERTICAL, 5 );
+ m_bpButtonAltSyncCfg = new wxBitmapButton( m_panelLeft, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW );
+ m_bpButtonAltSyncCfg->SetToolTip( _("Select alternate synchronization settings") );
+
+ m_bpButtonAltSyncCfg->SetToolTip( _("Select alternate synchronization settings") );
+
+ bSizer114->Add( m_bpButtonAltSyncCfg, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
m_panelLeft->SetSizer( bSizer114 );
m_panelLeft->Layout();
bSizer114->Fit( m_panelLeft );
@@ -978,6 +992,13 @@ BatchFolderPairGenerated::BatchFolderPairGenerated( wxWindow* parent, wxWindowID
bSizer115->Add( m_dirPickerRight, 0, wxALIGN_CENTER_VERTICAL, 5 );
+ m_bpButtonAltFilter = new wxBitmapButton( m_panelRight, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW );
+ m_bpButtonAltFilter->SetToolTip( _("Select alternate filter settings") );
+
+ m_bpButtonAltFilter->SetToolTip( _("Select alternate filter settings") );
+
+ bSizer115->Add( m_bpButtonAltFilter, 0, wxALIGN_CENTER_VERTICAL, 5 );
+
m_panelRight->SetSizer( bSizer115 );
m_panelRight->Layout();
bSizer115->Fit( m_panelRight );
@@ -1089,13 +1110,6 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS
bSizer1361->Add( m_bpButtonAddPair, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 3 );
- m_bpButtonRemoveTopPair = new wxBitmapButton( m_panelMainPair, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 19,21 ), wxBU_AUTODRAW );
- m_bpButtonRemoveTopPair->SetToolTip( _("Remove folder pair") );
-
- m_bpButtonRemoveTopPair->SetToolTip( _("Remove folder pair") );
-
- bSizer1361->Add( m_bpButtonRemoveTopPair, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 );
-
bSizer147->Add( bSizer1361, 0, wxALIGN_CENTER_VERTICAL, 5 );
wxBoxSizer* bSizer143;
@@ -1183,11 +1197,10 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS
bSizer100->Add( 0, 10, 0, 0, 5 );
- wxBoxSizer* bSizer57;
- bSizer57 = new wxBoxSizer( wxVERTICAL );
-
- wxBoxSizer* bSizer156;
- bSizer156 = new wxBoxSizer( wxHORIZONTAL );
+ wxFlexGridSizer* fgSizer15;
+ fgSizer15 = new wxFlexGridSizer( 2, 2, 10, 10 );
+ fgSizer15->SetFlexibleDirection( wxBOTH );
+ fgSizer15->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
wxStaticBoxSizer* sbSizer6;
sbSizer6 = new wxStaticBoxSizer( new wxStaticBox( m_panelOverview, wxID_ANY, _("Compare by...") ), wxVERTICAL );
@@ -1203,10 +1216,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS
sbSizer6->Add( m_radioBtnContent, 0, wxTOP, 5 );
- bSizer156->Add( sbSizer6, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
-
-
- bSizer156->Add( 10, 10, 0, wxEXPAND, 5 );
+ fgSizer15->Add( sbSizer6, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
wxStaticBoxSizer* sbSizer24;
sbSizer24 = new wxStaticBoxSizer( new wxStaticBox( m_panelOverview, wxID_ANY, wxEmptyString ), wxVERTICAL );
@@ -1229,15 +1239,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS
sbSizer24->Add( 0, 0, 1, wxEXPAND, 5 );
- bSizer156->Add( sbSizer24, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
-
- bSizer57->Add( bSizer156, 0, 0, 5 );
-
-
- bSizer57->Add( 10, 10, 0, 0, 5 );
-
- wxBoxSizer* bSizer721;
- bSizer721 = new wxBoxSizer( wxHORIZONTAL );
+ fgSizer15->Add( sbSizer24, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
wxStaticBoxSizer* sbSizer25;
sbSizer25 = new wxStaticBoxSizer( new wxStaticBox( m_panelOverview, wxID_ANY, _("Error handling") ), wxHORIZONTAL );
@@ -1247,10 +1249,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS
m_choiceHandleError->SetSelection( 0 );
sbSizer25->Add( m_choiceHandleError, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
- bSizer721->Add( sbSizer25, 0, wxEXPAND, 5 );
-
-
- bSizer721->Add( 10, 10, 0, 0, 5 );
+ fgSizer15->Add( sbSizer25, 0, wxEXPAND, 5 );
wxStaticBoxSizer* sbSizer23;
sbSizer23 = new wxStaticBoxSizer( new wxStaticBox( m_panelOverview, wxID_ANY, _("Deletion handling") ), wxVERTICAL );
@@ -1277,11 +1276,9 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS
bSizer1151->Fit( m_panelCustomDeletionDir );
sbSizer23->Add( m_panelCustomDeletionDir, 0, 0, 5 );
- bSizer721->Add( sbSizer23, 0, wxEXPAND, 5 );
-
- bSizer57->Add( bSizer721, 0, 0, 5 );
+ fgSizer15->Add( sbSizer23, 0, wxEXPAND, 5 );
- bSizer100->Add( bSizer57, 0, 0, 5 );
+ bSizer100->Add( fgSizer15, 0, 0, 5 );
bSizer120->Add( bSizer100, 1, 0, 5 );
@@ -1317,7 +1314,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS
wxBoxSizer* bSizer122;
bSizer122 = new wxBoxSizer( wxHORIZONTAL );
- m_bitmapLeftOnly = new wxStaticBitmap( m_panelOverview, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 48,48 ), 0 );
+ m_bitmapLeftOnly = new wxStaticBitmap( m_panelOverview, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 45,45 ), 0 );
m_bitmapLeftOnly->SetToolTip( _("Files/folders that exist on left side only") );
bSizer122->Add( m_bitmapLeftOnly, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 );
@@ -1333,7 +1330,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS
wxBoxSizer* bSizer123;
bSizer123 = new wxBoxSizer( wxHORIZONTAL );
- m_bitmapRightOnly = new wxStaticBitmap( m_panelOverview, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 48,48 ), 0 );
+ m_bitmapRightOnly = new wxStaticBitmap( m_panelOverview, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 45,45 ), 0 );
m_bitmapRightOnly->SetToolTip( _("Files/folders that exist on right side only") );
bSizer123->Add( m_bitmapRightOnly, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 );
@@ -1349,7 +1346,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS
wxBoxSizer* bSizer124;
bSizer124 = new wxBoxSizer( wxHORIZONTAL );
- m_bitmapLeftNewer = new wxStaticBitmap( m_panelOverview, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 48,48 ), 0 );
+ m_bitmapLeftNewer = new wxStaticBitmap( m_panelOverview, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 45,45 ), 0 );
m_bitmapLeftNewer->SetToolTip( _("Files that exist on both sides, left one is newer") );
bSizer124->Add( m_bitmapLeftNewer, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 );
@@ -1365,7 +1362,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS
wxBoxSizer* bSizer125;
bSizer125 = new wxBoxSizer( wxHORIZONTAL );
- m_bitmapRightNewer = new wxStaticBitmap( m_panelOverview, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 48,48 ), 0 );
+ m_bitmapRightNewer = new wxStaticBitmap( m_panelOverview, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 45,45 ), 0 );
m_bitmapRightNewer->SetToolTip( _("Files that exist on both sides, right one is newer") );
bSizer125->Add( m_bitmapRightNewer, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 );
@@ -1381,7 +1378,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS
wxBoxSizer* bSizer126;
bSizer126 = new wxBoxSizer( wxHORIZONTAL );
- m_bitmapDifferent = new wxStaticBitmap( m_panelOverview, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 48,48 ), 0 );
+ m_bitmapDifferent = new wxStaticBitmap( m_panelOverview, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 45,45 ), 0 );
m_bitmapDifferent->SetToolTip( _("Files that exist on both sides and have different content") );
bSizer126->Add( m_bitmapDifferent, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 );
@@ -1394,6 +1391,22 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS
bSizer121->Add( bSizer126, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
+ wxBoxSizer* bSizer127;
+ bSizer127 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_bitmapConflict = new wxStaticBitmap( m_panelOverview, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 45,45 ), 0 );
+ m_bitmapConflict->SetToolTip( _("Conflicts/files that cannot be categorized") );
+
+ bSizer127->Add( m_bitmapConflict, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bSizer127->Add( 5, 0, 0, 0, 5 );
+
+ m_bpButtonConflict = new wxBitmapButton( m_panelOverview, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW );
+ bSizer127->Add( m_bpButtonConflict, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ bSizer121->Add( bSizer127, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
+
sbSizer61->Add( bSizer121, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
bSizer120->Add( sbSizer61, 0, wxALIGN_CENTER_VERTICAL, 5 );
@@ -1534,7 +1547,6 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS
// Connect Events
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( BatchDlgGenerated::OnClose ) );
m_bpButtonAddPair->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnAddFolderPair ), NULL, this );
- m_bpButtonRemoveTopPair->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnRemoveTopFolderPair ), NULL, this );
m_radioBtnSizeDate->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( BatchDlgGenerated::OnChangeCompareVar ), NULL, this );
m_radioBtnContent->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( BatchDlgGenerated::OnChangeCompareVar ), NULL, this );
m_checkBoxFilter->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnCheckFilter ), NULL, this );
@@ -1546,6 +1558,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS
m_bpButtonLeftNewer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnLeftNewer ), NULL, this );
m_bpButtonRightNewer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnRightNewer ), NULL, this );
m_bpButtonDifferent->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnDifferent ), NULL, this );
+ m_bpButtonConflict->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnConflict ), NULL, this );
m_buttonSave->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnSaveBatchJob ), NULL, this );
m_buttonLoad->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnLoadBatchJob ), NULL, this );
m_button6->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnCancel ), NULL, this );
@@ -1556,7 +1569,6 @@ BatchDlgGenerated::~BatchDlgGenerated()
// Disconnect Events
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( BatchDlgGenerated::OnClose ) );
m_bpButtonAddPair->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnAddFolderPair ), NULL, this );
- m_bpButtonRemoveTopPair->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnRemoveTopFolderPair ), NULL, this );
m_radioBtnSizeDate->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( BatchDlgGenerated::OnChangeCompareVar ), NULL, this );
m_radioBtnContent->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( BatchDlgGenerated::OnChangeCompareVar ), NULL, this );
m_checkBoxFilter->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnCheckFilter ), NULL, this );
@@ -1568,6 +1580,7 @@ BatchDlgGenerated::~BatchDlgGenerated()
m_bpButtonLeftNewer->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnLeftNewer ), NULL, this );
m_bpButtonRightNewer->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnRightNewer ), NULL, this );
m_bpButtonDifferent->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnDifferent ), NULL, this );
+ m_bpButtonConflict->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnConflict ), NULL, this );
m_buttonSave->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnSaveBatchJob ), NULL, this );
m_buttonLoad->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnLoadBatchJob ), NULL, this );
m_button6->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnCancel ), NULL, this );
@@ -1824,18 +1837,14 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const
bSizer201 = new wxBoxSizer( wxHORIZONTAL );
- wxStaticBoxSizer* sbSizer27;
- sbSizer27 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Error handling") ), wxHORIZONTAL );
+ sbSizerErrorHandling = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Error handling") ), wxHORIZONTAL );
wxArrayString m_choiceHandleErrorChoices;
m_choiceHandleError = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceHandleErrorChoices, 0 );
m_choiceHandleError->SetSelection( 0 );
- sbSizer27->Add( m_choiceHandleError, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
-
- bSizer201->Add( sbSizer27, 0, wxEXPAND, 5 );
-
+ sbSizerErrorHandling->Add( m_choiceHandleError, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
- bSizer201->Add( 10, 0, 0, 0, 5 );
+ bSizer201->Add( sbSizerErrorHandling, 0, wxEXPAND|wxRIGHT, 10 );
wxStaticBoxSizer* sbSizer231;
sbSizer231 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Deletion handling") ), wxVERTICAL );
@@ -1922,7 +1931,7 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const
wxBoxSizer* bSizer122;
bSizer122 = new wxBoxSizer( wxHORIZONTAL );
- m_bitmapLeftOnly = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 48,48 ), 0 );
+ m_bitmapLeftOnly = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 45,45 ), 0 );
m_bitmapLeftOnly->SetToolTip( _("Files/folders that exist on left side only") );
bSizer122->Add( m_bitmapLeftOnly, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 );
@@ -1938,7 +1947,7 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const
wxBoxSizer* bSizer123;
bSizer123 = new wxBoxSizer( wxHORIZONTAL );
- m_bitmapRightOnly = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 48,48 ), 0 );
+ m_bitmapRightOnly = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 45,45 ), 0 );
m_bitmapRightOnly->SetToolTip( _("Files/folders that exist on right side only") );
bSizer123->Add( m_bitmapRightOnly, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 );
@@ -1954,7 +1963,7 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const
wxBoxSizer* bSizer124;
bSizer124 = new wxBoxSizer( wxHORIZONTAL );
- m_bitmapLeftNewer = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 48,48 ), 0 );
+ m_bitmapLeftNewer = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 45,45 ), 0 );
m_bitmapLeftNewer->SetToolTip( _("Files that exist on both sides, left one is newer") );
bSizer124->Add( m_bitmapLeftNewer, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 );
@@ -1970,7 +1979,7 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const
wxBoxSizer* bSizer125;
bSizer125 = new wxBoxSizer( wxHORIZONTAL );
- m_bitmapRightNewer = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 48,48 ), 0 );
+ m_bitmapRightNewer = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 45,45 ), 0 );
m_bitmapRightNewer->SetToolTip( _("Files that exist on both sides, right one is newer") );
bSizer125->Add( m_bitmapRightNewer, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 );
@@ -1986,7 +1995,7 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const
wxBoxSizer* bSizer126;
bSizer126 = new wxBoxSizer( wxHORIZONTAL );
- m_bitmapDifferent = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 48,48 ), 0 );
+ m_bitmapDifferent = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 45,45 ), 0 );
m_bitmapDifferent->SetToolTip( _("Files that exist on both sides and have different content") );
bSizer126->Add( m_bitmapDifferent, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 );
@@ -1999,6 +2008,22 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const
bSizer121->Add( bSizer126, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
+ wxBoxSizer* bSizer127;
+ bSizer127 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_bitmapConflict = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 45,45 ), 0 );
+ m_bitmapConflict->SetToolTip( _("Conflicts/files that cannot be categorized") );
+
+ bSizer127->Add( m_bitmapConflict, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 );
+
+
+ bSizer127->Add( 5, 0, 0, 0, 5 );
+
+ m_bpButtonConflict = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW );
+ bSizer127->Add( m_bpButtonConflict, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 );
+
+ bSizer121->Add( bSizer127, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
+
sbSizer6->Add( bSizer121, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
bSizer181->Add( sbSizer6, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
@@ -2029,6 +2054,7 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const
m_bpButtonLeftNewer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnLeftNewer ), NULL, this );
m_bpButtonRightNewer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnRightNewer ), NULL, this );
m_bpButtonDifferent->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnDifferent ), NULL, this );
+ m_bpButtonConflict->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnConflict ), NULL, this );
}
SyncCfgDlgGenerated::~SyncCfgDlgGenerated()
@@ -2051,6 +2077,7 @@ SyncCfgDlgGenerated::~SyncCfgDlgGenerated()
m_bpButtonLeftNewer->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnLeftNewer ), NULL, this );
m_bpButtonRightNewer->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnRightNewer ), NULL, this );
m_bpButtonDifferent->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnDifferent ), NULL, this );
+ m_bpButtonConflict->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnConflict ), NULL, this );
}
CmpCfgDlgGenerated::CmpCfgDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
@@ -2451,9 +2478,6 @@ HelpDlgGenerated::HelpDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr
m_staticText80->Wrap( -1 );
bSizer70->Add( m_staticText80, 0, wxRIGHT|wxLEFT, 5 );
-
- bSizer70->Add( 0, 10, 0, 0, 5 );
-
m_staticText78 = new wxStaticText( m_scrolledWindow1, wxID_ANY, _("- conflict"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText78->Wrap( -1 );
bSizer70->Add( m_staticText78, 0, wxRIGHT|wxLEFT, 5 );
@@ -2914,7 +2938,7 @@ QuestionDlgGenerated::QuestionDlgGenerated( wxWindow* parent, wxWindowID id, con
bSizer24->Add( bSizer26, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxBOTTOM, 5 );
- m_checkBoxDontAskAgain = new wxCheckBox( this, wxID_ANY, _("Don't ask me again"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_checkBoxDontAskAgain = new wxCheckBox( this, wxID_ANY, _("Do not show this dialog again"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer24->Add( m_checkBoxDontAskAgain, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
@@ -3092,7 +3116,7 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w
wxBoxSizer* bSizer70;
bSizer70 = new wxBoxSizer( wxHORIZONTAL );
- m_staticText44 = new wxStaticText( this, wxID_ANY, _("Only files/directories that pass filtering will be selected for synchronization. The filter will be applied to the name relative(!) to the synchronization directories."), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText44 = new wxStaticText( this, wxID_ANY, _("Only files/directories that pass filtering will be selected for synchronization. The filter will be applied to the name relative(!) to the base synchronization directories."), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText44->Wrap( 400 );
bSizer70->Add( m_staticText44, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 );
@@ -3230,7 +3254,7 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w
bSizer22->Add( 0, 0, 1, wxEXPAND, 5 );
- m_button10 = new wxButton( this, wxID_OK, _("&OK"), wxDefaultPosition, wxSize( -1,30 ), 0 );
+ m_button10 = new wxButton( this, wxID_OK, _("&Apply"), wxDefaultPosition, wxSize( -1,30 ), 0 );
m_button10->SetDefault();
m_button10->SetFont( wxFont( 10, 74, 90, 92, false, wxT("Tahoma") ) );
@@ -3251,7 +3275,7 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( FilterDlgGenerated::OnClose ) );
m_bpButtonHelp->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FilterDlgGenerated::OnHelp ), NULL, this );
m_button9->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FilterDlgGenerated::OnDefault ), NULL, this );
- m_button10->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FilterDlgGenerated::OnOK ), NULL, this );
+ m_button10->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FilterDlgGenerated::OnApply ), NULL, this );
m_button17->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FilterDlgGenerated::OnCancel ), NULL, this );
}
@@ -3261,7 +3285,7 @@ FilterDlgGenerated::~FilterDlgGenerated()
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( FilterDlgGenerated::OnClose ) );
m_bpButtonHelp->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FilterDlgGenerated::OnHelp ), NULL, this );
m_button9->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FilterDlgGenerated::OnDefault ), NULL, this );
- m_button10->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FilterDlgGenerated::OnOK ), NULL, this );
+ m_button10->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FilterDlgGenerated::OnApply ), NULL, this );
m_button17->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FilterDlgGenerated::OnCancel ), NULL, this );
}
@@ -3360,7 +3384,10 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind
bSizer86 = new wxBoxSizer( wxHORIZONTAL );
m_bitmapSettings = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), 0 );
- bSizer86->Add( m_bitmapSettings, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
+ bSizer86->Add( m_bitmapSettings, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
+
+
+ bSizer86->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL, 5 );
m_panel8 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER|wxTAB_TRAVERSAL );
m_panel8->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT ) );
@@ -3379,9 +3406,6 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind
bSizer72->Fit( m_panel8 );
bSizer86->Add( m_panel8, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
-
- bSizer86->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL, 5 );
-
bSizer95->Add( bSizer86, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
@@ -3390,24 +3414,6 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind
wxStaticBoxSizer* sbSizer23;
sbSizer23 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxEmptyString ), wxVERTICAL );
- wxBoxSizer* bSizer100;
- bSizer100 = new wxBoxSizer( wxHORIZONTAL );
-
- m_staticText99 = new wxStaticText( this, wxID_ANY, _("File Time tolerance (seconds):"), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticText99->Wrap( -1 );
- m_staticText99->Hide();
- m_staticText99->SetToolTip( _("File times that differ by up to the specified number of seconds are still handled as having same time.") );
-
- bSizer100->Add( m_staticText99, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
-
- m_spinCtrlFileTimeTolerance = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_WRAP, 0, 2000000000, 0 );
- m_spinCtrlFileTimeTolerance->Hide();
- m_spinCtrlFileTimeTolerance->SetToolTip( _("File times that differ by up to the specified number of seconds are still handled as having same time.") );
-
- bSizer100->Add( m_spinCtrlFileTimeTolerance, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
-
- sbSizer23->Add( bSizer100, 1, wxEXPAND, 5 );
-
wxBoxSizer* bSizer120;
bSizer120 = new wxBoxSizer( wxHORIZONTAL );
@@ -3431,44 +3437,81 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind
m_staticline10 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
sbSizer23->Add( m_staticline10, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxTOP|wxBOTTOM, 5 );
- wxBoxSizer* bSizer104;
- bSizer104 = new wxBoxSizer( wxHORIZONTAL );
-
- m_staticTextCommand = new wxStaticText( this, wxID_ANY, _("File Manager integration:"), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticTextCommand->Wrap( -1 );
- bSizer104->Add( m_staticTextCommand, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
-
- m_textCtrlCommand = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 150,-1 ), 0 );
- bSizer104->Add( m_textCtrlCommand, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
-
- sbSizer23->Add( bSizer104, 1, wxEXPAND, 5 );
-
- m_staticline101 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
- sbSizer23->Add( m_staticline101, 0, wxEXPAND | wxALL, 5 );
-
wxBoxSizer* bSizer101;
bSizer101 = new wxBoxSizer( wxHORIZONTAL );
- m_staticText100 = new wxStaticText( this, wxID_ANY, _("Warnings:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText100 = new wxStaticText( this, wxID_ANY, _("Hidden dialogs:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText100->Wrap( -1 );
bSizer101->Add( m_staticText100, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
bSizer101->Add( 0, 0, 1, wxEXPAND, 5 );
- m_buttonResetWarnings = new wxButtonWithImage( this, wxID_ANY, _("Reset"), wxDefaultPosition, wxSize( 80,-1 ), 0 );
- m_buttonResetWarnings->SetFont( wxFont( 8, 74, 90, 92, false, wxT("Tahoma") ) );
- m_buttonResetWarnings->SetToolTip( _("Reset all warning messages") );
+ m_buttonResetDialogs = new wxButtonWithImage( this, wxID_ANY, _("Reset"), wxDefaultPosition, wxSize( 80,-1 ), 0 );
+ m_buttonResetDialogs->SetFont( wxFont( 8, 74, 90, 92, false, wxT("Tahoma") ) );
+ m_buttonResetDialogs->SetToolTip( _("Show hidden dialogs") );
- bSizer101->Add( m_buttonResetWarnings, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
+ bSizer101->Add( m_buttonResetDialogs, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
sbSizer23->Add( bSizer101, 1, wxEXPAND, 5 );
- bSizer95->Add( sbSizer23, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 5 );
+ bSizer95->Add( sbSizer23, 1, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT|wxEXPAND, 5 );
bSizer95->Add( 0, 10, 0, 0, 5 );
+ wxStaticBoxSizer* sbSizer26;
+ sbSizer26 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("External applications") ), wxHORIZONTAL );
+
+
+ sbSizer26->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ m_gridCustomCommand = new wxGrid( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+
+ // Grid
+ m_gridCustomCommand->CreateGrid( 5, 2 );
+ m_gridCustomCommand->EnableEditing( true );
+ m_gridCustomCommand->EnableGridLines( true );
+ m_gridCustomCommand->EnableDragGridSize( false );
+ m_gridCustomCommand->SetMargins( 0, 0 );
+
+ // Columns
+ m_gridCustomCommand->SetColSize( 0, 98 );
+ m_gridCustomCommand->SetColSize( 1, 179 );
+ m_gridCustomCommand->EnableDragColMove( false );
+ m_gridCustomCommand->EnableDragColSize( true );
+ m_gridCustomCommand->SetColLabelSize( 20 );
+ m_gridCustomCommand->SetColLabelValue( 0, _("Description") );
+ m_gridCustomCommand->SetColLabelValue( 1, _("Commandline") );
+ m_gridCustomCommand->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Rows
+ m_gridCustomCommand->EnableDragRowSize( false );
+ m_gridCustomCommand->SetRowLabelSize( 0 );
+ m_gridCustomCommand->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+
+ // Label Appearance
+
+ // Cell Defaults
+ m_gridCustomCommand->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+ sbSizer26->Add( m_gridCustomCommand, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 );
+
+ wxBoxSizer* bSizer157;
+ bSizer157 = new wxBoxSizer( wxVERTICAL );
+
+ m_bpButtonAddRow = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 19,21 ), wxBU_AUTODRAW );
+ bSizer157->Add( m_bpButtonAddRow, 0, 0, 5 );
+
+ m_bpButtonRemoveRow = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 19,21 ), wxBU_AUTODRAW );
+ bSizer157->Add( m_bpButtonRemoveRow, 0, 0, 5 );
+
+ sbSizer26->Add( bSizer157, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
+
+
+ sbSizer26->Add( 0, 0, 1, wxEXPAND, 5 );
+
+ bSizer95->Add( sbSizer26, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxRIGHT|wxLEFT, 5 );
+
wxBoxSizer* bSizer97;
bSizer97 = new wxBoxSizer( wxHORIZONTAL );
@@ -3496,7 +3539,9 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind
// Connect Events
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( GlobalSettingsDlgGenerated::OnClose ) );
- m_buttonResetWarnings->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnResetWarnings ), NULL, this );
+ m_buttonResetDialogs->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnResetDialogs ), NULL, this );
+ m_bpButtonAddRow->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnAddRow ), NULL, this );
+ m_bpButtonRemoveRow->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnRemoveRow ), NULL, this );
m_buttonOkay->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnOkay ), NULL, this );
m_button9->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnDefault ), NULL, this );
m_button29->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnCancel ), NULL, this );
@@ -3506,7 +3551,9 @@ GlobalSettingsDlgGenerated::~GlobalSettingsDlgGenerated()
{
// Disconnect Events
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( GlobalSettingsDlgGenerated::OnClose ) );
- m_buttonResetWarnings->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnResetWarnings ), NULL, this );
+ m_buttonResetDialogs->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnResetDialogs ), NULL, this );
+ m_bpButtonAddRow->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnAddRow ), NULL, this );
+ m_bpButtonRemoveRow->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnRemoveRow ), NULL, this );
m_buttonOkay->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnOkay ), NULL, this );
m_button9->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnDefault ), NULL, this );
m_button29->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnCancel ), NULL, this );
@@ -3725,7 +3772,7 @@ PopupFrameGenerated1::PopupFrameGenerated1( wxWindow* parent, wxWindowID id, con
bSizer158->Add( m_bitmapLeft, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_staticTextMain = new wxStaticText( this, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 );
- m_staticTextMain->Wrap( -1 );
+ m_staticTextMain->Wrap( 600 );
bSizer158->Add( m_staticTextMain, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 );
this->SetSizer( bSizer158 );
diff --git a/ui/guiGenerated.h b/ui/guiGenerated.h
index 79c07c47..5f4cc208 100644
--- a/ui/guiGenerated.h
+++ b/ui/guiGenerated.h
@@ -13,6 +13,7 @@
class CustomGridLeft;
class CustomGridMiddle;
class CustomGridRight;
+class ToggleButton;
class wxButtonWithImage;
#include <wx/string.h>
@@ -48,7 +49,6 @@ class wxButtonWithImage;
#include <wx/animate.h>
#include <wx/treectrl.h>
#include <wx/checklst.h>
-#include <wx/spinctrl.h>
///////////////////////////////////////////////////////////////////////////
@@ -66,6 +66,9 @@ class MainDialogGenerated : public wxFrame
wxMenuItem* m_menuItem10;
wxMenuItem* m_menuItem11;
wxMenuItem* m_menuItemSwitchView;
+ wxMenuItem* m_menuItemNew;
+ wxMenuItem* m_menuItemSave;
+ wxMenuItem* m_menuItemLoad;
wxMenu* m_menuAdvanced;
wxMenu* m_menuLanguages;
wxMenuItem* m_menuItemGlobSett;
@@ -97,7 +100,6 @@ class MainDialogGenerated : public wxFrame
wxBitmapButton* m_bpButtonSwapSides;
wxPanel* m_panelTopRight;
wxBitmapButton* m_bpButtonAddPair;
- wxBitmapButton* m_bpButtonRemoveTopPair;
wxComboBox* m_directoryRight;
wxDirPickerCtrl* m_dirPickerRight;
wxScrolledWindow* m_scrolledWindowFolderPairs;
@@ -120,20 +122,20 @@ class MainDialogGenerated : public wxFrame
wxCheckBox* m_checkBoxHideFilt;
wxPanel* m_panel112;
- wxBitmapButton* m_bpButtonLeftOnly;
- wxBitmapButton* m_bpButtonLeftNewer;
- wxBitmapButton* m_bpButtonEqual;
- wxBitmapButton* m_bpButtonDifferent;
- wxBitmapButton* m_bpButtonRightNewer;
- wxBitmapButton* m_bpButtonRightOnly;
- wxBitmapButton* m_bpButtonSyncCreateLeft;
- wxBitmapButton* m_bpButtonSyncDirLeft;
- wxBitmapButton* m_bpButtonSyncDeleteLeft;
- wxBitmapButton* m_bpButtonSyncDirNone;
- wxBitmapButton* m_bpButtonSyncDeleteRight;
- wxBitmapButton* m_bpButtonSyncDirRight;
- wxBitmapButton* m_bpButtonSyncCreateRight;
- wxBitmapButton* m_bpButtonConflict;
+ ToggleButton* m_bpButtonLeftOnly;
+ ToggleButton* m_bpButtonLeftNewer;
+ ToggleButton* m_bpButtonEqual;
+ ToggleButton* m_bpButtonDifferent;
+ ToggleButton* m_bpButtonRightNewer;
+ ToggleButton* m_bpButtonRightOnly;
+ ToggleButton* m_bpButtonSyncCreateLeft;
+ ToggleButton* m_bpButtonSyncDirOverwLeft;
+ ToggleButton* m_bpButtonSyncDeleteLeft;
+ ToggleButton* m_bpButtonSyncDirNone;
+ ToggleButton* m_bpButtonSyncDeleteRight;
+ ToggleButton* m_bpButtonSyncDirOverwRight;
+ ToggleButton* m_bpButtonSyncCreateRight;
+ ToggleButton* m_bpButtonConflict;
wxBoxSizer* bSizerBottomRight;
@@ -166,6 +168,7 @@ class MainDialogGenerated : public wxFrame
virtual void OnCompare( wxCommandEvent& event ){ event.Skip(); }
virtual void OnStartSync( wxCommandEvent& event ){ event.Skip(); }
virtual void OnSwitchView( wxCommandEvent& event ){ event.Skip(); }
+ virtual void OnNewConfig( wxCommandEvent& event ){ event.Skip(); }
virtual void OnSaveConfig( wxCommandEvent& event ){ event.Skip(); }
virtual void OnLoadConfig( wxCommandEvent& event ){ event.Skip(); }
virtual void OnMenuQuit( wxCommandEvent& event ){ event.Skip(); }
@@ -180,7 +183,6 @@ class MainDialogGenerated : public wxFrame
virtual void OnDirSelected( wxFileDirPickerEvent& event ){ event.Skip(); }
virtual void OnSwapSides( wxCommandEvent& event ){ event.Skip(); }
virtual void OnAddFolderPair( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnRemoveTopFolderPair( wxCommandEvent& event ){ event.Skip(); }
virtual void OnLeftGridDoubleClick( wxGridEvent& event ){ event.Skip(); }
virtual void OnContextRim( wxGridEvent& event ){ event.Skip(); }
virtual void OnSortLeftGrid( wxGridEvent& event ){ event.Skip(); }
@@ -228,14 +230,16 @@ class FolderPairGenerated : public wxPanel
protected:
wxPanel* m_panel20;
- wxPanel* m_panel21;
+
+ wxBitmapButton* m_bpButtonAltFilter;
+ wxBitmapButton* m_bpButtonAltSyncCfg;
public:
wxPanel* m_panelLeft;
wxTextCtrl* m_directoryLeft;
wxDirPickerCtrl* m_dirPickerLeft;
- wxStaticBitmap* m_bitmap23;
+ wxPanel* m_panel21;
wxPanel* m_panelRight;
wxBitmapButton* m_bpButtonRemovePair;
wxTextCtrl* m_directoryRight;
@@ -257,7 +261,9 @@ class BatchFolderPairGenerated : public wxPanel
wxStaticText* m_staticText53;
wxStaticText* m_staticText541;
wxPanel* m_panelLeft;
+ wxBitmapButton* m_bpButtonAltSyncCfg;
wxPanel* m_panelRight;
+ wxBitmapButton* m_bpButtonAltFilter;
public:
@@ -303,13 +309,10 @@ class BatchDlgGenerated : public wxDialog
wxRadioButton* m_radioBtnSizeDate;
wxRadioButton* m_radioBtnContent;
-
wxCheckBox* m_checkBoxFilter;
wxCheckBox* m_checkBoxSilent;
-
wxChoice* m_choiceHandleError;
-
wxChoice* m_choiceHandleDeletion;
wxPanel* m_panelCustomDeletionDir;
wxTextCtrl* m_textCtrlCustomDelFolder;
@@ -333,6 +336,9 @@ class BatchDlgGenerated : public wxDialog
wxStaticBitmap* m_bitmapDifferent;
wxBitmapButton* m_bpButtonDifferent;
+ wxStaticBitmap* m_bitmapConflict;
+
+ wxBitmapButton* m_bpButtonConflict;
wxPanel* m_panelFilter;
wxStaticText* m_staticText15;
@@ -353,7 +359,6 @@ class BatchDlgGenerated : public wxDialog
// Virtual event handlers, overide them in your derived class
virtual void OnClose( wxCloseEvent& event ){ event.Skip(); }
virtual void OnAddFolderPair( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnRemoveTopFolderPair( wxCommandEvent& event ){ event.Skip(); }
virtual void OnChangeCompareVar( wxCommandEvent& event ){ event.Skip(); }
virtual void OnCheckFilter( wxCommandEvent& event ){ event.Skip(); }
virtual void OnCheckLogging( wxCommandEvent& event ){ event.Skip(); }
@@ -364,6 +369,7 @@ class BatchDlgGenerated : public wxDialog
virtual void OnLeftNewer( wxCommandEvent& event ){ event.Skip(); }
virtual void OnRightNewer( wxCommandEvent& event ){ event.Skip(); }
virtual void OnDifferent( wxCommandEvent& event ){ event.Skip(); }
+ virtual void OnConflict( wxCommandEvent& event ){ event.Skip(); }
virtual void OnSaveBatchJob( wxCommandEvent& event ){ event.Skip(); }
virtual void OnLoadBatchJob( wxCommandEvent& event ){ event.Skip(); }
virtual void OnCancel( wxCommandEvent& event ){ event.Skip(); }
@@ -371,7 +377,6 @@ class BatchDlgGenerated : public wxDialog
public:
wxBitmapButton* m_bpButtonAddPair;
- wxBitmapButton* m_bpButtonRemoveTopPair;
wxTextCtrl* m_directoryLeft;
wxDirPickerCtrl* m_dirPickerLeft;
wxTextCtrl* m_directoryRight;
@@ -440,8 +445,8 @@ class SyncCfgDlgGenerated : public wxDialog
wxStaticText* m_staticText9;
wxBoxSizer* bSizer201;
+ wxStaticBoxSizer* sbSizerErrorHandling;
wxChoice* m_choiceHandleError;
-
wxChoice* m_choiceHandleDeletion;
wxPanel* m_panelCustomDeletionDir;
wxTextCtrl* m_textCtrlCustomDelFolder;
@@ -469,6 +474,9 @@ class SyncCfgDlgGenerated : public wxDialog
wxStaticBitmap* m_bitmapDifferent;
wxBitmapButton* m_bpButtonDifferent;
+ wxStaticBitmap* m_bitmapConflict;
+
+ wxBitmapButton* m_bpButtonConflict;
// Virtual event handlers, overide them in your derived class
virtual void OnClose( wxCloseEvent& event ){ event.Skip(); }
@@ -485,6 +493,7 @@ class SyncCfgDlgGenerated : public wxDialog
virtual void OnLeftNewer( wxCommandEvent& event ){ event.Skip(); }
virtual void OnRightNewer( wxCommandEvent& event ){ event.Skip(); }
virtual void OnDifferent( wxCommandEvent& event ){ event.Skip(); }
+ virtual void OnConflict( wxCommandEvent& event ){ event.Skip(); }
public:
@@ -605,7 +614,6 @@ class HelpDlgGenerated : public wxDialog
wxStaticText* m_staticText77;
wxStaticText* m_staticText79;
wxStaticText* m_staticText80;
-
wxStaticText* m_staticText78;
wxScrolledWindow* m_scrolledWindow5;
wxStaticText* m_staticText65;
@@ -850,7 +858,7 @@ class FilterDlgGenerated : public wxDialog
virtual void OnClose( wxCloseEvent& event ){ event.Skip(); }
virtual void OnHelp( wxCommandEvent& event ){ event.Skip(); }
virtual void OnDefault( wxCommandEvent& event ){ event.Skip(); }
- virtual void OnOK( wxCommandEvent& event ){ event.Skip(); }
+ virtual void OnApply( wxCommandEvent& event ){ event.Skip(); }
virtual void OnCancel( wxCommandEvent& event ){ event.Skip(); }
@@ -900,22 +908,22 @@ class GlobalSettingsDlgGenerated : public wxDialog
protected:
wxStaticBitmap* m_bitmapSettings;
+
wxPanel* m_panel8;
wxStaticText* m_staticText56;
-
- wxStaticText* m_staticText99;
- wxSpinCtrl* m_spinCtrlFileTimeTolerance;
wxStaticText* m_staticText114;
wxCheckBox* m_checkBoxIgnoreOneHour;
wxStaticLine* m_staticline10;
- wxStaticText* m_staticTextCommand;
- wxTextCtrl* m_textCtrlCommand;
- wxStaticLine* m_staticline101;
wxStaticText* m_staticText100;
- wxButtonWithImage* m_buttonResetWarnings;
+ wxButtonWithImage* m_buttonResetDialogs;
+
+
+ wxGrid* m_gridCustomCommand;
+ wxBitmapButton* m_bpButtonAddRow;
+ wxBitmapButton* m_bpButtonRemoveRow;
wxButton* m_buttonOkay;
wxButton* m_button9;
@@ -923,7 +931,9 @@ class GlobalSettingsDlgGenerated : public wxDialog
// Virtual event handlers, overide them in your derived class
virtual void OnClose( wxCloseEvent& event ){ event.Skip(); }
- virtual void OnResetWarnings( wxCommandEvent& event ){ event.Skip(); }
+ virtual void OnResetDialogs( wxCommandEvent& event ){ event.Skip(); }
+ virtual void OnAddRow( wxCommandEvent& event ){ event.Skip(); }
+ virtual void OnRemoveRow( wxCommandEvent& event ){ event.Skip(); }
virtual void OnOkay( wxCommandEvent& event ){ event.Skip(); }
virtual void OnDefault( wxCommandEvent& event ){ event.Skip(); }
virtual void OnCancel( wxCommandEvent& event ){ event.Skip(); }
diff --git a/ui/guiStatusHandler.cpp b/ui/guiStatusHandler.cpp
index 280328da..4e69b66e 100644
--- a/ui/guiStatusHandler.cpp
+++ b/ui/guiStatusHandler.cpp
@@ -1,8 +1,9 @@
#include "guiStatusHandler.h"
#include "smallDialogs.h"
-#include "../shared/globalFunctions.h"
+#include "../shared/systemConstants.h"
#include "mainDialog.h"
#include <wx/wupdlock.h>
+#include "../shared/globalFunctions.h"
CompareStatusHandler::CompareStatusHandler(MainDialog* dlg) :
@@ -30,9 +31,6 @@ CompareStatusHandler::CompareStatusHandler(MainDialog* dlg) :
CompareStatusHandler::~CompareStatusHandler()
{
- //ATTENTION: wxAPP->Yield() is called! at this point in time there is a mismatch between
- //gridDataView and currentGridData!! make sure gridDataView does NOT access currentGridData!!
-
updateUiNow(); //ui update before enabling buttons again: prevent strange behaviour of delayed button clicks
//reenable complete main dialog
@@ -225,19 +223,19 @@ SyncStatusHandler::~SyncStatusHandler()
//notify to syncStatusFrame that current process has ended
if (abortIsRequested())
{
- result+= wxString(_("Synchronization aborted!")) + wxT(" ") + _("You may try to synchronize remaining items again (WITHOUT having to re-compare)!");
+ result += wxString(_("Synchronization aborted!")) + wxT(" ") + _("You may try to synchronize remaining items again (WITHOUT having to re-compare)!");
syncStatusFrame->setStatusText_NoUpdate(result.c_str());
syncStatusFrame->processHasFinished(SyncStatus::ABORTED); //enable okay and close events
}
else if (errorLog.errorsTotal() > 0)
{
- result+= wxString(_("Synchronization completed with errors!")) + wxT(" ") + _("You may try to synchronize remaining items again (WITHOUT having to re-compare)!");
+ result += wxString(_("Synchronization completed with errors!")) + wxT(" ") + _("You may try to synchronize remaining items again (WITHOUT having to re-compare)!");
syncStatusFrame->setStatusText_NoUpdate(result.c_str());
syncStatusFrame->processHasFinished(SyncStatus::FINISHED_WITH_ERROR);
}
else
{
- result+= _("Synchronization completed successfully!");
+ result += _("Synchronization completed successfully!");
syncStatusFrame->setStatusText_NoUpdate(result.c_str());
syncStatusFrame->processHasFinished(SyncStatus::FINISHED_WITH_SUCCESS);
}
diff --git a/ui/sorting.h b/ui/sorting.h
index c3cf8f97..33a6404f 100644
--- a/ui/sorting.h
+++ b/ui/sorting.h
@@ -1,282 +1,169 @@
#ifndef SORTING_H_INCLUDED
#define SORTING_H_INCLUDED
-#include "../structures.h"
-#include "../shared/globalFunctions.h"
+#include "../fileHierarchy.h"
+#include "../shared/systemConstants.h"
+#include "../synchronization.h"
namespace FreeFileSync
{
- enum SideToSort
- {
- SORT_ON_LEFT,
- SORT_ON_RIGHT,
- };
-
-
inline
- bool stringSmallerThan(const DefaultChar* stringA, const DefaultChar* stringB)
+ int compareString(const Zstring& stringA, const Zstring& stringB)
{
-#ifdef FFS_WIN
- //case-insensitive comparison!
- return FreeFileSync::compareStringsWin32(stringA, stringB) < 0; //way faster than wxString::CmpNoCase() in windows build!!!
-#else
- return defaultCompare(stringA, stringB) < 0;
+#ifdef FFS_WIN //Windows does NOT distinguish between upper/lower-case
+ return stringA.CmpNoCase(stringB);
+#elif defined FFS_LINUX //Linux DOES distinguish between upper/lower-case
+ return stringA.Cmp(stringB);
#endif
}
inline
- int compareString(const wxChar* stringA, const wxChar* stringB, const int lengthA, const int lengthB)
+ bool stringSmallerThan(const Zstring& stringA, const Zstring& stringB)
{
-#ifdef FFS_WIN
- //case-insensitive comparison!
- return FreeFileSync::compareStringsWin32(stringA, stringB, lengthA, lengthB); //way faster than wxString::CmpNoCase() in the windows build!!!
-#else
- for (int i = 0; i < std::min(lengthA, lengthB); ++i)
- {
- if (stringA[i] != stringB[i])
- return stringA[i] - stringB[i];
- }
- return lengthA - lengthB;
-
- //equivalent:
- //const int rv = strncmp(stringA, stringB, std::min(lengthA, lengthB));
- //return rv != 0 ? rv : lengthA - lengthB;
-#endif
+ return compareString(stringA, stringB) < 0;
}
- template <SideToSort side>
+ template <bool ascending, SelectedSide side>
inline
- bool sortByFileName(const FileCompareLine& a, const FileCompareLine& b)
+ bool sortByFileName(const FileSystemObject& a, const FileSystemObject& b)
{
- const FileDescrLine* const descrLineA = side == SORT_ON_LEFT ? &a.fileDescrLeft : &a.fileDescrRight;
- const FileDescrLine* const descrLineB = side == SORT_ON_LEFT ? &b.fileDescrLeft : &b.fileDescrRight;
-
//presort types: first files, then directories then empty rows
- if (descrLineA->objType == FileDescrLine::TYPE_NOTHING)
+ if (a.isEmpty<side>())
return false; //empty rows always last
- else if (descrLineB->objType == FileDescrLine::TYPE_NOTHING)
+ else if (b.isEmpty<side>())
return true; //empty rows always last
- if (descrLineA->objType == FileDescrLine::TYPE_DIRECTORY) //sort directories by relative name
+ if (dynamic_cast<const DirMapping*>(&a)) //sort directories by relative name
{
- if (descrLineB->objType == FileDescrLine::TYPE_DIRECTORY)
- return stringSmallerThan(descrLineA->relativeName.c_str(), descrLineB->relativeName.c_str());
+ if (dynamic_cast<const DirMapping*>(&b))
+ return stringSmallerThan(a.getRelativeName<side>(), b.getRelativeName<side>());
else
return false;
}
else
{
- if (descrLineB->objType == FileDescrLine::TYPE_DIRECTORY)
+ if (dynamic_cast<const DirMapping*>(&b))
return true;
else
{
- const wxChar* stringA = descrLineA->relativeName.c_str();
- const wxChar* stringB = descrLineB->relativeName.c_str();
-
- size_t pos = descrLineA->relativeName.findFromEnd(globalFunctions::FILE_NAME_SEPARATOR); //start search beginning from end
- if (pos != std::string::npos)
- stringA += pos + 1;
-
- pos = descrLineB->relativeName.findFromEnd(globalFunctions::FILE_NAME_SEPARATOR); //start search beginning from end
- if (pos != std::string::npos)
- stringB += pos + 1;
-
- return stringSmallerThan(stringA, stringB);
+ return ascending ?
+ stringSmallerThan(a.getShortName<side>(), b.getShortName<side>()) :
+ stringSmallerThan(b.getShortName<side>(), a.getShortName<side>());
}
}
}
- template <SideToSort side>
- bool sortByRelativeName(const FileCompareLine& a, const FileCompareLine& b)
+ template <bool ascending, SelectedSide side>
+ bool sortByRelativeName(const FileSystemObject& a, const FileSystemObject& b)
{
- const FileDescrLine* const descrLineA = side == SORT_ON_LEFT ? &a.fileDescrLeft : &a.fileDescrRight;
- const FileDescrLine* const descrLineB = side == SORT_ON_LEFT ? &b.fileDescrLeft : &b.fileDescrRight;
-
- //extract relative name and filename
- const wxChar* const relStringA = descrLineA->relativeName.c_str(); //mustn't be NULL for CompareString() API to work correctly
- const wxChar* fileStringA = relStringA;
- int relLengthA = 0;
- int fileLengthA = 0;
-
- if (descrLineA->objType == FileDescrLine::TYPE_DIRECTORY)
- relLengthA = descrLineA->relativeName.length();
- else if (descrLineA->objType == FileDescrLine::TYPE_FILE)
- {
- relLengthA = descrLineA->relativeName.findFromEnd(globalFunctions::FILE_NAME_SEPARATOR); //start search beginning from end
- if (relLengthA == wxNOT_FOUND)
- {
- relLengthA = 0;
- fileLengthA = descrLineA->relativeName.length();
- }
- else
- {
- fileStringA += relLengthA + 1;
- fileLengthA = descrLineA->relativeName.length() - (relLengthA + 1);
- }
- }
- else
- return false; //empty rows should be on end of list
+ if (a.isEmpty<side>())
+ return false; //empty rows always last
+ else if (b.isEmpty<side>())
+ return true; //empty rows always last
- const wxChar* const relStringB = descrLineB->relativeName.c_str(); //mustn't be NULL for CompareString() API to work correctly
- const wxChar* fileStringB = relStringB;
- int relLengthB = 0;
- int fileLengthB = 0;
+ const FileMapping* fileObjA = dynamic_cast<const FileMapping*>(&a);
+ const Zstring relDirNameA = fileObjA != NULL ?
+ a.getParentRelativeName<side>() : //file
+ a.getRelativeName<side>(); //directory
- if (descrLineB->objType == FileDescrLine::TYPE_DIRECTORY)
- relLengthB = descrLineB->relativeName.length();
- else if (descrLineB->objType == FileDescrLine::TYPE_FILE)
- {
- relLengthB = descrLineB->relativeName.findFromEnd(globalFunctions::FILE_NAME_SEPARATOR); //start search beginning from end
- if (relLengthB == wxNOT_FOUND)
- {
- relLengthB = 0;
- fileLengthB = descrLineB->relativeName.length();
- }
- else
- {
- fileStringB += relLengthB + 1;
- fileLengthB = descrLineB->relativeName.length() - (relLengthB + 1);
- }
- }
- else
- return true; //empty rows should be on end of list
+ const FileMapping* fileObjB = dynamic_cast<const FileMapping*>(&b);
+ const Zstring relDirNameB = fileObjB != NULL ?
+ b.getParentRelativeName<side>() : //file
+ b.getRelativeName<side>(); //directory
//compare relative names without filenames first
- const int rv = compareString(relStringA, relStringB, relLengthA, relLengthB);
+ const int rv = compareString(relDirNameA, relDirNameB);
if (rv != 0)
- return rv < 0;
+ return ascending ? rv < 0 : rv > 0;
else //compare the filenames
{
- if (descrLineB->objType == FileDescrLine::TYPE_DIRECTORY) //directories shall appear before files
+ if (fileObjB == NULL) //directories shall appear before files
return false;
- else if (descrLineA->objType == FileDescrLine::TYPE_DIRECTORY)
+ else if (fileObjA == NULL)
return true;
- return compareString(fileStringA, fileStringB, fileLengthA, fileLengthB) < 0;
+ return stringSmallerThan(a.getShortName<side>(), b.getShortName<side>());
}
}
- template <SideToSort side>
+ template <bool ascending, SelectedSide side>
inline
- bool sortByFullName(const FileCompareLine& a, const FileCompareLine& b)
+ bool sortByFileSize(const FileSystemObject& a, const FileSystemObject& b)
{
- const FileDescrLine* const descrLineA = side == SORT_ON_LEFT ? &a.fileDescrLeft : &a.fileDescrRight;
- const FileDescrLine* const descrLineB = side == SORT_ON_LEFT ? &b.fileDescrLeft : &b.fileDescrRight;
-
- //presort types: first files, then directories then empty rows
- if (descrLineA->objType == FileDescrLine::TYPE_NOTHING)
+ if (a.isEmpty<side>())
return false; //empty rows always last
- else if (descrLineB->objType == FileDescrLine::TYPE_NOTHING)
+ else if (b.isEmpty<side>())
return true; //empty rows always last
- else
-#ifdef FFS_WIN //case-insensitive comparison!
- return FreeFileSync::compareStringsWin32(descrLineA->fullName.c_str(), descrLineB->fullName.c_str()) < 0; //way faster than wxString::CmpNoCase() in windows build!!!
-#else
- return descrLineA->fullName.Cmp(descrLineB->fullName) < 0;
-#endif
- }
-
- template <SideToSort side>
- inline
- bool sortByFileSize(const FileCompareLine& a, const FileCompareLine& b)
- {
- const FileDescrLine* const descrLineA = side == SORT_ON_LEFT ? &a.fileDescrLeft : &a.fileDescrRight;
- const FileDescrLine* const descrLineB = side == SORT_ON_LEFT ? &b.fileDescrLeft : &b.fileDescrRight;
- //presort types: first files, then directories then empty rows
- if (descrLineA->objType == FileDescrLine::TYPE_NOTHING)
- return false; //empty rows always last
- else if (descrLineB->objType == FileDescrLine::TYPE_NOTHING)
- return true; //empty rows always last
+ const FileMapping* fileObjA = dynamic_cast<const FileMapping*>(&a);
+ const FileMapping* fileObjB = dynamic_cast<const FileMapping*>(&b);
+ if (fileObjA == NULL)
+ return false; //directories last
+ else if (fileObjB == NULL)
+ return true; //directories last
- if (descrLineA->objType == FileDescrLine::TYPE_DIRECTORY) //sort directories by relative name
- {
- if (descrLineB->objType == FileDescrLine::TYPE_DIRECTORY)
- return stringSmallerThan(descrLineA->relativeName.c_str(), descrLineB->relativeName.c_str());
- else
- return false;
- }
- else
- {
- if (descrLineB->objType == FileDescrLine::TYPE_DIRECTORY)
- return true;
- else
- return descrLineA->fileSize > descrLineB->fileSize; //sortAscending shall result in list beginning with largest files first
- }
+ return ascending ?
+ fileObjA->getFileSize<side>() > fileObjB->getFileSize<side>() : //sortAscending shall result in list beginning with largest files first
+ fileObjA->getFileSize<side>() < fileObjB->getFileSize<side>();
}
- template <SideToSort side>
+ template <bool ascending, SelectedSide side>
inline
- bool sortByDate(const FileCompareLine& a, const FileCompareLine& b)
+ bool sortByDate(const FileSystemObject& a, const FileSystemObject& b)
{
- const FileDescrLine* const descrLineA = side == SORT_ON_LEFT ? &a.fileDescrLeft : &a.fileDescrRight;
- const FileDescrLine* const descrLineB = side == SORT_ON_LEFT ? &b.fileDescrLeft : &b.fileDescrRight;
-
- //presort types: first files, then directories then empty rows
- if (descrLineA->objType == FileDescrLine::TYPE_NOTHING)
+ if (a.isEmpty<side>())
return false; //empty rows always last
- else if (descrLineB->objType == FileDescrLine::TYPE_NOTHING)
+ else if (b.isEmpty<side>())
return true; //empty rows always last
- if (descrLineA->objType == FileDescrLine::TYPE_DIRECTORY) //sort directories by relative name
- {
- if (descrLineB->objType == FileDescrLine::TYPE_DIRECTORY)
- return stringSmallerThan(descrLineA->relativeName.c_str(), descrLineB->relativeName.c_str());
- else
- return false;
- }
- else
- {
- if (descrLineB->objType == FileDescrLine::TYPE_DIRECTORY)
- return true;
- else
- return descrLineA->lastWriteTimeRaw > descrLineB->lastWriteTimeRaw;
- }
+
+ const FileMapping* fileObjA = dynamic_cast<const FileMapping*>(&a);
+ const FileMapping* fileObjB = dynamic_cast<const FileMapping*>(&b);
+
+ if (fileObjA == NULL)
+ return false; //directories last
+ else if (fileObjB == NULL)
+ return true; //directories last
+
+ return ascending ?
+ fileObjA->getLastWriteTime<side>() > fileObjB->getLastWriteTime<side>() :
+ fileObjA->getLastWriteTime<side>() < fileObjB->getLastWriteTime<side>();
}
+ template <bool ascending>
inline
- bool sortByCmpResult(const FileCompareLine& a, const FileCompareLine& b)
+ bool sortByCmpResult(const FileSystemObject& a, const FileSystemObject& b)
{
//presort result: equal shall appear at end of list
- if (a.cmpResult == FILE_EQUAL)
+ if (a.getCategory() == FILE_EQUAL)
return false;
- if (b.cmpResult == FILE_EQUAL)
+ if (b.getCategory() == FILE_EQUAL)
return true;
- return a.cmpResult < b.cmpResult;
- }
-
-
- inline
- bool sortBySyncDirection(const FileCompareLine& a, const FileCompareLine& b)
- {
- return a.syncDir < b.syncDir;
+ return ascending ?
+ a.getCategory() < b.getCategory() :
+ a.getCategory() > b.getCategory();
}
- template <SideToSort side>
+ template <bool ascending>
inline
- bool sortByDirectory(const FolderCompareLine& a, const FolderCompareLine& b)
+ bool sortBySyncDirection(const FileSystemObject& a, const FileSystemObject& b)
{
- const Zstring& dirNameA = side == SORT_ON_LEFT ? a.syncPair.leftDirectory : a.syncPair.rightDirectory;
- const Zstring& dirNameB = side == SORT_ON_LEFT ? b.syncPair.leftDirectory : b.syncPair.rightDirectory;
-
-#ifdef FFS_WIN //case-insensitive comparison!
- return FreeFileSync::compareStringsWin32(dirNameA.c_str(), dirNameB.c_str()) < 0; //way faster than wxString::CmpNoCase() in windows build!!!
-#elif defined FFS_LINUX
- return dirNameA.Cmp(dirNameB) < 0;
-#endif
+ return ascending ?
+ getSyncOperation(a) < getSyncOperation(b) :
+ getSyncOperation(a) > getSyncOperation(b);
}
}
bgstack15