From fd0853d2623dd278b08288331ed42e3be59252fb Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Fri, 18 Apr 2014 17:00:17 +0200 Subject: 2.2 --- ui/MainDialog.cpp | 1293 ++++++++++++++++++++++++++------------------- ui/MainDialog.h | 76 ++- ui/SmallDialogs.cpp | 335 +++++++----- ui/SmallDialogs.h | 43 +- ui/SyncDialog.cpp | 672 ++++++++++++++++------- ui/SyncDialog.h | 81 ++- ui/batchStatusHandler.cpp | 384 ++++++++------ ui/batchStatusHandler.h | 31 +- ui/checkVersion.cpp | 23 +- ui/gridView.cpp | 134 +++-- ui/gridView.h | 13 +- ui/guiGenerated.cpp | 1021 +++++++++++++++++++++++------------ ui/guiGenerated.h | 183 +++++-- ui/guiStatusHandler.cpp | 230 +++----- ui/guiStatusHandler.h | 22 +- ui/sorting.h | 108 ++-- 16 files changed, 2881 insertions(+), 1768 deletions(-) (limited to 'ui') diff --git a/ui/MainDialog.cpp b/ui/MainDialog.cpp index e9119fea..5f078cda 100644 --- a/ui/MainDialog.cpp +++ b/ui/MainDialog.cpp @@ -1,12 +1,11 @@ #include "mainDialog.h" #include -#include "../library/globalFunctions.h" +#include "../shared/globalFunctions.h" #include #include #include #include "../library/customGrid.h" -#include "../library/customButton.h" -#include +#include "../shared/customButton.h" #include #include "../comparison.h" #include "../synchronization.h" @@ -14,14 +13,21 @@ #include "checkVersion.h" #include "guiStatusHandler.h" #include "syncDialog.h" -#include "../library/localization.h" +#include "../shared/localization.h" #include "smallDialogs.h" -#include "dragAndDrop.h" +#include "../shared/dragAndDrop.h" #include "../library/filter.h" #include "../structures.h" #include +#include +#include "gridView.h" +#include "../library/resources.h" +#include "../shared/fileHandling.h" +#include "../shared/xmlBase.h" +#include "../shared/standardPaths.h" using namespace FreeFileSync; +using FreeFileSync::CustomLocale; class FolderPairPanel : public FolderPairGenerated @@ -71,7 +77,7 @@ public: } //disable the sync button - mainDlg_->syncPreview->enableSynchronization(false); + mainDlg_->syncPreview.enableSynchronization(false); //clear grids mainDlg_->currentGridData.clear(); @@ -127,40 +133,43 @@ private: //################################################################################################################################## -MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, CustomLocale* language, xmlAccess::XmlGlobalSettings& settings) : +MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, xmlAccess::XmlGlobalSettings& settings) : MainDialogGenerated(frame), globalSettings(settings), - gridDataView(currentGridData), contextMenu(new wxMenu), //initialize right-click context menu; will be dynamically re-created on each R-mouse-click - programLanguage(language), - cmpStatusHandlerTmp(0), cleanedUp(false), lastSortColumn(-1), lastSortGrid(NULL), #ifdef FFS_WIN updateFileIcons(new IconUpdater(m_gridLeft, m_gridRight)), #endif - syncPreview(new SyncPreview(this)) + syncPreview(this) { - m_bpButtonRemoveTopPair->Hide(); + wxWindowUpdateLocker dummy(this); //avoid display distortion + + gridDataView.reset(new FreeFileSync::GridView(currentGridData)); + m_bpButtonRemoveTopPair->Hide(); //initialize and load configuration readGlobalSettings(); - readConfigurationFromXml(cfgFileName, true); + + if (cfgFileName.empty()) + readConfigurationFromXml(lastConfigFileName(), true); + else + readConfigurationFromXml(cfgFileName, true); //set icons for this dialog m_bpButton10->SetBitmapLabel(*GlobalResources::getInstance().bitmapExit); m_bpButtonSwapSides->SetBitmapLabel(*GlobalResources::getInstance().bitmapSwap); m_buttonCompare->setBitmapFront(*GlobalResources::getInstance().bitmapCompare); m_bpButtonSyncConfig->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncCfg); - m_bpButton14->SetBitmapLabel(*GlobalResources::getInstance().bitmapHelp); + m_bpButtonCmpConfig->SetBitmapLabel(*GlobalResources::getInstance().bitmapCmpCfg); 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_bitmapShift->SetBitmap(*GlobalResources::getInstance().bitmapShift); m_bitmapCreate->SetBitmap(*GlobalResources::getInstance().bitmapCreate); m_bitmapUpdate->SetBitmap(*GlobalResources::getInstance().bitmapUpdate); @@ -186,7 +195,8 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, CustomLocale for (std::vector::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(*i->languageFlag); + + newItem->SetBitmap(GlobalResources::getInstance().getImageByName(i->languageFlag)); //map menu item IDs with language IDs: evaluated when processing event handler languageMenuItemMap.insert(std::map::value_type(newItem->GetId(), i->languageID)); @@ -219,20 +229,23 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, CustomLocale m_gridMiddle->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainDialog::onGridMiddleButtonEvent), NULL, this); Connect(wxEVT_IDLE, wxEventHandler(MainDialog::OnIdleEvent), NULL, this); - Connect(wxEVT_SIZE, wxEventHandler(MainDialog::onResizeMainWindow), NULL, this); - Connect(wxEVT_MOVE, wxEventHandler(MainDialog::onResizeMainWindow), NULL, this); + Connect(wxEVT_SIZE, wxSizeEventHandler(MainDialog::OnResize), NULL, this); + Connect(wxEVT_MOVE, wxSizeEventHandler(MainDialog::OnResize), NULL, this); + + //calculate witdh of folder pair manually (if scrollbars are visible) + m_scrolledWindowFolderPairs->Connect(wxEVT_SIZE, wxSizeEventHandler(MainDialog::OnResizeFolderPairs), NULL, this); //event handler for manual (un-)checking of rows and setting of sync direction m_gridMiddle->Connect(FFS_CHECK_ROWS_EVENT, FFSCheckRowsEventHandler(MainDialog::OnCheckRows), NULL, this); m_gridMiddle->Connect(FFS_SYNC_DIRECTION_EVENT, FFSSyncDirectionEventHandler(MainDialog::OnSetSyncDirection), NULL, this); //init grid settings - m_gridLeft ->initSettings(m_gridLeft, m_gridMiddle, m_gridRight, &gridDataView); - m_gridMiddle->initSettings(m_gridLeft, m_gridMiddle, m_gridRight, &gridDataView); - m_gridRight ->initSettings(m_gridLeft, m_gridMiddle, m_gridRight, &gridDataView); + m_gridLeft ->initSettings(m_gridLeft, m_gridMiddle, m_gridRight, gridDataView.get()); + m_gridMiddle->initSettings(m_gridLeft, m_gridMiddle, m_gridRight, gridDataView.get()); + m_gridRight ->initSettings(m_gridLeft, m_gridMiddle, m_gridRight, gridDataView.get()); //disable sync button as long as "compare" hasn't been triggered. - syncPreview->enableSynchronization(false); + syncPreview.enableSynchronization(false); //mainly to update row label sizes... updateGuiGrid(); @@ -270,10 +283,10 @@ void MainDialog::cleanUp() { cleanedUp = true; - //no need for event Disconnect() here; done automatically + //no need for wxEventHandler::Disconnect() here; done automatically when window is destoyed! //save configuration - writeConfigurationToXml(FreeFileSync::getLastConfigFile()); //don't trow exceptions in destructors + writeConfigurationToXml(lastConfigFileName()); //don't trow exceptions in destructors writeGlobalSettings(); } } @@ -365,8 +378,8 @@ void MainDialog::setSyncDirManually(const std::set& rowsToSetOnUiTable, con { for (std::set::const_iterator i = rowsToSetOnUiTable.begin(); i != rowsToSetOnUiTable.end(); ++i) { - gridDataView[*i].direction = dir; - gridDataView[*i].selectedForSynchronization = true; + (*gridDataView)[*i].syncDir = dir; + (*gridDataView)[*i].selectedForSynchronization = true; } updateGuiGrid(); @@ -381,15 +394,15 @@ void MainDialog::filterRangeManually(const std::set& rowsToFilterOnUiTable, 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; + if (0 <= leadingRow && leadingRow < int(gridDataView->elementsOnView())) + newSelection = !(*gridDataView)[leadingRow].selectedForSynchronization; //if hidefiltered is active, there should be no filtered elements on screen => current element was filtered out - assert(!hideFilteredElements || !newSelection); + 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); + gridDataView->viewRefToFolderRef(rowsToFilterOnUiTable, compRef); assert(compRef.size() == currentGridData.size()); //GridView::viewRefToFolderRef() should ensure this! @@ -399,15 +412,15 @@ void MainDialog::filterRangeManually(const std::set& rowsToFilterOnUiTable, const std::set& markedRows = compRef[i - currentGridData.begin()]; std::set markedRowsTotal; //retrieve additional rows that need to be filtered, too - for (std::set::const_iterator i = markedRows.begin(); i != markedRows.end(); ++i) + for (std::set::const_iterator j = markedRows.begin(); j != markedRows.end(); ++j) { - markedRowsTotal.insert(*i); - FreeFileSync::addSubElements(fileCmp, fileCmp[*i], markedRowsTotal); + markedRowsTotal.insert(*j); + FreeFileSync::addSubElements(fileCmp, fileCmp[*j], markedRowsTotal); } //toggle selection of filtered rows - for (std::set::iterator i = markedRowsTotal.begin(); i != markedRowsTotal.end(); ++i) - fileCmp[*i].selectedForSynchronization = newSelection; + for (std::set::iterator k = markedRowsTotal.begin(); k != markedRowsTotal.end(); ++k) + fileCmp[*k].selectedForSynchronization = newSelection; } refreshGridAfterFilterChange(400); //call this instead of updateGuiGrid() to add some delay if hideFiltered == true and to handle some graphical artifacts @@ -484,7 +497,7 @@ std::set MainDialog::getSelectedRows(const CustomGrid* grid) const { std::set output = grid->getAllSelectedRows(); - removeInvalidRows(output, gridDataView.elementsOnView()); + removeInvalidRows(output, gridDataView->elementsOnView()); return output; } @@ -502,42 +515,92 @@ std::set MainDialog::getSelectedRows() const } -class DeleteErrorHandler : public ErrorHandler +class ManualDeletionHandler : private wxEvtHandler, public DeleteFilesHandler { public: - DeleteErrorHandler() : - ignoreErrors(false) {} + ManualDeletionHandler(MainDialog* main, int totalObjToDel) : + mainDlg(main), + totalObjToDelete(totalObjToDel), + abortRequested(false), + ignoreErrors(false), + deletionCount(0) + { + mainDlg->disableAllElements(); //disable everything except abort button + mainDlg->clearStatusBar(); + + //register abort button + mainDlg->m_buttonAbort->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ManualDeletionHandler::OnAbortCompare ), NULL, this ); + } - ~DeleteErrorHandler() {} + ~ManualDeletionHandler() + { + //de-register abort button + mainDlg->m_buttonAbort->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ManualDeletionHandler::OnAbortCompare ), NULL, this ); - Response reportError(const Zstring& errorMessage) + mainDlg->enableAllElements(); + } + + virtual Response reportError(const wxString& errorMessage) { + if (abortRequested) + throw FreeFileSync::AbortThisProcess(); + if (ignoreErrors) - return ErrorHandler::IGNORE_ERROR; + return DeleteFilesHandler::IGNORE_ERROR; bool ignoreNextErrors = false; ErrorDlg* errorDlg = new ErrorDlg(NULL, ErrorDlg::BUTTON_IGNORE | ErrorDlg::BUTTON_RETRY | ErrorDlg::BUTTON_ABORT, - errorMessage.c_str(), ignoreNextErrors); - int rv = errorDlg->ShowModal(); + errorMessage, ignoreNextErrors); + const int rv = errorDlg->ShowModal(); errorDlg->Destroy(); - switch (rv) + switch (static_cast(rv)) { case ErrorDlg::BUTTON_IGNORE: ignoreErrors = ignoreNextErrors; - return ErrorHandler::IGNORE_ERROR; + return DeleteFilesHandler::IGNORE_ERROR; case ErrorDlg::BUTTON_RETRY: - return ErrorHandler::RETRY; + return DeleteFilesHandler::RETRY; case ErrorDlg::BUTTON_ABORT: throw FreeFileSync::AbortThisProcess(); - default: - assert (false); - return ErrorHandler::IGNORE_ERROR; //dummy return value } + + assert (false); + return DeleteFilesHandler::IGNORE_ERROR; //dummy return value + } + + virtual void deletionSuccessful() //called for each file/folder that has been deleted + { + ++deletionCount; + + if (updateUiIsAllowed()) //test if specific time span between ui updates is over + { + wxString statusMessage = _("%x / %y objects deleted successfully"); + statusMessage.Replace(wxT("%x"), globalFunctions::numberToWxString(deletionCount), false); + statusMessage.Replace(wxT("%y"), globalFunctions::numberToWxString(totalObjToDelete), false); + + mainDlg->m_staticTextStatusMiddle->SetLabel(statusMessage); + mainDlg->m_panel7->Layout(); + + updateUiNow(); + } + + if (abortRequested) //test after (implicit) call to wxApp::Yield() + throw FreeFileSync::AbortThisProcess(); } private: + void OnAbortCompare(wxCommandEvent& event) //handle abort button click + { + abortRequested = true; //don't throw exceptions in a GUI-Callback!!! (throw FreeFileSync::AbortThisProcess()) + } + + MainDialog* const mainDlg; + const int totalObjToDelete; + + bool abortRequested; bool ignoreErrors; + unsigned int deletionCount; }; @@ -551,18 +614,20 @@ void MainDialog::deleteSelectedFiles() { //map lines from GUI view to grid line references for "currentGridData" FolderCompRef compRefLeft; - gridDataView.viewRefToFolderRef(viewSelectionLeft, compRefLeft); + gridDataView->viewRefToFolderRef(viewSelectionLeft, compRefLeft); FolderCompRef compRefRight; - gridDataView.viewRefToFolderRef(viewSelectionRight, 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, - globalSettings.gui.useRecyclerForManualDeletion); + globalSettings.gui.useRecyclerForManualDeletion, + totalDeleteCount); if (confirmDeletion->ShowModal() == DeleteDialog::BUTTON_OKAY) { if (globalSettings.gui.useRecyclerForManualDeletion && !FreeFileSync::recycleBinExists()) @@ -574,10 +639,11 @@ void MainDialog::deleteSelectedFiles() //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 - DeleteErrorHandler errorHandler; + ManualDeletionHandler statusHandler(this, totalDeleteCount); assert(compRefLeft.size() == currentGridData.size()); //GridView::viewRefToFolderRef() should ensure this! assert(compRefRight.size() == currentGridData.size()); @@ -594,8 +660,8 @@ void MainDialog::deleteSelectedFiles() rowsToDeleteOnRight, globalSettings.gui.deleteOnBothSides, globalSettings.gui.useRecyclerForManualDeletion, - cfg.syncConfiguration, - &errorHandler); + currentCfg.mainCfg.syncConfiguration, + &statusHandler); } } @@ -612,83 +678,80 @@ void MainDialog::deleteSelectedFiles() } -void MainDialog::openWithFileManager(const int rowNumber, const bool leftSide) +void exstractNames(const FileDescrLine& fileDescr, wxString& name, wxString& dir) { - wxString command; - - if (0 <= rowNumber && rowNumber < int(gridDataView.elementsOnView())) + switch (fileDescr.objType) { - const FileDescrLine* fileDescr = leftSide ? - &gridDataView[rowNumber].fileDescrLeft : - &gridDataView[rowNumber].fileDescrRight; + case FileDescrLine::TYPE_FILE: + name = fileDescr.fullName.c_str(); + dir = wxString(fileDescr.fullName.c_str()).BeforeLast(globalFunctions::FILE_NAME_SEPARATOR); + break; - switch (fileDescr->objType) - { - case FileDescrLine::TYPE_FILE: - command = globalSettings.gui.commandLineFileManager; - command.Replace(wxT("%name"), fileDescr->fullName.c_str()); - command.Replace(wxT("%path"), wxString(fileDescr->fullName.c_str()).BeforeLast(FreeFileSync::FILE_NAME_SEPARATOR)); - break; - case FileDescrLine::TYPE_DIRECTORY: - command = globalSettings.gui.commandLineFileManager; - command.Replace(wxT("%name"), fileDescr->fullName.c_str()); - command.Replace(wxT("%path"), fileDescr->fullName.c_str()); - break; - case FileDescrLine::TYPE_NOTHING: - { - //use path from other side - const FileDescrLine* fileDescrOther = leftSide ? - &gridDataView[rowNumber].fileDescrRight : - &gridDataView[rowNumber].fileDescrLeft; + case FileDescrLine::TYPE_DIRECTORY: + name = fileDescr.fullName.c_str(); + dir = fileDescr.fullName.c_str(); + break; - const wxString syncFolder = leftSide ? - gridDataView.getFolderPair(rowNumber).leftDirectory.c_str() : - gridDataView.getFolderPair(rowNumber).rightDirectory.c_str(); + case FileDescrLine::TYPE_NOTHING: + name.clear(); + dir.clear(); + break; + } +} - wxString alternateFolder; - switch (fileDescrOther->objType) - { - case FileDescrLine::TYPE_FILE: - alternateFolder = syncFolder + wxString(fileDescrOther->relativeName.c_str()).BeforeLast(FreeFileSync::FILE_NAME_SEPARATOR); - break; - case FileDescrLine::TYPE_DIRECTORY: - alternateFolder = syncFolder + wxString(fileDescrOther->relativeName.c_str()); - break; - case FileDescrLine::TYPE_NOTHING: - assert(false); - break; - } - if (!wxDirExists(alternateFolder)) - alternateFolder = syncFolder; +void MainDialog::openWithFileManager(const int rowNumber, const bool leftSide) +{ + wxString command = globalSettings.gui.commandLineFileManager; -#ifdef FFS_WIN - command = wxString(wxT("explorer ")) + alternateFolder; //default -#elif defined FFS_LINUX - command = globalSettings.gui.commandLineFileManager; - command.Replace(wxT("%name"), alternateFolder); - command.Replace(wxT("%path"), alternateFolder); -#endif + wxString name; + wxString dir; + wxString nameCo; + wxString dirCo; + + if (0 <= rowNumber && rowNumber < int(gridDataView->elementsOnView())) + { + if (leftSide) + { + exstractNames((*gridDataView)[rowNumber].fileDescrLeft, name, dir); + exstractNames((*gridDataView)[rowNumber].fileDescrRight, nameCo, dirCo); } - break; + else + { + exstractNames((*gridDataView)[rowNumber].fileDescrRight, name, dir); + exstractNames((*gridDataView)[rowNumber].fileDescrLeft, nameCo, dirCo); + } +#ifdef FFS_WIN + if (name.empty()) + { + if (leftSide) + wxExecute(wxString(wxT("explorer ")) + gridDataView->getFolderPair(rowNumber).leftDirectory); + else + wxExecute(wxString(wxT("explorer ")) + gridDataView->getFolderPair(rowNumber).rightDirectory); + return; } +#endif } else { //fallback - const wxString defaultFolder = leftSide ? - FreeFileSync::getFormattedDirectoryName(m_directoryLeft->GetValue().c_str()).c_str() : - FreeFileSync::getFormattedDirectoryName(m_directoryRight->GetValue().c_str()).c_str(); + dir = FreeFileSync::getFormattedDirectoryName(m_directoryLeft->GetValue().c_str()).c_str(); + dirCo = FreeFileSync::getFormattedDirectoryName(m_directoryRight->GetValue().c_str()).c_str(); + + if (!leftSide) + std::swap(dir, dirCo); + #ifdef FFS_WIN - command = wxString(wxT("explorer ")) + defaultFolder; //default -#elif defined FFS_LINUX - command = globalSettings.gui.commandLineFileManager; - command.Replace(wxT("%name"), defaultFolder); - command.Replace(wxT("%path"), defaultFolder); + wxExecute(wxString(wxT("explorer ")) + dir); //default + return; #endif } - if (!command.empty()) - wxExecute(command.c_str()); + 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); } @@ -712,7 +775,80 @@ void MainDialog::clearStatusBar() } -void MainDialog::onResizeMainWindow(wxEvent& event) +void MainDialog::disableAllElements() +{ //disenables all elements (except abort button) that might receive user input during long-running processes: comparison, deletion + m_bpButtonCmpConfig-> Disable(); + m_notebookBottomLeft->Disable(); + m_checkBoxHideFilt-> Disable(); + m_bpButtonSyncConfig->Disable(); + m_buttonStartSync-> Disable(); + m_dirPickerLeft-> Disable(); + m_dirPickerRight-> Disable(); + m_bpButtonSwapSides-> Disable(); + m_bpButtonLeftOnly-> Disable(); + m_bpButtonLeftNewer-> Disable(); + m_bpButtonEqual-> Disable(); + m_bpButtonDifferent-> Disable(); + m_bpButtonRightNewer->Disable(); + m_bpButtonRightOnly-> Disable(); + m_panelLeft-> Disable(); + m_panelMiddle-> Disable(); + m_panelRight-> Disable(); + m_panelTopLeft-> Disable(); + m_panelTopMiddle-> Disable(); + m_panelTopRight-> Disable(); + m_bpButton10-> Disable(); + m_scrolledWindowFolderPairs->Disable(); + m_menubar1->EnableTop(0, false); + m_menubar1->EnableTop(1, false); + m_menubar1->EnableTop(2, false); + + //show abort button + m_buttonAbort->Enable(); + m_buttonAbort->Show(); + m_buttonCompare->Disable(); + m_buttonCompare->Hide(); + m_buttonAbort->SetFocus(); +} + + +void MainDialog::enableAllElements() +{ + m_bpButtonCmpConfig-> Enable(); + m_notebookBottomLeft->Enable(); + m_checkBoxHideFilt-> Enable(); + m_bpButtonSyncConfig->Enable(); + m_buttonStartSync-> Enable(); + m_dirPickerLeft-> Enable(); + m_dirPickerRight-> Enable(); + m_bpButtonSwapSides-> Enable(); + m_bpButtonLeftOnly-> Enable(); + m_bpButtonLeftNewer-> Enable(); + m_bpButtonEqual-> Enable(); + m_bpButtonDifferent-> Enable(); + m_bpButtonRightNewer->Enable(); + m_bpButtonRightOnly-> Enable(); + m_panelLeft-> Enable(); + m_panelMiddle-> Enable(); + m_panelRight-> Enable(); + m_panelTopLeft-> Enable(); + m_panelTopMiddle-> Enable(); + m_panelTopRight-> Enable(); + m_bpButton10-> Enable(); + m_scrolledWindowFolderPairs->Enable(); + m_menubar1->EnableTop(0, true); + m_menubar1->EnableTop(1, true); + m_menubar1->EnableTop(2, true); + + //show compare button + m_buttonAbort->Disable(); + m_buttonAbort->Hide(); + m_buttonCompare->Enable(); + m_buttonCompare->Show(); +} + + +void MainDialog::OnResize(wxSizeEvent& event) { if (!IsMaximized()) { @@ -733,6 +869,22 @@ void MainDialog::onResizeMainWindow(wxEvent& event) posYNotMaximized = y; } } + + event.Skip(); +} + + +void MainDialog::OnResizeFolderPairs(wxSizeEvent& event) +{ + //adapt left-shift display distortion caused by scrollbars for multiple folder pairs + if (additionalFolderPairs.size() > 0) + { + const int width = m_panelTopLeft->GetSize().GetWidth(); + + for (std::vector::iterator i = additionalFolderPairs.begin(); i != additionalFolderPairs.end(); ++i) + (*i)->m_panelLeft->SetMinSize(wxSize(width, -1)); + } + event.Skip(); } @@ -747,6 +899,8 @@ void MainDialog::onGridLeftButtonEvent(wxKeyEvent& event) copySelectionToClipboard(m_gridLeft); else if (keyCode == 65) //CTRL + A m_gridLeft->SelectAll(); + else if (keyCode == WXK_NUMPAD_ADD) //CTRL + '+' + m_gridLeft->AutoSizeColumns(false); } else if (keyCode == WXK_DELETE || keyCode == WXK_NUMPAD_DELETE) deleteSelectedFiles(); @@ -779,6 +933,8 @@ void MainDialog::onGridRightButtonEvent(wxKeyEvent& event) copySelectionToClipboard(m_gridRight); else if (keyCode == 65) //CTRL + A m_gridRight->SelectAll(); + else if (keyCode == WXK_NUMPAD_ADD) //CTRL + '+' + m_gridRight->AutoSizeColumns(false); } else if (keyCode == WXK_DELETE || keyCode == WXK_NUMPAD_DELETE) deleteSelectedFiles(); @@ -821,23 +977,23 @@ void MainDialog::OnContextRim(wxGridEvent& event) //re-create context menu contextMenu.reset(new wxMenu); - if (syncPreview->previewIsEnabled()) + if (syncPreview.previewIsEnabled()) { if (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((*gridDataView)[selectionBegin].cmpResult, 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((*gridDataView)[selectionBegin].cmpResult, 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((*gridDataView)[selectionBegin].cmpResult, true, SYNC_DIR_RIGHT)); contextMenu->Append(menuItemSyncDirRight); contextMenu->AppendSeparator(); @@ -848,7 +1004,7 @@ void MainDialog::OnContextRim(wxGridEvent& event) //CONTEXT_FILTER_TEMP if (selectionLeft.size() + selectionRight.size() > 0) { - if (gridDataView[selectionBegin].selectedForSynchronization) //valid access, as getSelectedRows returns valid references only + if ((*gridDataView)[selectionBegin].selectedForSynchronization) //valid access, as getSelectedRows returns valid references only { wxMenuItem* menuItemExclTemp = new wxMenuItem(contextMenu.get(), CONTEXT_FILTER_TEMP, _("Exclude temporarily")); menuItemExclTemp->SetBitmap(*GlobalResources::getInstance().bitmapCheckBoxFalse); @@ -873,7 +1029,7 @@ void MainDialog::OnContextRim(wxGridEvent& event) FilterObject newFilterEntry; for (std::set::const_iterator i = selectionLeft.begin(); i != selectionLeft.end(); ++i) { - const FileCompareLine& line = gridDataView[*i]; + const FileCompareLine& line = (*gridDataView)[*i]; newFilterEntry.relativeName = line.fileDescrLeft.relativeName.c_str(); newFilterEntry.type = line.fileDescrLeft.objType; if (!newFilterEntry.relativeName.IsEmpty()) @@ -881,7 +1037,7 @@ void MainDialog::OnContextRim(wxGridEvent& event) } for (std::set::const_iterator i = selectionRight.begin(); i != selectionRight.end(); ++i) { - const FileCompareLine& line = gridDataView[*i]; + const FileCompareLine& line = (*gridDataView)[*i]; newFilterEntry.relativeName = line.fileDescrRight.relativeName.c_str(); newFilterEntry.type = line.fileDescrRight.objType; if (!newFilterEntry.relativeName.IsEmpty()) @@ -893,7 +1049,7 @@ void MainDialog::OnContextRim(wxGridEvent& event) exFilterCandidateExtension.clear(); if (exFilterCandidateObj.size() > 0 && exFilterCandidateObj[0].type == FileDescrLine::TYPE_FILE) { - const wxString filename = exFilterCandidateObj[0].relativeName.AfterLast(FreeFileSync::FILE_NAME_SEPARATOR); + 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('.')); @@ -909,7 +1065,7 @@ void MainDialog::OnContextRim(wxGridEvent& event) //CONTEXT_EXCLUDE_OBJ wxMenuItem* menuItemExclObj = NULL; if (exFilterCandidateObj.size() == 1) - menuItemExclObj = new wxMenuItem(contextMenu.get(), CONTEXT_EXCLUDE_OBJ, wxString(_("Exclude via filter:")) + wxT(" ") + exFilterCandidateObj[0].relativeName.AfterLast(FreeFileSync::FILE_NAME_SEPARATOR)); + menuItemExclObj = new wxMenuItem(contextMenu.get(), CONTEXT_EXCLUDE_OBJ, wxString(_("Exclude via filter:")) + wxT(" ") + exFilterCandidateObj[0].relativeName.AfterLast(globalFunctions::FILE_NAME_SEPARATOR)); else if (exFilterCandidateObj.size() > 1) menuItemExclObj = new wxMenuItem(contextMenu.get(), CONTEXT_EXCLUDE_OBJ, wxString(_("Exclude via filter:")) + wxT(" ") + _("")); @@ -1001,19 +1157,19 @@ void MainDialog::OnContextRimSelection(wxCommandEvent& event) case CONTEXT_EXCLUDE_EXT: if (!exFilterCandidateExtension.IsEmpty()) { - if (!cfg.excludeFilter.IsEmpty() && !cfg.excludeFilter.EndsWith(wxT(";"))) - cfg.excludeFilter+= wxT("\n"); + if (!currentCfg.mainCfg.excludeFilter.IsEmpty() && !currentCfg.mainCfg.excludeFilter.EndsWith(wxT(";"))) + currentCfg.mainCfg.excludeFilter+= wxT("\n"); - cfg.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("*.")) + exFilterCandidateExtension + wxT(";"); //';' is appended to 'mark' that next exclude extension entry won't write to new line - cfg.filterIsActive = true; - updateFilterButton(m_bpButtonFilter, cfg.filterIsActive); + currentCfg.mainCfg.filterIsActive = true; + updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive); - FreeFileSync::FilterProcess filterInstance(cfg.includeFilter, cfg.excludeFilter); + FreeFileSync::FilterProcess filterInstance(currentCfg.mainCfg.includeFilter, currentCfg.mainCfg.excludeFilter); filterInstance.filterGridData(currentGridData); updateGuiGrid(); - if (hideFilteredElements) + if (currentCfg.hideFilteredElements) { m_gridLeft->ClearSelection(); m_gridRight->ClearSelection(); @@ -1027,24 +1183,24 @@ void MainDialog::OnContextRimSelection(wxCommandEvent& event) { for (std::vector::const_iterator i = exFilterCandidateObj.begin(); i != exFilterCandidateObj.end(); ++i) { - if (!cfg.excludeFilter.IsEmpty() && !cfg.excludeFilter.EndsWith(wxT("\n"))) - cfg.excludeFilter+= wxT("\n"); + if (!currentCfg.mainCfg.excludeFilter.IsEmpty() && !currentCfg.mainCfg.excludeFilter.EndsWith(wxT("\n"))) + currentCfg.mainCfg.excludeFilter+= wxT("\n"); if (i->type == FileDescrLine::TYPE_FILE) - cfg.excludeFilter+= wxString(FreeFileSync::FILE_NAME_SEPARATOR) + i->relativeName; + currentCfg.mainCfg.excludeFilter+= wxString(globalFunctions::FILE_NAME_SEPARATOR) + i->relativeName; else if (i->type == FileDescrLine::TYPE_DIRECTORY) - cfg.excludeFilter+= wxString(FreeFileSync::FILE_NAME_SEPARATOR) + i->relativeName + FreeFileSync::FILE_NAME_SEPARATOR + wxT("*"); + currentCfg.mainCfg.excludeFilter+= wxString(globalFunctions::FILE_NAME_SEPARATOR) + i->relativeName + globalFunctions::FILE_NAME_SEPARATOR + wxT("*"); else assert(false); } - cfg.filterIsActive = true; - updateFilterButton(m_bpButtonFilter, cfg.filterIsActive); + currentCfg.mainCfg.filterIsActive = true; + updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive); - FreeFileSync::FilterProcess filterInstance(cfg.includeFilter, cfg.excludeFilter); + FreeFileSync::FilterProcess filterInstance(currentCfg.mainCfg.includeFilter, currentCfg.mainCfg.excludeFilter); filterInstance.filterGridData(currentGridData); updateGuiGrid(); - if (hideFilteredElements) + if (currentCfg.hideFilteredElements) { m_gridLeft->ClearSelection(); m_gridRight->ClearSelection(); @@ -1088,7 +1244,14 @@ void MainDialog::OnContextRimSelection(wxCommandEvent& event) void MainDialog::OnContextRimLabelLeft(wxGridEvent& event) { contextMenu.reset(new wxMenu); //re-create context menu - contextMenu->Append(CONTEXT_CUSTOMIZE_COLUMN_LEFT, _("Customize columns")); + contextMenu->Append(CONTEXT_CUSTOMIZE_COLUMN_LEFT, _("Customize...")); + + contextMenu->AppendSeparator(); + + wxMenuItem* itemAutoAdjust = new wxMenuItem(contextMenu.get(), CONTEXT_AUTO_ADJUST_COLUMN_LEFT, _("Auto-adjust columns"), wxEmptyString, wxITEM_CHECK); + contextMenu->Append(itemAutoAdjust); + itemAutoAdjust->Check(globalSettings.gui.autoAdjustColumnsLeft); + contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextRimLabelSelection), NULL, this); PopupMenu(contextMenu.get()); //show context menu } @@ -1097,7 +1260,14 @@ void MainDialog::OnContextRimLabelLeft(wxGridEvent& event) void MainDialog::OnContextRimLabelRight(wxGridEvent& event) { contextMenu.reset(new wxMenu); //re-create context menu - contextMenu->Append(CONTEXT_CUSTOMIZE_COLUMN_RIGHT, _("Customize columns")); + contextMenu->Append(CONTEXT_CUSTOMIZE_COLUMN_RIGHT, _("Customize...")); + + contextMenu->AppendSeparator(); + + wxMenuItem* itemAutoAdjust = new wxMenuItem(contextMenu.get(), CONTEXT_AUTO_ADJUST_COLUMN_RIGHT, _("Auto-adjust columns"), wxEmptyString, wxITEM_CHECK); + contextMenu->Append(itemAutoAdjust); + itemAutoAdjust->Check(globalSettings.gui.autoAdjustColumnsRight); + contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextRimLabelSelection), NULL, this); PopupMenu(contextMenu.get()); //show context menu } @@ -1125,6 +1295,7 @@ void MainDialog::OnContextRimLabelSelection(wxCommandEvent& event) } } break; + case CONTEXT_CUSTOMIZE_COLUMN_RIGHT: { xmlAccess::ColumnAttributes colAttr = m_gridRight->getColumnAttributes(); @@ -1142,6 +1313,16 @@ void MainDialog::OnContextRimLabelSelection(wxCommandEvent& event) } } 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; } } @@ -1153,7 +1334,7 @@ void MainDialog::OnContextMiddle(wxGridEvent& event) contextMenu->Append(CONTEXT_CHECK_ALL, _("Check all")); contextMenu->Append(CONTEXT_UNCHECK_ALL, _("Uncheck all")); - if (gridDataView.refGridIsEmpty()) + if (gridDataView->refGridIsEmpty()) { contextMenu->Enable(CONTEXT_CHECK_ALL, false); contextMenu->Enable(CONTEXT_UNCHECK_ALL, false); @@ -1188,7 +1369,7 @@ void MainDialog::OnContextMiddleLabel(wxGridEvent& event) wxMenuItem* itemSyncPreview = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_PREVIEW, _("Synchronization Preview")); wxMenuItem* itemCmpResult = new wxMenuItem(contextMenu.get(), CONTEXT_COMPARISON_RESULT, _("Comparison Result")); - if (syncPreview->previewIsEnabled()) + if (syncPreview.previewIsEnabled()) itemSyncPreview->SetBitmap(*GlobalResources::getInstance().bitmapSyncViewSmall); else itemCmpResult->SetBitmap(*GlobalResources::getInstance().bitmapCmpViewSmall); @@ -1208,11 +1389,11 @@ void MainDialog::OnContextMiddleLabelSelection(wxCommandEvent& event) { case CONTEXT_COMPARISON_RESULT: //change view - syncPreview->enablePreview(false); + syncPreview.enablePreview(false); break; case CONTEXT_SYNC_PREVIEW: //change view - syncPreview->enablePreview(true); + syncPreview.enablePreview(true); break; } } @@ -1223,7 +1404,7 @@ void MainDialog::OnDirSelected(wxFileDirPickerEvent& event) //left and right directory text-control and dirpicker are synchronized by MainFolderDragDrop automatically //disable the sync button - syncPreview->enableSynchronization(false); + syncPreview.enableSynchronization(false); //clear grids currentGridData.clear(); @@ -1242,18 +1423,23 @@ wxString getFormattedHistoryElement(const wxString& filename) } +wxString getFullFilename(const wxString& name) +{ + //resolve relative names to avoid problems after working directory is changed + wxFileName filename(name); + if (!filename.Normalize()) + return name; //fallback + + return filename.GetFullPath(); +} + + //tests if the same filenames are specified, even if they are relative to the current working directory inline bool sameFileSpecified(const wxString& file1, const wxString& file2) { - wxString file1Full = file1; - wxString file2Full = file2; - - if (wxFileName(file1).GetPath() == wxEmptyString) - file1Full = wxFileName::GetCwd() + FreeFileSync::FILE_NAME_SEPARATOR + file1; - - if (wxFileName(file2).GetPath() == wxEmptyString) - file2Full = wxFileName::GetCwd() + FreeFileSync::FILE_NAME_SEPARATOR + file2; + const wxString file1Full = getFullFilename(file1); + 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; @@ -1284,8 +1470,8 @@ void MainDialog::addFileToCfgHistory(const wxString& filename) if (!wxFileExists(filename)) return; - std::vector::const_iterator i; - if ((i = find_if(cfgFileNames.begin(), cfgFileNames.end(), FindDuplicates(filename))) != cfgFileNames.end()) + std::vector::const_iterator i = find_if(cfgFileNames.begin(), cfgFileNames.end(), FindDuplicates(filename)); + if (i != cfgFileNames.end()) { //if entry is in the list, then jump to element m_choiceHistory->SetSelection(i - cfgFileNames.begin()); } @@ -1294,7 +1480,7 @@ void MainDialog::addFileToCfgHistory(const wxString& filename) cfgFileNames.insert(cfgFileNames.begin(), filename); //the default config file should receive another name on GUI - if (sameFileSpecified(FreeFileSync::getLastConfigFile(), filename)) + if (sameFileSpecified(lastConfigFileName(), filename)) m_choiceHistory->Insert(_(""), 0); //insert at beginning of list else m_choiceHistory->Insert(getFormattedHistoryElement(filename), 0); //insert at beginning of list @@ -1407,18 +1593,6 @@ void MainDialog::OnLoadFromHistory(wxCommandEvent& event) } -void MainDialog::OnMenuSaveConfig(wxCommandEvent& event) -{ - OnSaveConfig(event); -} - - -void MainDialog::OnMenuLoadConfig(wxCommandEvent& event) -{ - OnLoadConfig(event); -} - - void MainDialog::loadConfiguration(const wxString& filename) { //notify user about changed settings @@ -1516,20 +1690,6 @@ void MainDialog::OnFolderHistoryKeyEvent(wxKeyEvent& event) } -void MainDialog::OnCompareByTimeSize(wxCommandEvent& event) -{ - cfg.compareVar = CMP_BY_TIME_SIZE; - updateCompareButtons(); -} - - -void MainDialog::OnCompareByContent(wxCommandEvent& event) -{ - cfg.compareVar = CMP_BY_CONTENT; - updateCompareButtons(); -} - - void MainDialog::OnClose(wxCloseEvent &event) { requestShutdown(); @@ -1584,7 +1744,7 @@ void MainDialog::OnCheckRows(FFSCheckRowsEvent& event) { std::set selectedRowsOnView; - for (int i = lowerBound; i <= std::min(upperBound, int(gridDataView.elementsOnView()) - 1); ++i) + for (int i = lowerBound; i <= std::min(upperBound, int(gridDataView->elementsOnView()) - 1); ++i) selectedRowsOnView.insert(i); filterRangeManually(selectedRowsOnView, event.rowFrom); @@ -1599,10 +1759,10 @@ 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->elementsOnView()) - 1); ++i) { - gridDataView[i].direction = event.direction; - gridDataView[i].selectedForSynchronization = true; + (*gridDataView)[i].syncDir = event.direction; + (*gridDataView)[i].selectedForSynchronization = true; } updateGuiGrid(); @@ -1613,101 +1773,81 @@ void MainDialog::OnSetSyncDirection(FFSSyncDirectionEvent& event) bool MainDialog::readConfigurationFromXml(const wxString& filename, bool programStartup) { //load XML - xmlAccess::XmlGuiConfig guiCfg; //structure to receive gui settings, already defaulted!! + xmlAccess::XmlGuiConfig newGuiCfg; //structure to receive gui settings, already defaulted!! try { - guiCfg = xmlAccess::readGuiConfig(filename); + xmlAccess::readGuiConfig(filename, newGuiCfg); } - catch (const FileError& error) + catch (const xmlAccess::XmlError& error) { - if (programStartup) - { - if (filename == FreeFileSync::getLastConfigFile() && !wxFileExists(filename)) //do not show error in this case - ; - else //program startup: show error message and load defaults - wxMessageBox(error.show().c_str(), _("Error"), wxOK | wxICON_ERROR); - } + if (programStartup && filename == lastConfigFileName() && !wxFileExists(filename)) //do not show error message in this case + ; else { - wxMessageBox(error.show().c_str(), _("Error"), wxOK | wxICON_ERROR); - return false; + if (error.getSeverity() == xmlAccess::XmlError::WARNING) + wxMessageBox(error.show(), _("Warning"), wxOK | wxICON_WARNING); + else + { + wxMessageBox(error.show(), _("Error"), wxOK | wxICON_ERROR); + return false; + } } } - //(re-)set view filter buttons - gridDataView.leftOnlyFilesActive = true; - gridDataView.leftNewerFilesActive = true; - gridDataView.differentFilesActive = true; - gridDataView.rightNewerFilesActive = true; //do not save/load these bool values from harddisk! - gridDataView.rightOnlyFilesActive = true; //it's more convenient to have them defaulted at startup - gridDataView.equalFilesActive = false; - - gridDataView.conflictFilesActive = true; + currentCfg = newGuiCfg; - gridDataView.syncDirLeftActive = true; - gridDataView.syncDirRightActive = true; - gridDataView.syncDirNoneActive = true; - - updateViewFilterButtons(); + //evaluate new settings... + //disable the sync button + syncPreview.enableSynchronization(false); - //load main configuration into instance - cfg = guiCfg.mainCfg; + //clear grids + currentGridData.clear(); + updateGuiGrid(); - //update visible config on main window - updateCompareButtons(); + //(re-)set view filter buttons + gridDataView->resetSettings(); + updateViewFilterButtons(); - updateFilterButton(m_bpButtonFilter, cfg.filterIsActive); + updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive); //read folder pairs: + //clear existing pairs first - m_directoryLeft->SetSelection(wxNOT_FOUND); - m_directoryLeft->SetValue(wxEmptyString); - m_dirPickerLeft->SetPath(wxEmptyString); - m_directoryRight->SetSelection(wxNOT_FOUND); - m_directoryRight->SetValue(wxEmptyString); - m_dirPickerRight->SetPath(wxEmptyString); + FreeFileSync::setDirectoryName(wxEmptyString, m_directoryLeft, m_dirPickerLeft); + FreeFileSync::setDirectoryName(wxEmptyString, m_directoryRight, m_dirPickerRight); - clearFolderPairs(); + clearAddFolderPairs(); - if (guiCfg.directoryPairs.size() > 0) + if (currentCfg.directoryPairs.size() > 0) { //set main folder pair - std::vector::const_iterator main = guiCfg.directoryPairs.begin(); + std::vector::const_iterator main = currentCfg.directoryPairs.begin(); - m_directoryLeft->SetValue(main->leftDirectory.c_str()); - const wxString leftDirFormatted = FreeFileSync::getFormattedDirectoryName(main->leftDirectory).c_str(); - if (wxDirExists(leftDirFormatted)) - m_dirPickerLeft->SetPath(leftDirFormatted); - addLeftFolderToHistory(main->leftDirectory.c_str()); //another hack: wxCombobox::Insert() asynchronously sends message overwriting a later wxCombobox::SetValue()!!! :( + FreeFileSync::setDirectoryName(main->leftDirectory.c_str(), m_directoryLeft, m_dirPickerLeft); + FreeFileSync::setDirectoryName(main->rightDirectory.c_str(), m_directoryRight, m_dirPickerRight); - m_directoryRight->SetValue(main->rightDirectory.c_str()); - const wxString rightDirFormatted = FreeFileSync::getFormattedDirectoryName(main->rightDirectory).c_str(); - if (wxDirExists(rightDirFormatted)) - m_dirPickerRight->SetPath(rightDirFormatted); - addRightFolderToHistory(main->rightDirectory.c_str()); //another hack... + 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 - std::vector additionalPairs; //don't modify guiCfg.directoryPairs! - for (std::vector::const_iterator i = guiCfg.directoryPairs.begin() + 1; i != guiCfg.directoryPairs.end(); ++i) - additionalPairs.push_back(*i); - addFolderPair(additionalPairs); + addFolderPair(std::vector(currentCfg.directoryPairs.begin() + 1, currentCfg.directoryPairs.end())); } //read GUI layout - hideFilteredElements = guiCfg.hideFilteredElements; - m_checkBoxHideFilt->SetValue(hideFilteredElements); + currentCfg.hideFilteredElements = currentCfg.hideFilteredElements; + m_checkBoxHideFilt->SetValue(currentCfg.hideFilteredElements); - ignoreErrors = guiCfg.ignoreErrors; + currentCfg.ignoreErrors = currentCfg.ignoreErrors; - syncPreview->enablePreview(guiCfg.syncPreviewEnabled); + syncPreview.enablePreview(currentCfg.syncPreviewEnabled); //########################################################### addFileToCfgHistory(filename); //put filename on list of last used config files - lastConfigurationSaved = guiCfg; + lastConfigurationSaved = currentCfg; - if (filename == FreeFileSync::getLastConfigFile()) //set title + if (filename == lastConfigFileName()) //set title { SetTitle(wxString(wxT("FreeFileSync - ")) + _("Folder Comparison and Synchronization")); currentConfigFileName.clear(); @@ -1718,8 +1858,11 @@ bool MainDialog::readConfigurationFromXml(const wxString& filename, bool program currentConfigFileName = filename; } - //update variant name - m_staticTextVariant->SetLabel(wxString(wxT("(")) + cfg.syncConfiguration.getVariantName() + wxT(")")); + //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; @@ -1733,20 +1876,20 @@ bool MainDialog::writeConfigurationToXml(const wxString& filename) //write config to XML try { - xmlAccess::writeGuiConfig(filename, guiCfg); + xmlAccess::writeGuiConfig(guiCfg, filename); } - catch (const FileError& error) + catch (const xmlAccess::XmlError& error) { wxMessageBox(error.show().c_str(), _("Error"), wxOK | wxICON_ERROR); return false; } - //put filename on list of last used config files - addFileToCfgHistory(filename); + //########################################################### + addFileToCfgHistory(filename); //put filename on list of last used config files lastConfigurationSaved = guiCfg; - if (filename == FreeFileSync::getLastConfigFile()) //set title + if (filename == lastConfigFileName()) //set title { SetTitle(wxString(wxT("FreeFileSync - ")) + _("Folder Comparison and Synchronization")); currentConfigFileName.clear(); @@ -1763,27 +1906,22 @@ bool MainDialog::writeConfigurationToXml(const wxString& filename) xmlAccess::XmlGuiConfig MainDialog::getCurrentConfiguration() const { - xmlAccess::XmlGuiConfig guiCfg; - - //load structure with basic settings "mainCfg" - guiCfg.mainCfg = cfg; - guiCfg.directoryPairs = getFolderPairs(); - - //load structure with gui settings - guiCfg.hideFilteredElements = hideFilteredElements; + xmlAccess::XmlGuiConfig guiCfg = currentCfg; - guiCfg.ignoreErrors = ignoreErrors; - - guiCfg.syncPreviewEnabled = syncPreview->previewIsEnabled(); + //load settings whose ownership lies not in currentCfg + guiCfg.directoryPairs = getFolderPairs(); + guiCfg.syncPreviewEnabled = syncPreview.previewIsEnabled(); return guiCfg; } -void MainDialog::OnShowHelpDialog(wxCommandEvent &event) +const wxString& MainDialog::lastConfigFileName() { - HelpDlg* helpDlg = new HelpDlg(this); - helpDlg->ShowModal(); + static wxString instance = FreeFileSync::getConfigDir().EndsWith(wxString(globalFunctions::FILE_NAME_SEPARATOR)) ? + FreeFileSync::getConfigDir() + wxT("LastRun.ffs_gui") : + FreeFileSync::getConfigDir() + globalFunctions::FILE_NAME_SEPARATOR + wxT("LastRun.ffs_gui"); + return instance; } @@ -1795,7 +1933,7 @@ void MainDialog::refreshGridAfterFilterChange(const int delay) m_gridRight->ForceRefresh(); Update(); //show changes resulting from ForceRefresh() - if (hideFilteredElements) + 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) @@ -1810,13 +1948,13 @@ void MainDialog::refreshGridAfterFilterChange(const int delay) void MainDialog::OnFilterButton(wxCommandEvent &event) { //toggle filter on/off - cfg.filterIsActive = !cfg.filterIsActive; + currentCfg.mainCfg.filterIsActive = !currentCfg.mainCfg.filterIsActive; //make sure, button-appearance and "filterIsActive" are in sync. - updateFilterButton(m_bpButtonFilter, cfg.filterIsActive); + updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive); - if (cfg.filterIsActive) + if (currentCfg.mainCfg.filterIsActive) { - FreeFileSync::FilterProcess filterInstance(cfg.includeFilter, cfg.excludeFilter); + 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 } @@ -1830,9 +1968,9 @@ void MainDialog::OnFilterButton(wxCommandEvent &event) void MainDialog::OnHideFilteredButton(wxCommandEvent &event) { //toggle showing filtered rows - hideFilteredElements = !hideFilteredElements; + currentCfg.hideFilteredElements = !currentCfg.hideFilteredElements; //make sure, checkbox and "hideFiltered" are in sync - m_checkBoxHideFilt->SetValue(hideFilteredElements); + m_checkBoxHideFilt->SetValue(currentCfg.hideFilteredElements); m_gridLeft->ClearSelection(); m_gridRight->ClearSelection(); @@ -1845,29 +1983,29 @@ void MainDialog::OnHideFilteredButton(wxCommandEvent &event) void MainDialog::OnConfigureFilter(wxHyperlinkEvent &event) { - const wxString beforeImage = cfg.includeFilter + wxChar(1) + cfg.excludeFilter; + const wxString beforeImage = currentCfg.mainCfg.includeFilter + wxChar(1) + currentCfg.mainCfg.excludeFilter; - FilterDlg* filterDlg = new FilterDlg(this, cfg.includeFilter, cfg.excludeFilter); + FilterDlg* filterDlg = new FilterDlg(this, currentCfg.mainCfg.includeFilter, currentCfg.mainCfg.excludeFilter); if (filterDlg->ShowModal() == FilterDlg::BUTTON_OKAY) { - const wxString afterImage = cfg.includeFilter + wxChar(1) + cfg.excludeFilter; + 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 { - cfg.filterIsActive = false; + currentCfg.mainCfg.filterIsActive = false; FreeFileSync::FilterProcess::includeAllRowsOnGrid(currentGridData); } else { - cfg.filterIsActive = true; + currentCfg.mainCfg.filterIsActive = true; - FreeFileSync::FilterProcess filterInstance(cfg.includeFilter, cfg.excludeFilter); + FreeFileSync::FilterProcess filterInstance(currentCfg.mainCfg.includeFilter, currentCfg.mainCfg.excludeFilter); filterInstance.filterGridData(currentGridData); } - updateFilterButton(m_bpButtonFilter, cfg.filterIsActive); + updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive); updateGuiGrid(); } @@ -1879,35 +2017,35 @@ void MainDialog::OnConfigureFilter(wxHyperlinkEvent &event) void MainDialog::OnLeftOnlyFiles(wxCommandEvent& event) { - gridDataView.leftOnlyFilesActive = !gridDataView.leftOnlyFilesActive; + gridDataView->leftOnlyFilesActive = !gridDataView->leftOnlyFilesActive; updateViewFilterButtons(); updateGuiGrid(); }; void MainDialog::OnLeftNewerFiles(wxCommandEvent& event) { - gridDataView.leftNewerFilesActive = !gridDataView.leftNewerFilesActive; + gridDataView->leftNewerFilesActive = !gridDataView->leftNewerFilesActive; updateViewFilterButtons(); updateGuiGrid(); }; void MainDialog::OnDifferentFiles(wxCommandEvent& event) { - gridDataView.differentFilesActive = !gridDataView.differentFilesActive; + gridDataView->differentFilesActive = !gridDataView->differentFilesActive; updateViewFilterButtons(); updateGuiGrid(); }; void MainDialog::OnRightNewerFiles(wxCommandEvent& event) { - gridDataView.rightNewerFilesActive = !gridDataView.rightNewerFilesActive; + gridDataView->rightNewerFilesActive = !gridDataView->rightNewerFilesActive; updateViewFilterButtons(); updateGuiGrid(); }; void MainDialog::OnRightOnlyFiles(wxCommandEvent& event) { - gridDataView.rightOnlyFilesActive = !gridDataView.rightOnlyFilesActive; + gridDataView->rightOnlyFilesActive = !gridDataView->rightOnlyFilesActive; updateViewFilterButtons(); updateGuiGrid(); }; @@ -1915,7 +2053,7 @@ void MainDialog::OnRightOnlyFiles(wxCommandEvent& event) void MainDialog::OnEqualFiles(wxCommandEvent& event) { - gridDataView.equalFilesActive = !gridDataView.equalFilesActive; + gridDataView->equalFilesActive = !gridDataView->equalFilesActive; updateViewFilterButtons(); updateGuiGrid(); }; @@ -1923,7 +2061,39 @@ void MainDialog::OnEqualFiles(wxCommandEvent& event) void MainDialog::OnConflictFiles(wxCommandEvent& event) { - gridDataView.conflictFilesActive = !gridDataView.conflictFilesActive; + gridDataView->conflictFilesActive = !gridDataView->conflictFilesActive; + updateViewFilterButtons(); + updateGuiGrid(); +}; + + +void MainDialog::OnSyncCreateLeft(wxCommandEvent& event) +{ + gridDataView->syncCreateLeftActive = !gridDataView->syncCreateLeftActive; + updateViewFilterButtons(); + updateGuiGrid(); +}; + + +void MainDialog::OnSyncCreateRight(wxCommandEvent& event) +{ + gridDataView->syncCreateRightActive = !gridDataView->syncCreateRightActive; + updateViewFilterButtons(); + updateGuiGrid(); +}; + + +void MainDialog::OnSyncDeleteLeft(wxCommandEvent& event) +{ + gridDataView->syncDeleteLeftActive = !gridDataView->syncDeleteLeftActive; + updateViewFilterButtons(); + updateGuiGrid(); +}; + + +void MainDialog::OnSyncDeleteRight(wxCommandEvent& event) +{ + gridDataView->syncDeleteRightActive = !gridDataView->syncDeleteRightActive; updateViewFilterButtons(); updateGuiGrid(); }; @@ -1931,7 +2101,7 @@ void MainDialog::OnConflictFiles(wxCommandEvent& event) void MainDialog::OnSyncDirLeft(wxCommandEvent& event) { - gridDataView.syncDirLeftActive = !gridDataView.syncDirLeftActive; + gridDataView->syncDirLeftActive = !gridDataView->syncDirLeftActive; updateViewFilterButtons(); updateGuiGrid(); }; @@ -1939,7 +2109,7 @@ void MainDialog::OnSyncDirLeft(wxCommandEvent& event) void MainDialog::OnSyncDirRight(wxCommandEvent& event) { - gridDataView.syncDirRightActive = !gridDataView.syncDirRightActive; + gridDataView->syncDirRightActive = !gridDataView->syncDirRightActive; updateViewFilterButtons(); updateGuiGrid(); }; @@ -1947,7 +2117,7 @@ void MainDialog::OnSyncDirRight(wxCommandEvent& event) void MainDialog::OnSyncDirNone(wxCommandEvent& event) { - gridDataView.syncDirNoneActive = !gridDataView.syncDirNoneActive; + gridDataView->syncDirNoneActive = !gridDataView->syncDirNoneActive; updateViewFilterButtons(); updateGuiGrid(); }; @@ -1956,7 +2126,7 @@ void MainDialog::OnSyncDirNone(wxCommandEvent& event) void MainDialog::updateViewFilterButtons() { //compare result buttons - if (gridDataView.leftOnlyFilesActive) + if (gridDataView->leftOnlyFilesActive) { m_bpButtonLeftOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapLeftOnlyAct); m_bpButtonLeftOnly->SetToolTip(_("Hide files that exist on left side only")); @@ -1967,7 +2137,7 @@ void MainDialog::updateViewFilterButtons() m_bpButtonLeftOnly->SetToolTip(_("Show files that exist on left side only")); } - if (gridDataView.rightOnlyFilesActive) + if (gridDataView->rightOnlyFilesActive) { m_bpButtonRightOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapRightOnlyAct); m_bpButtonRightOnly->SetToolTip(_("Hide files that exist on right side only")); @@ -1978,7 +2148,7 @@ void MainDialog::updateViewFilterButtons() m_bpButtonRightOnly->SetToolTip(_("Show files that exist on right side only")); } - if (gridDataView.leftNewerFilesActive) + if (gridDataView->leftNewerFilesActive) { m_bpButtonLeftNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapLeftNewerAct); m_bpButtonLeftNewer->SetToolTip(_("Hide files that are newer on left")); @@ -1989,7 +2159,7 @@ void MainDialog::updateViewFilterButtons() m_bpButtonLeftNewer->SetToolTip(_("Show files that are newer on left")); } - if (gridDataView.rightNewerFilesActive) + if (gridDataView->rightNewerFilesActive) { m_bpButtonRightNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapRightNewerAct); m_bpButtonRightNewer->SetToolTip(_("Hide files that are newer on right")); @@ -2000,7 +2170,7 @@ void MainDialog::updateViewFilterButtons() m_bpButtonRightNewer->SetToolTip(_("Show files that are newer on right")); } - if (gridDataView.equalFilesActive) + if (gridDataView->equalFilesActive) { m_bpButtonEqual->SetBitmapLabel(*GlobalResources::getInstance().bitmapEqualAct); m_bpButtonEqual->SetToolTip(_("Hide files that are equal")); @@ -2011,7 +2181,7 @@ void MainDialog::updateViewFilterButtons() m_bpButtonEqual->SetToolTip(_("Show files that are equal")); } - if (gridDataView.differentFilesActive) + if (gridDataView->differentFilesActive) { m_bpButtonDifferent->SetBitmapLabel(*GlobalResources::getInstance().bitmapDifferentAct); m_bpButtonDifferent->SetToolTip(_("Hide files that are different")); @@ -2022,7 +2192,7 @@ void MainDialog::updateViewFilterButtons() m_bpButtonDifferent->SetToolTip(_("Show files that are different")); } - if (gridDataView.conflictFilesActive) + if (gridDataView->conflictFilesActive) { m_bpButtonConflict->SetBitmapLabel(*GlobalResources::getInstance().bitmapConflictAct); m_bpButtonConflict->SetToolTip(_("Hide conflicts")); @@ -2034,7 +2204,51 @@ void MainDialog::updateViewFilterButtons() } //sync preview buttons - if (gridDataView.syncDirLeftActive) + 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")); + } + + if (gridDataView->syncDirLeftActive) { m_bpButtonSyncDirLeft->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncDirLeftAct); m_bpButtonSyncDirLeft->SetToolTip(_("Hide files that will be copied to the left side")); @@ -2045,7 +2259,7 @@ void MainDialog::updateViewFilterButtons() m_bpButtonSyncDirLeft->SetToolTip(_("Show files that will be copied to the left side")); } - if (gridDataView.syncDirRightActive) + if (gridDataView->syncDirRightActive) { m_bpButtonSyncDirRight->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncDirRightAct); m_bpButtonSyncDirRight->SetToolTip(_("Hide files that will be copied to the right side")); @@ -2056,7 +2270,7 @@ void MainDialog::updateViewFilterButtons() m_bpButtonSyncDirRight->SetToolTip(_("Show files that will be copied to the right side")); } - if (gridDataView.syncDirNoneActive) + if (gridDataView->syncDirNoneActive) { m_bpButtonSyncDirNone->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncDirNoneAct); m_bpButtonSyncDirNone->SetToolTip(_("Hide files that won't be copied")); @@ -2097,29 +2311,6 @@ void MainDialog::updateFilterButton(wxBitmapButton* filterButton, bool isActive) } -void MainDialog::updateCompareButtons() -{ - switch (cfg.compareVar) - { - case CMP_BY_TIME_SIZE: - m_radioBtnSizeDate->SetValue(true); - break; - case CMP_BY_CONTENT: - m_radioBtnContent->SetValue(true); - break; - default: - assert (false); - } - - //disable the sync button - syncPreview->enableSynchronization(false); - - //clear grids - currentGridData.clear(); - updateGuiGrid(); -} - - std::vector MainDialog::getFolderPairs() const { std::vector output; @@ -2144,7 +2335,9 @@ void MainDialog::OnCompare(wxCommandEvent &event) wxBusyCursor dummy; //show hourglass cursor - //prevent temporary memory peak by clearing old result list + //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(); updateGuiGrid(); //refresh GUI grid @@ -2152,12 +2345,11 @@ void MainDialog::OnCompare(wxCommandEvent &event) try { //class handling status display and error messages CompareStatusHandler statusHandler(this); - cmpStatusHandlerTmp = &statusHandler; //prepare filter std::auto_ptr filterInstance(NULL); - if (cfg.filterIsActive) - filterInstance.reset(new FreeFileSync::FilterProcess(cfg.includeFilter, cfg.excludeFilter)); + if (currentCfg.mainCfg.filterIsActive) + filterInstance.reset(new FreeFileSync::FilterProcess(currentCfg.mainCfg.includeFilter, currentCfg.mainCfg.excludeFilter)); //begin comparison FreeFileSync::CompareProcess comparison(globalSettings.traverseDirectorySymlinks, @@ -2168,30 +2360,29 @@ void MainDialog::OnCompare(wxCommandEvent &event) &statusHandler); comparison.startCompareProcess(getFolderPairs(), - cfg.compareVar, - cfg.syncConfiguration, + currentCfg.mainCfg.compareVar, + currentCfg.mainCfg.syncConfiguration, currentGridData); //if (output.size < 50000) statusHandler.updateStatusText(_("Sorting file list...")); statusHandler.forceUiRefresh(); //keep total number of scanned files up to date - gridDataView.sortView(GridView::SORT_BY_DIRECTORY, true, true); + gridDataView->sortView(GridView::SORT_BY_DIRECTORY, true, true); } catch (AbortThisProcess&) { aborted = true; } - cmpStatusHandlerTmp = NULL; if (aborted) { //disable the sync button - syncPreview->enableSynchronization(false); + syncPreview.enableSynchronization(false); m_buttonCompare->SetFocus(); } else { //once compare is finished enable the sync button - syncPreview->enableSynchronization(true); + syncPreview.enableSynchronization(true); m_buttonStartSync->SetFocus(); //hide sort direction indicator on GUI grids @@ -2217,70 +2408,57 @@ void MainDialog::OnCompare(wxCommandEvent &event) } -void MainDialog::OnAbortCompare(wxCommandEvent& event) -{ - if (cmpStatusHandlerTmp) - cmpStatusHandlerTmp->requestAbortion(); -} - - void MainDialog::updateGuiGrid() { - m_gridLeft->BeginBatch(); //necessary?? + m_gridLeft ->BeginBatch(); //necessary?? m_gridMiddle->BeginBatch(); - m_gridRight->BeginBatch(); + m_gridRight ->BeginBatch(); updateGridViewData(); //update gridDataView and write status information - //all three grids retrieve their data directly via currentGridData!!! + //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 - m_gridLeft->updateGridSizes(); + m_gridLeft ->updateGridSizes(); m_gridMiddle->updateGridSizes(); - m_gridRight->updateGridSizes(); + m_gridRight ->updateGridSizes(); //enlarge label width to display row numbers correctly const int nrOfRows = m_gridLeft->GetNumberRows(); - - if (nrOfRows >= 1) + if (nrOfRows >= 0) { #ifdef FFS_WIN - const int digitWidth = 8; + const unsigned int digitWidth = 8; #elif defined FFS_LINUX - const int digitWidth = 10; + const unsigned int digitWidth = 10; #endif - const int nrOfDigits = int(floor(log10(double(nrOfRows)) + 1)); - m_gridLeft->SetRowLabelSize(nrOfDigits * digitWidth + 4); + const unsigned int nrOfDigits = globalFunctions::getDigitCount(static_cast(nrOfRows)); + m_gridLeft ->SetRowLabelSize(nrOfDigits * digitWidth + 4); m_gridRight->SetRowLabelSize(nrOfDigits * digitWidth + 4); } + //support for column auto adjustment + if (globalSettings.gui.autoAdjustColumnsLeft) + m_gridLeft->AutoSizeColumns(false); + if (globalSettings.gui.autoAdjustColumnsRight) + m_gridRight->AutoSizeColumns(false); + //update sync preview statistics calculatePreview(); - m_gridLeft->EndBatch(); + m_gridLeft ->EndBatch(); m_gridMiddle->EndBatch(); - m_gridRight->EndBatch(); + m_gridRight ->EndBatch(); } void MainDialog::calculatePreview() { //update preview of bytes to be transferred: - int objectsToCreate = 0; - int objectsToOverwrite = 0; - int objectsToDelete = 0; - int conflictsDummy = 0; - wxULongLong dataToProcess; - FreeFileSync::calcTotalBytesToSync(currentGridData, - objectsToCreate, - objectsToOverwrite, - objectsToDelete, - conflictsDummy, - dataToProcess); - - const wxString toCreate = globalFunctions::includeNumberSeparator(globalFunctions::numberToWxString(objectsToCreate)); - const wxString toUpdate = globalFunctions::includeNumberSeparator(globalFunctions::numberToWxString(objectsToOverwrite)); - const wxString toDelete = globalFunctions::includeNumberSeparator(globalFunctions::numberToWxString(objectsToDelete)); - const wxString data = FreeFileSync::formatFilesizeToShortString(dataToProcess); + const SyncStatistics st(currentGridData); + 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())); + const wxString data = FreeFileSync::formatFilesizeToShortString(st.getDataToProcess()); m_textCtrlCreate->SetValue(toCreate); m_textCtrlUpdate->SetValue(toUpdate); @@ -2292,56 +2470,67 @@ void MainDialog::calculatePreview() void MainDialog::OnSwitchView(wxCommandEvent& event) { //toggle view - syncPreview->enablePreview(!syncPreview->previewIsEnabled()); + syncPreview.enablePreview(!syncPreview.previewIsEnabled()); } void MainDialog::OnSyncSettings(wxCommandEvent& event) { - SyncDialog* syncDlg = new SyncDialog(this, currentGridData, cfg, ignoreErrors); - if (syncDlg->ShowModal() == SyncDialog::BUTTON_OKAY) + SyncCfgDialog* syncDlg = new SyncCfgDialog(this, currentGridData, currentCfg.mainCfg, currentCfg.ignoreErrors); + if (syncDlg->ShowModal() == SyncCfgDialog::BUTTON_OKAY) { - //update variant name - m_staticTextVariant->SetLabel(wxString(wxT("(")) + cfg.syncConfiguration.getVariantName() + wxT(")")); + //update sync variant name + m_staticTextSyncVariant->SetLabel(wxString(wxT("(")) + currentCfg.mainCfg.syncConfiguration.getVariantName() + wxT(")")); bSizer6->Layout(); //adapt layout for variant text - redetermineSyncDirection(cfg.syncConfiguration, currentGridData); + redetermineSyncDirection(currentCfg.mainCfg.syncConfiguration, currentGridData); updateGuiGrid(); } } +void MainDialog::OnCmpSettings(wxCommandEvent& event) +{ + CompareVariant newCmpVariant = currentCfg.mainCfg.compareVar; + + CompareCfgDialog* syncDlg = new CompareCfgDialog(this, newCmpVariant); + if (syncDlg->ShowModal() == CompareCfgDialog::BUTTON_OKAY) + { + if (currentCfg.mainCfg.compareVar != newCmpVariant) + { + currentCfg.mainCfg.compareVar = newCmpVariant; + + //update compare variant name + m_staticTextCmpVariant->SetLabel(wxString(wxT("(")) + getVariantName(currentCfg.mainCfg.compareVar) + wxT(")")); + bSizer6->Layout(); //adapt layout for variant text + + //disable the sync button + syncPreview.enableSynchronization(false); + + //clear grids + currentGridData.clear(); + updateGuiGrid(); + + m_buttonCompare->SetFocus(); + } + } +} + + void MainDialog::OnStartSync(wxCommandEvent& event) { - if (syncPreview->synchronizationIsEnabled()) + if (syncPreview.synchronizationIsEnabled()) { //show sync preview screen if (globalSettings.gui.showSummaryBeforeSync) { - //prepare preview screen - int objectsToCreate = 0; - int objectsToOverwrite = 0; - int objectsToDelete = 0; - int conflictsDummy = 0; - wxULongLong dataToProcess; - FreeFileSync::calcTotalBytesToSync(currentGridData, - objectsToCreate, - objectsToOverwrite, - objectsToDelete, - conflictsDummy, - dataToProcess); - - const wxString toCreate = globalFunctions::includeNumberSeparator(globalFunctions::numberToWxString(objectsToCreate)); - const wxString toUpdate = globalFunctions::includeNumberSeparator(globalFunctions::numberToWxString(objectsToOverwrite)); - const wxString toDelete = globalFunctions::includeNumberSeparator(globalFunctions::numberToWxString(objectsToDelete)); - const wxString data = FreeFileSync::formatFilesizeToShortString(dataToProcess); - bool dontShowAgain = false; SyncPreviewDlg* preview = new SyncPreviewDlg( - this, cfg.syncConfiguration.getVariantName(), - toCreate, toUpdate, toDelete, data, + this, + currentCfg.mainCfg.syncConfiguration.getVariantName(), + FreeFileSync::SyncStatistics(currentGridData), dontShowAgain); if (preview->ShowModal() != SyncPreviewDlg::BUTTON_START) @@ -2359,15 +2548,20 @@ 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 { //class handling status updates and error messages - SyncStatusHandler statusHandler(this, ignoreErrors); + SyncStatusHandler statusHandler(this, currentCfg.ignoreErrors); //start synchronization and return elements that were not sync'ed in currentGridData FreeFileSync::SyncProcess synchronization( - cfg.useRecycleBin, + currentCfg.mainCfg.handleDeletion, + currentCfg.mainCfg.customDeletionDirectory, globalSettings.copyFileSymlinks, globalSettings.traverseDirectorySymlinks, globalSettings.warnings, @@ -2388,12 +2582,12 @@ void MainDialog::OnStartSync(wxCommandEvent& event) m_gridMiddle->ClearSelection(); m_gridRight->ClearSelection(); - if (!gridDataView.refGridIsEmpty()) + 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); + syncPreview.enableSynchronization(false); } } } @@ -2433,22 +2627,22 @@ void MainDialog::OnSortLeftGrid(wxGridEvent& event) switch (columnType) { case xmlAccess::FULL_PATH: - gridDataView.sortView(GridView::SORT_BY_DIRECTORY, true, sortAscending); + gridDataView->sortView(GridView::SORT_BY_DIRECTORY, true, sortAscending); break; case xmlAccess::FILENAME: - gridDataView.sortView(GridView::SORT_BY_FILENAME, true, sortAscending); + gridDataView->sortView(GridView::SORT_BY_FILENAME, true, sortAscending); break; case xmlAccess::REL_PATH: - gridDataView.sortView(GridView::SORT_BY_REL_NAME, true, sortAscending); + gridDataView->sortView(GridView::SORT_BY_REL_NAME, true, sortAscending); break; case xmlAccess::DIRECTORY: - gridDataView.sortView(GridView::SORT_BY_DIRECTORY, true, sortAscending); + gridDataView->sortView(GridView::SORT_BY_DIRECTORY, true, sortAscending); break; case xmlAccess::SIZE: - gridDataView.sortView(GridView::SORT_BY_FILESIZE, true, sortAscending); + gridDataView->sortView(GridView::SORT_BY_FILESIZE, true, sortAscending); break; case xmlAccess::DATE: - gridDataView.sortView(GridView::SORT_BY_DATE, true, sortAscending); + gridDataView->sortView(GridView::SORT_BY_DATE, true, sortAscending); break; } @@ -2474,10 +2668,10 @@ void MainDialog::OnSortMiddleGrid(wxGridEvent& event) lastSortGrid = m_gridMiddle; //start sort - if (syncPreview->previewIsEnabled()) - gridDataView.sortView(GridView::SORT_BY_SYNC_DIRECTION, true, sortAscending); + if (syncPreview.previewIsEnabled()) + gridDataView->sortView(GridView::SORT_BY_SYNC_DIRECTION, true, sortAscending); else - gridDataView.sortView(GridView::SORT_BY_CMP_RESULT, true, sortAscending); + gridDataView->sortView(GridView::SORT_BY_CMP_RESULT, true, sortAscending); updateGuiGrid(); //refresh gridDataView @@ -2508,22 +2702,22 @@ void MainDialog::OnSortRightGrid(wxGridEvent& event) switch (columnType) { case xmlAccess::FULL_PATH: - gridDataView.sortView(GridView::SORT_BY_DIRECTORY, false, sortAscending); + gridDataView->sortView(GridView::SORT_BY_DIRECTORY, false, sortAscending); break; case xmlAccess::FILENAME: - gridDataView.sortView(GridView::SORT_BY_FILENAME, false, sortAscending); + gridDataView->sortView(GridView::SORT_BY_FILENAME, false, sortAscending); break; case xmlAccess::REL_PATH: - gridDataView.sortView(GridView::SORT_BY_REL_NAME, false, sortAscending); + gridDataView->sortView(GridView::SORT_BY_REL_NAME, false, sortAscending); break; case xmlAccess::DIRECTORY: - gridDataView.sortView(GridView::SORT_BY_DIRECTORY, false, sortAscending); + gridDataView->sortView(GridView::SORT_BY_DIRECTORY, false, sortAscending); break; case xmlAccess::SIZE: - gridDataView.sortView(GridView::SORT_BY_FILESIZE, false, sortAscending); + gridDataView->sortView(GridView::SORT_BY_FILESIZE, false, sortAscending); break; case xmlAccess::DATE: - gridDataView.sortView(GridView::SORT_BY_DATE, false, sortAscending); + gridDataView->sortView(GridView::SORT_BY_DATE, false, sortAscending); break; } @@ -2559,14 +2753,17 @@ void MainDialog::OnSwapSides(wxCommandEvent& event) } //swap view filter - std::swap(gridDataView.leftOnlyFilesActive, gridDataView.rightOnlyFilesActive); - std::swap(gridDataView.leftNewerFilesActive, gridDataView.rightNewerFilesActive); - std::swap(gridDataView.syncDirLeftActive, gridDataView.syncDirRightActive); + std::swap(gridDataView->leftOnlyFilesActive, gridDataView->rightOnlyFilesActive); + std::swap(gridDataView->leftNewerFilesActive, gridDataView->rightNewerFilesActive); + + std::swap(gridDataView->syncCreateLeftActive, gridDataView->syncCreateRightActive); + std::swap(gridDataView->syncDirLeftActive, gridDataView->syncDirRightActive); + std::swap(gridDataView->syncDeleteLeftActive, gridDataView->syncDeleteRightActive); updateViewFilterButtons(); //swap grid information - FreeFileSync::swapGrids(cfg.syncConfiguration, currentGridData); + FreeFileSync::swapGrids(currentCfg.mainCfg.syncConfiguration, currentGridData); updateGuiGrid(); event.Skip(); } @@ -2574,7 +2771,7 @@ void MainDialog::OnSwapSides(wxCommandEvent& event) void MainDialog::updateGridViewData() { - const GridView::StatusInfo result = gridDataView.update(hideFilteredElements, syncPreview->previewIsEnabled()); + const GridView::StatusInfo result = gridDataView->update(currentCfg.hideFilteredElements, syncPreview.previewIsEnabled()); //hide or enable view filter buttons @@ -2615,6 +2812,26 @@ void MainDialog::updateGridViewData() 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(); + + if (result.existsSyncDeleteLeft) + m_bpButtonSyncDeleteLeft->Show(); + else + m_bpButtonSyncDeleteLeft->Hide(); + + if (result.existsSyncDeleteRight) + m_bpButtonSyncDeleteRight->Show(); + else + m_bpButtonSyncDeleteRight->Hide(); + if (result.existsSyncDirLeft) m_bpButtonSyncDirLeft->Show(); else @@ -2631,15 +2848,19 @@ void MainDialog::updateGridViewData() m_bpButtonSyncDirNone->Hide(); - if ( result.existsLeftOnly || - result.existsRightOnly || - result.existsLeftNewer || - result.existsRightNewer || - result.existsDifferent || - result.existsEqual || - result.existsConflict || - result.existsSyncDirLeft || - result.existsSyncDirRight || + 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(); @@ -2669,7 +2890,7 @@ void MainDialog::updateGridViewData() statusLeftNew += _("1 directory"); else { - wxString folderCount = globalFunctions::includeNumberSeparator(globalFunctions::numberToWxString(result.foldersOnLeftView)); + wxString folderCount = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(result.foldersOnLeftView)); wxString outputString = _("%x directories"); outputString.Replace(wxT("%x"), folderCount, false); @@ -2686,7 +2907,7 @@ void MainDialog::updateGridViewData() statusLeftNew += _("1 file,"); else { - wxString fileCount = globalFunctions::includeNumberSeparator(globalFunctions::numberToWxString(result.filesOnLeftView)); + wxString fileCount = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(result.filesOnLeftView)); wxString outputString = _("%x files,"); outputString.Replace(wxT("%x"), fileCount, false); @@ -2696,7 +2917,7 @@ void MainDialog::updateGridViewData() statusLeftNew += FreeFileSync::formatFilesizeToShortString(result.filesizeLeftView); } - const wxString objectsView = globalFunctions::includeNumberSeparator(globalFunctions::numberToWxString(gridDataView.elementsOnView())); + const wxString objectsView = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(gridDataView->elementsOnView())); if (result.objectsTotal == 1) { wxString outputString = _("%x of 1 row in view"); @@ -2705,7 +2926,7 @@ void MainDialog::updateGridViewData() } else { - const wxString objectsTotal = globalFunctions::includeNumberSeparator(globalFunctions::numberToWxString(result.objectsTotal)); + const wxString objectsTotal = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(result.objectsTotal)); wxString outputString = _("%x of %y rows in view"); outputString.Replace(wxT("%x"), objectsView, false); @@ -2719,7 +2940,7 @@ void MainDialog::updateGridViewData() statusRightNew += _("1 directory"); else { - wxString folderCount = globalFunctions::includeNumberSeparator(globalFunctions::numberToWxString(result.foldersOnRightView)); + wxString folderCount = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(result.foldersOnRightView)); wxString outputString = _("%x directories"); outputString.Replace(wxT("%x"), folderCount, false); @@ -2736,7 +2957,7 @@ void MainDialog::updateGridViewData() statusRightNew += _("1 file,"); else { - wxString fileCount = globalFunctions::includeNumberSeparator(globalFunctions::numberToWxString(result.filesOnRightView)); + wxString fileCount = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(result.filesOnRightView)); wxString outputString = _("%x files,"); outputString.Replace(wxT("%x"), fileCount, false); @@ -2762,21 +2983,18 @@ void MainDialog::updateGridViewData() void MainDialog::OnAddFolderPair(wxCommandEvent& event) { - const wxString topPairLeft = m_directoryLeft->GetValue(); - const wxString topPairRight = m_directoryRight->GetValue(); + std::vector newPairs; + newPairs.push_back(FolderPair(m_directoryLeft ->GetValue().c_str(), + m_directoryRight->GetValue().c_str())); - //clear existing pairs first - m_directoryLeft->SetSelection(wxNOT_FOUND); - m_directoryLeft->SetValue(wxEmptyString); - m_dirPickerLeft->SetPath(wxEmptyString); - m_directoryRight->SetSelection(wxNOT_FOUND); - m_directoryRight->SetValue(wxEmptyString); - m_dirPickerRight->SetPath(wxEmptyString); + addFolderPair(newPairs, true); //add pair in front of additonal pairs - addFolderPair(topPairLeft.c_str(), topPairRight.c_str(), true); //add pair in front of additonal pairs + //clear existing pairs + FreeFileSync::setDirectoryName(wxEmptyString, m_directoryLeft, m_dirPickerLeft); + FreeFileSync::setDirectoryName(wxEmptyString, m_directoryRight, m_dirPickerRight); //disable the sync button - syncPreview->enableSynchronization(false); + syncPreview.enableSynchronization(false); //clear grids currentGridData.clear(); @@ -2792,10 +3010,10 @@ void MainDialog::OnRemoveFolderPair(wxCommandEvent& event) { if (eventObj == static_cast((*i)->m_bpButtonRemovePair)) { - removeFolderPair(i - additionalFolderPairs.begin()); + removeAddFolderPair(i - additionalFolderPairs.begin()); //disable the sync button - syncPreview->enableSynchronization(false); + syncPreview.enableSynchronization(false); //clear grids currentGridData.clear(); @@ -2810,16 +3028,16 @@ void MainDialog::OnRemoveTopFolderPair(wxCommandEvent& event) { if (additionalFolderPairs.size() > 0) { - m_directoryLeft->SetSelection(wxNOT_FOUND); - m_directoryRight->SetSelection(wxNOT_FOUND); + const wxString leftDir = (*additionalFolderPairs.begin())->m_directoryLeft->GetValue().c_str(); + const wxString rightDir = (*additionalFolderPairs.begin())->m_directoryRight->GetValue().c_str(); - m_directoryLeft->SetValue((*additionalFolderPairs.begin())->m_directoryLeft->GetValue()); - m_directoryRight->SetValue((*additionalFolderPairs.begin())->m_directoryRight->GetValue()); + FreeFileSync::setDirectoryName(leftDir, m_directoryLeft, m_dirPickerLeft); + FreeFileSync::setDirectoryName(rightDir, m_directoryRight, m_dirPickerRight); - removeFolderPair(0); //remove first of additional folder pairs + removeAddFolderPair(0); //remove first of additional folder pairs //disable the sync button - syncPreview->enableSynchronization(false); + syncPreview.enableSynchronization(false); //clear grids currentGridData.clear(); @@ -2828,15 +3046,6 @@ void MainDialog::OnRemoveTopFolderPair(wxCommandEvent& event) } -void MainDialog::addFolderPair(const Zstring& leftDir, const Zstring& rightDir, bool addFront) -{ - std::vector newPairs; - newPairs.push_back(FolderPair(leftDir, rightDir)); - - MainDialog::addFolderPair(newPairs, addFront); -} - - void scrollToBottom(wxScrolledWindow* scrWindow) { int height = 0; @@ -2857,11 +3066,17 @@ void scrollToBottom(wxScrolledWindow* scrWindow) } +const size_t MAX_ADD_FOLDER_PAIRS = 5; + + void MainDialog::addFolderPair(const std::vector& newPairs, bool addFront) { if (newPairs.size() == 0) return; + wxWindowUpdateLocker dummy(this); //avoid display distortion + + int pairHeight = 0; for (std::vector::const_iterator i = newPairs.begin(); i != newPairs.end(); ++i) { //add new folder pair @@ -2869,124 +3084,98 @@ void MainDialog::addFolderPair(const std::vector& newPairs, bool add newPair->m_bitmap23->SetBitmap(*GlobalResources::getInstance().bitmapLink); newPair->m_bpButtonRemovePair->SetBitmapLabel(*GlobalResources::getInstance().bitmapRemoveFolderPair); + //set width of left folder panel + const int width = m_panelTopLeft->GetSize().GetWidth(); + newPair->m_panelLeft->SetMinSize(wxSize(width, -1)); + + if (addFront) { - bSizerFolderPairs->Insert(0, newPair, 0, wxEXPAND, 5); + bSizerAddFolderPairs->Insert(0, newPair, 0, wxEXPAND, 5); additionalFolderPairs.insert(additionalFolderPairs.begin(), newPair); } else { - bSizerFolderPairs->Add(newPair, 0, wxEXPAND, 5); + bSizerAddFolderPairs->Add(newPair, 0, wxEXPAND, 5); additionalFolderPairs.push_back(newPair); } - //set size of scrolled window - const wxSize pairSize = newPair->GetSize(); - - const int additionalRows = additionalFolderPairs.size(); - if (additionalRows <= 3) //up to 3 additional pairs shall be shown - m_scrolledWindowFolderPairs->SetMinSize(wxSize( -1, pairSize.GetHeight() * additionalRows)); - else //adjust scrollbars - m_scrolledWindowFolderPairs->Fit(); + //get size of scrolled window + pairHeight = newPair->GetSize().GetHeight(); //register events newPair->m_bpButtonRemovePair->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainDialog::OnRemoveFolderPair), NULL, this ); - //insert directory names if provided - newPair->m_directoryLeft->SetValue(i->leftDirectory.c_str()); - const wxString leftDirFormatted = FreeFileSync::getFormattedDirectoryName(i->leftDirectory).c_str(); - if (wxDirExists(leftDirFormatted)) - newPair->m_dirPickerLeft->SetPath(leftDirFormatted); - - newPair->m_directoryRight->SetValue(i->rightDirectory.c_str()); - const wxString rightDirFormatted = FreeFileSync::getFormattedDirectoryName(i->rightDirectory).c_str(); - if (wxDirExists(rightDirFormatted)) - newPair->m_dirPickerRight->SetPath(rightDirFormatted); + //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); } - //adapt left-shift display distortion caused by scrollbars - if (additionalFolderPairs.size() > 3 && !m_bitmapShift->IsShown()) - { - //m_scrolledWindowFolderPairs and bSizerFolderPairs need to be up to date - m_scrolledWindowFolderPairs->Layout(); - bSizer1->Layout(); - - //calculate scrollbar width - const int shiftToRight = m_scrolledWindowFolderPairs->GetSize().GetWidth() - bSizerFolderPairs->GetSize().GetWidth(); - m_bitmapShift->SetMinSize(wxSize(shiftToRight, -1)); - m_bitmapShift->Show(); - } + //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 - if (additionalFolderPairs.size() > 0) - { - m_bpButtonRemoveTopPair->Show(); - m_panelTopRight->Layout(); - } + m_bpButtonRemoveTopPair->Show(); + m_panelTopRight->Layout(); + + //update controls + m_scrolledWindowFolderPairs->Fit(); //adjust scrolled window size + m_scrolledWindowFolderPairs->Layout(); //adjust stuff inside scrolled window + bSizer1->Layout(); //scroll to the bottom of wxScrolledWindow //scrollToBottom(m_scrolledWindowFolderPairs); - - m_scrolledWindowFolderPairs->Layout(); - bSizer1->Layout(); - m_bpButtonSwapSides->Refresh(); } -void MainDialog::removeFolderPair(const int pos, bool refreshLayout) +void MainDialog::removeAddFolderPair(const int pos) { + wxWindowUpdateLocker dummy(this); //avoid display distortion + if (0 <= pos && pos < int(additionalFolderPairs.size())) { - wxSize pairSize; //remove folder pairs from window FolderPairPanel* pairToDelete = additionalFolderPairs[pos]; - pairSize = pairToDelete->GetSize(); + const int pairHeight = pairToDelete->GetSize().GetHeight(); - bSizerFolderPairs->Detach(pairToDelete); //Remove() does not work on Window*, so do it manually + bSizerAddFolderPairs->Detach(pairToDelete); //Remove() does not work on Window*, so do it manually pairToDelete->Destroy(); // - additionalFolderPairs.erase(additionalFolderPairs.begin() + pos); //remove last element in vector + additionalFolderPairs.erase(additionalFolderPairs.begin() + pos); //remove element from vector //set size of scrolled window - const int additionalRows = additionalFolderPairs.size(); - if (additionalRows <= 3) //up to 3 additional pairs shall be shown - m_scrolledWindowFolderPairs->SetMinSize(wxSize(-1, pairSize.GetHeight() * additionalRows)); - //adjust scrollbars (do not put in else clause) - m_scrolledWindowFolderPairs->Fit(); - - //adapt left-shift display distortion caused by scrollbars - if (refreshLayout) - { - if (additionalRows <= 3) - m_bitmapShift->Hide(); - - m_scrolledWindowFolderPairs->Layout(); - bSizer1->Layout(); - } + const size_t additionalRows = additionalFolderPairs.size(); + 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(); - if (refreshLayout) - m_panelTopRight->Layout(); + m_panelTopRight->Layout(); } + //update controls + m_scrolledWindowFolderPairs->Fit(); //adjust scrolled window size + m_scrolledWindowFolderPairs->Layout(); //adjust stuff inside scrolled window + bSizer1->Layout(); } } -void MainDialog::clearFolderPairs() +void MainDialog::clearAddFolderPairs() { - if (additionalFolderPairs.size() > 0) - { - for (int i = int(additionalFolderPairs.size()) - 1; i > 0; --i) - MainDialog::removeFolderPair(i, false); + wxWindowUpdateLocker dummy(this); //avoid display distortion - //refresh layout just once for improved performance! - MainDialog::removeFolderPair(0, true); - } -} + additionalFolderPairs.clear(); + bSizerAddFolderPairs->Clear(true); + + m_bpButtonRemoveTopPair->Hide(); + m_panelTopRight->Layout(); + m_scrolledWindowFolderPairs->SetMinSize(wxSize(-1, 0)); + bSizer1->Layout(); +} //######################################################################################################## @@ -3064,11 +3253,11 @@ void MainDialog::OnMenuBatchJob(wxCommandEvent& event) { //fill batch config structure xmlAccess::XmlBatchConfig batchCfg; - batchCfg.mainCfg = cfg; + batchCfg.mainCfg = currentCfg.mainCfg; batchCfg.directoryPairs = getFolderPairs(); batchCfg.silent = false; - if (ignoreErrors) + if (currentCfg.ignoreErrors) batchCfg.handleError = xmlAccess::ON_ERROR_IGNORE; else batchCfg.handleError = xmlAccess::ON_ERROR_POPUP; @@ -3099,6 +3288,11 @@ void MainDialog::OnLayoutWindowAsync(wxIdleEvent& event) //execute just once per startup! Disconnect(wxEVT_IDLE, wxIdleEventHandler(MainDialog::OnLayoutWindowAsync), NULL, this); + wxWindowUpdateLocker dummy(this); //avoid display distortion + + //adjust folder pair distortion on startup + m_scrolledWindowFolderPairs->Fit(); + Layout(); //strangely this layout call works if called in next idle event only Refresh(); } @@ -3121,13 +3315,13 @@ void MainDialog::OnMenuQuit(wxCommandEvent& event) //language selection void MainDialog::switchProgramLanguage(const int langID) { - programLanguage->setLanguage(langID); //language is a global attribute + CustomLocale::getInstance().setLanguage(langID); //language is a global attribute //create new main window and delete old one cleanUp(); //destructor's code: includes writing settings to HD //create new dialog with respect to new language - MainDialog* frame = new MainDialog(NULL, FreeFileSync::getLastConfigFile(), programLanguage, globalSettings); + MainDialog* frame = new MainDialog(NULL, wxEmptyString, globalSettings); frame->SetIcon(*GlobalResources::getInstance().programIcon); //set application icon frame->Show(); @@ -3145,20 +3339,19 @@ void MainDialog::OnMenuLanguageSwitch(wxCommandEvent& event) //######################################################################################################### - -SyncPreview::SyncPreview(MainDialog* mainDlg) : +MainDialog::SyncPreview::SyncPreview(MainDialog* mainDlg) : mainDlg_(mainDlg), syncPreviewEnabled(false), synchronizationEnabled(false) {} -bool SyncPreview::previewIsEnabled() +bool MainDialog::SyncPreview::previewIsEnabled() const { return syncPreviewEnabled; } -void SyncPreview::enablePreview(bool value) +void MainDialog::SyncPreview::enablePreview(bool value) { if (value) { @@ -3183,7 +3376,7 @@ void SyncPreview::enablePreview(bool value) } -void SyncPreview::enableSynchronization(bool value) +void MainDialog::SyncPreview::enableSynchronization(bool value) { if (value) { @@ -3200,7 +3393,7 @@ void SyncPreview::enableSynchronization(bool value) } -bool SyncPreview::synchronizationIsEnabled() +bool MainDialog::SyncPreview::synchronizationIsEnabled() const { return synchronizationEnabled; } diff --git a/ui/MainDialog.h b/ui/MainDialog.h index e8eae783..b6a49b17 100644 --- a/ui/MainDialog.h +++ b/ui/MainDialog.h @@ -11,7 +11,6 @@ #include "guiGenerated.h" #include #include "../library/processXml.h" -#include "gridView.h" #include #include @@ -22,20 +21,21 @@ class FolderPairPanel; class CustomGrid; class FFSCheckRowsEvent; class FFSSyncDirectionEvent; -class SyncPreview; class IconUpdater; +class ManualDeletionHandler; namespace FreeFileSync { class CustomLocale; + class GridView; } class MainDialog : public MainDialogGenerated { friend class CompareStatusHandler; + friend class ManualDeletionHandler; friend class MainFolderDragDrop; - friend class SyncPreview; //IDs for context menu items enum ContextIDRim //context menu for left and right grids @@ -54,7 +54,9 @@ class MainDialog : public MainDialogGenerated enum ContextIDRimLabel//context menu for column settings { CONTEXT_CUSTOMIZE_COLUMN_LEFT, - CONTEXT_CUSTOMIZE_COLUMN_RIGHT + CONTEXT_CUSTOMIZE_COLUMN_RIGHT, + CONTEXT_AUTO_ADJUST_COLUMN_LEFT, + CONTEXT_AUTO_ADJUST_COLUMN_RIGHT }; enum ContextIDMiddle//context menu for middle grid @@ -73,7 +75,6 @@ class MainDialog : public MainDialogGenerated public: MainDialog(wxFrame* frame, const wxString& cfgFileName, - FreeFileSync::CustomLocale* language, xmlAccess::XmlGlobalSettings& settings); ~MainDialog(); @@ -85,6 +86,7 @@ private: bool readConfigurationFromXml(const wxString& filename, bool programStartup = false); bool writeConfigurationToXml(const wxString& filename); xmlAccess::XmlGuiConfig getCurrentConfiguration() const; + static const wxString& lastConfigFileName(); xmlAccess::XmlGuiConfig lastConfigurationSaved; //support for: "Save changed configuration?" dialog @@ -93,16 +95,14 @@ private: void updateViewFilterButtons(); void updateFilterButton(wxBitmapButton* filterButton, bool isActive); - void updateCompareButtons(); void addFileToCfgHistory(const wxString& filename); void addLeftFolderToHistory(const wxString& leftFolder); void addRightFolderToHistory(const wxString& rightFolder); - void addFolderPair(const Zstring& leftDir, const Zstring& rightDir, bool addFront = false); void addFolderPair(const std::vector& newPairs, bool addFront = false); - void removeFolderPair(const int pos, bool refreshLayout = true); //keep it an int, allow negative values! - void clearFolderPairs(); + void removeAddFolderPair(const int pos); //keep it an int, allow negative values! + void clearAddFolderPairs(); //main method for putting gridDataView on UI: updates data respecting current view settings void updateGuiGrid(); @@ -125,6 +125,9 @@ private: void pushStatusInformation(const wxString& text); void clearStatusBar(); + void disableAllElements(); //dis-/enables all elements (except abort button) that might receive user input during long-running processes: comparison, deletion + void enableAllElements(); // + //events void onGridLeftButtonEvent( wxKeyEvent& event); void onGridRightButtonEvent( wxKeyEvent& event); @@ -160,6 +163,10 @@ private: void OnDifferentFiles( wxCommandEvent& event); void OnConflictFiles( wxCommandEvent& event); + void OnSyncCreateLeft( wxCommandEvent& event); + void OnSyncCreateRight( wxCommandEvent& event); + void OnSyncDeleteLeft( wxCommandEvent& event); + void OnSyncDeleteRight( wxCommandEvent& event); void OnSyncDirLeft( wxCommandEvent& event); void OnSyncDirRight( wxCommandEvent& event); void OnSyncDirNone( wxCommandEvent& event); @@ -177,18 +184,16 @@ private: void refreshGridAfterFilterChange(const int delay); - void onResizeMainWindow( wxEvent& event); - void OnAbortCompare( wxCommandEvent& event); + void OnResize( wxSizeEvent& event); + void OnResizeFolderPairs( wxSizeEvent& event); void OnFilterButton( wxCommandEvent& event); void OnHideFilteredButton( wxCommandEvent& event); void OnConfigureFilter( wxHyperlinkEvent& event); - void OnShowHelpDialog( wxCommandEvent& event); void OnSwapSides( wxCommandEvent& event); - void OnCompareByTimeSize( wxCommandEvent& event); - void OnCompareByContent( wxCommandEvent& event); void OnCompare( wxCommandEvent& event); void OnSwitchView( wxCommandEvent& event); void OnSyncSettings( wxCommandEvent& event); + void OnCmpSettings( wxCommandEvent& event); void OnStartSync( wxCommandEvent& event); void OnClose( wxCloseEvent& event); void OnQuit( wxCommandEvent& event); @@ -200,8 +205,6 @@ private: void OnRemoveTopFolderPair( wxCommandEvent& event); //menu events - void OnMenuSaveConfig( wxCommandEvent& event); - void OnMenuLoadConfig( wxCommandEvent& event); void OnMenuGlobalSettings( wxCommandEvent& event); void OnMenuExportFileList( wxCommandEvent& event); void OnMenuBatchJob( wxCommandEvent& event); @@ -226,11 +229,11 @@ private: FreeFileSync::FolderComparison currentGridData; //UI view of currentGridData - FreeFileSync::GridView gridDataView; + std::auto_ptr gridDataView; //------------------------------------- //functional configuration - FreeFileSync::MainConfiguration cfg; + xmlAccess::XmlGuiConfig currentCfg; //folder pairs: //m_directoryLeft, m_directoryRight @@ -241,8 +244,6 @@ private: int heightNotMaximized; int posXNotMaximized; int posYNotMaximized; - bool hideFilteredElements; - bool ignoreErrors; //------------------------------------- //convenience method to get all folder pairs (unformatted) @@ -252,8 +253,6 @@ private: //*********************************************** std::auto_ptr contextMenu; - FreeFileSync::CustomLocale* programLanguage; - //status information wxLongLong lastStatusChange; std::stack stackObjects; @@ -276,8 +275,6 @@ private: }; std::vector exFilterCandidateObj; - CompareStatusHandler* cmpStatusHandlerTmp; //used only by the abort button when comparing - bool cleanedUp; //determines if destructor code was already executed //remember last sort executed (for determination of sort order) @@ -294,27 +291,22 @@ private: #endif //encapsulation of handling of sync preview - std::auto_ptr syncPreview; -}; - - -class SyncPreview //encapsulates MainDialog functionality for synchronization preview (friend class) -{ - friend class MainDialog; - -public: - void enablePreview(bool value); - bool previewIsEnabled(); + class SyncPreview //encapsulates MainDialog functionality for synchronization preview (friend class) + { + public: + SyncPreview(MainDialog* mainDlg); - void enableSynchronization(bool value); - bool synchronizationIsEnabled(); + void enablePreview(bool value); + bool previewIsEnabled() const; -private: - SyncPreview(MainDialog* mainDlg); + void enableSynchronization(bool value); + bool synchronizationIsEnabled() const; - MainDialog* mainDlg_; - bool syncPreviewEnabled; //toggle to display configuration preview instead of comparison result - bool synchronizationEnabled; //determines whether synchronization should be allowed + private: + MainDialog* mainDlg_; + bool syncPreviewEnabled; //toggle to display configuration preview instead of comparison result + bool synchronizationEnabled; //determines whether synchronization should be allowed + } syncPreview; }; #endif // MAINDIALOG_H diff --git a/ui/SmallDialogs.cpp b/ui/SmallDialogs.cpp index 4565e16b..beb2d975 100644 --- a/ui/SmallDialogs.cpp +++ b/ui/SmallDialogs.cpp @@ -1,12 +1,16 @@ #include "smallDialogs.h" -#include "../library/globalFunctions.h" +#include "../shared/globalFunctions.h" #include "../library/resources.h" #include "../algorithm.h" +#include "../synchronization.h" #include #include "../library/customGrid.h" -#include "../library/customButton.h" +#include "../shared/customButton.h" #include "../library/statistics.h" -#include "../library/localization.h" +#include "../shared/localization.h" +#include "../shared/fileHandling.h" +#include "../library/statusHandler.h" +#include using namespace FreeFileSync; @@ -18,12 +22,11 @@ AboutDlg::AboutDlg(wxWindow* window) : AboutDlgGenerated(window) m_bitmap11->SetBitmap(*GlobalResources::getInstance().bitmapLogo); m_bitmap13->SetBitmap(*GlobalResources::getInstance().bitmapGPL); - //create language credits for (std::vector::const_iterator i = LocalizationInfo::getMapping().begin(); i != LocalizationInfo::getMapping().end(); ++i) { //flag - wxStaticBitmap* staticBitmapFlag = new wxStaticBitmap(m_scrolledWindowTranslators, wxID_ANY, *i->languageFlag, wxDefaultPosition, wxSize(-1,11), 0 ); + wxStaticBitmap* staticBitmapFlag = new wxStaticBitmap(m_scrolledWindowTranslators, wxID_ANY, GlobalResources::getInstance().getImageByName(i->languageFlag), wxDefaultPosition, wxSize(-1,11), 0 ); fgSizerTranslators->Add(staticBitmapFlag, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); //language name @@ -40,21 +43,19 @@ AboutDlg::AboutDlg(wxWindow* window) : AboutDlgGenerated(window) bSizerTranslators->Fit(m_scrolledWindowTranslators); - //build information wxString build = wxString(wxT("(")) + _("Build:") + wxT(" ") + __TDATE__; #if wxUSE_UNICODE - build+= wxT(" - Unicode)"); + build += wxT(" - Unicode)"); #else - build+= wxT(" - ANSI)"); + build += wxT(" - ANSI)"); #endif //wxUSE_UNICODE m_build->SetLabel(build); m_animationControl1->SetAnimation(*GlobalResources::getInstance().animationMoney); - m_animationControl1->Play(); //Note: The animation is created hidden(!) to not disturb constraint based window creation; - m_animationControl1->Show(); // + m_animationControl1->Play(); - m_button8->SetFocus(); + m_buttonOkay->SetFocus(); Fit(); } @@ -196,13 +197,15 @@ DeleteDialog::DeleteDialog(wxWindow* main, const FreeFileSync::FolderCompRef& rowsOnLeft, const FreeFileSync::FolderCompRef& rowsOnRight, bool& deleteOnBothSides, - bool& useRecycleBin) : + bool& useRecycleBin, + int& totalDeleteCount) : DeleteDlgGenerated(main), m_folderCmp(folderCmp), rowsToDeleteOnLeft(rowsOnLeft), rowsToDeleteOnRight(rowsOnRight), m_deleteOnBothSides(deleteOnBothSides), - m_useRecycleBin(useRecycleBin) + m_useRecycleBin(useRecycleBin), + totalDelCount(totalDeleteCount) { m_checkBoxDeleteBothSides->SetValue(deleteOnBothSides); m_checkBoxUseRecycler->SetValue(useRecycleBin); @@ -231,6 +234,7 @@ void DeleteDialog::updateTexts() 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; @@ -239,10 +243,13 @@ void DeleteDialog::updateTexts() if ( pairIndex < int(rowsToDeleteOnLeft.size()) && //just to be sure pairIndex < int(rowsToDeleteOnRight.size())) { - filesToDelete += FreeFileSync::deleteFromGridAndHDPreview(fileCmp, - rowsToDeleteOnLeft[pairIndex], - rowsToDeleteOnRight[pairIndex], - m_checkBoxDeleteBothSides->GetValue()); + const std::pair delInfo = FreeFileSync::deleteFromGridAndHDPreview(fileCmp, + rowsToDeleteOnLeft[pairIndex], + rowsToDeleteOnRight[pairIndex], + m_checkBoxDeleteBothSides->GetValue()); + + filesToDelete += delInfo.first; + totalDelCount += delInfo.second; } } m_textCtrlMessage->SetValue(filesToDelete); @@ -575,14 +582,14 @@ void CustomizeColsDlg::OnMoveDown(wxCommandEvent& event) SyncPreviewDlg::SyncPreviewDlg(wxWindow* parentWindow, const wxString& variantName, - const wxString& toCreate, - const wxString& toUpdate, - const wxString& toDelete, - const wxString& data, + const FreeFileSync::SyncStatistics& statistics, bool& dontShowAgain) : SyncPreviewDlgGenerated(parentWindow), m_dontShowAgain(dontShowAgain) { + using FreeFileSync::includeNumberSeparator; + using globalFunctions::numberToWxString; + //m_bitmapPreview->SetBitmap(*GlobalResources::getInstance().bitmapSync); m_buttonStartSync->setBitmapFront(*GlobalResources::getInstance().bitmapStartSync); m_bitmapCreate->SetBitmap(*GlobalResources::getInstance().bitmapCreate); @@ -591,10 +598,15 @@ SyncPreviewDlg::SyncPreviewDlg(wxWindow* parentWindow, m_bitmapData->SetBitmap(*GlobalResources::getInstance().bitmapData); m_staticTextVariant->SetLabel(variantName); - m_textCtrlCreate->SetValue(toCreate); - m_textCtrlUpdate->SetValue(toUpdate); - m_textCtrlDelete->SetValue(toDelete); - m_textCtrlData->SetValue(data); + m_textCtrlData->SetValue(FreeFileSync::formatFilesizeToShortString(statistics.getDataToProcess())); + + m_textCtrlCreateL->SetValue(includeNumberSeparator(numberToWxString(statistics.getCreate( true, false)))); + m_textCtrlUpdateL->SetValue(includeNumberSeparator(numberToWxString(statistics.getOverwrite(true, false)))); + m_textCtrlDeleteL->SetValue(includeNumberSeparator(numberToWxString(statistics.getDelete( true, false)))); + + m_textCtrlCreateR->SetValue(includeNumberSeparator(numberToWxString(statistics.getCreate( false, true)))); + m_textCtrlUpdateR->SetValue(includeNumberSeparator(numberToWxString(statistics.getOverwrite(false, true)))); + m_textCtrlDeleteR->SetValue(includeNumberSeparator(numberToWxString(statistics.getDelete( false, true)))); m_checkBoxDontShowAgain->SetValue(dontShowAgain); @@ -622,6 +634,60 @@ void SyncPreviewDlg::OnStartSync(wxCommandEvent& event) } +//######################################################################################## + +CompareCfgDialog::CompareCfgDialog(wxWindow* parentWindow, CompareVariant& cmpVar) : + CmpCfgDlgGenerated(parentWindow), + m_cmpVar(cmpVar) +{ + m_bpButtonHelp->SetBitmapLabel(*GlobalResources::getInstance().bitmapHelp); + + switch (cmpVar) + { + case CMP_BY_TIME_SIZE: + m_radioBtnSizeDate->SetValue(true); + m_buttonContent->SetFocus(); //set focus on the other button + break; + case CMP_BY_CONTENT: + m_radioBtnContent->SetValue(true); + m_buttonTimeSize->SetFocus(); //set focus on the other button + break; + } +} + + +void CompareCfgDialog::OnClose(wxCloseEvent& event) +{ + EndModal(0); +} + + +void CompareCfgDialog::OnCancel(wxCommandEvent& event) +{ + EndModal(0); +} + + +void CompareCfgDialog::OnTimeSize(wxCommandEvent& event) +{ + m_cmpVar = CMP_BY_TIME_SIZE; + EndModal(BUTTON_OKAY); +} + + +void CompareCfgDialog::OnContent(wxCommandEvent& event) +{ + m_cmpVar = CMP_BY_CONTENT; + EndModal(BUTTON_OKAY); +} + + +void CompareCfgDialog::OnShowHelp(wxCommandEvent& event) +{ + HelpDlg* helpDlg = new HelpDlg(this); + helpDlg->ShowModal(); +} + //######################################################################################## GlobalSettingsDlg::GlobalSettingsDlg(wxWindow* window, xmlAccess::XmlGlobalSettings& globalSettings) : @@ -634,7 +700,18 @@ GlobalSettingsDlg::GlobalSettingsDlg(wxWindow* window, xmlAccess::XmlGlobalSetti m_spinCtrlFileTimeTolerance->SetValue(globalSettings.fileTimeTolerance); m_checkBoxIgnoreOneHour->SetValue(globalSettings.ignoreOneHourDiff); - m_textCtrlFileManager->SetValue(globalSettings.gui.commandLineFileManager); + m_textCtrlCommand->SetValue(globalSettings.gui.commandLineFileManager); + + const wxString toolTip = wxString(_("This commandline will be executed on each doubleclick. 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"); + + m_staticTextCommand->SetToolTip(toolTip); + m_textCtrlCommand->SetToolTip(toolTip); + + m_buttonOkay->SetFocus(); Fit(); } @@ -646,7 +723,7 @@ void GlobalSettingsDlg::OnOkay(wxCommandEvent& event) settings.fileTimeTolerance = m_spinCtrlFileTimeTolerance->GetValue(); settings.ignoreOneHourDiff = m_checkBoxIgnoreOneHour->GetValue(); - settings.gui.commandLineFileManager = m_textCtrlFileManager->GetValue(); + settings.gui.commandLineFileManager = m_textCtrlCommand->GetValue(); EndModal(BUTTON_OKAY); } @@ -665,9 +742,9 @@ void GlobalSettingsDlg::OnDefault(wxCommandEvent& event) m_spinCtrlFileTimeTolerance->SetValue(2); m_checkBoxIgnoreOneHour->SetValue(true); #ifdef FFS_WIN - m_textCtrlFileManager->SetValue(wxT("explorer /select, %name")); + m_textCtrlCommand->SetValue(wxT("explorer /select, %name")); #elif defined FFS_LINUX - m_textCtrlFileManager->SetValue(wxT("konqueror \"%path\"")); + m_textCtrlCommand->SetValue(wxT("konqueror \"%dir\"")); #endif } @@ -713,7 +790,8 @@ void CompareStatus::init() m_gauge2->Hide(); bSizer42->Layout(); - scannedObjects = 0; + scannedObjects = 0; + currentStatusText.clear(); totalObjects = 0; totalData = 0; @@ -777,71 +855,73 @@ void CompareStatus::updateStatusPanelNow() { //static RetrieveStatistics statistic; //statistic.writeEntry(currentData, currentObjects); + { + wxWindowUpdateLocker dummy(this); //reduce display distortion - bool screenChanged = false; //avoid screen flicker by calling layout() only if necessary + bool screenChanged = false; //avoid screen flicker by calling layout() only if necessary - //remove linebreaks from currentStatusText - wxString formattedStatusText = currentStatusText.c_str(); - for (wxString::iterator i = formattedStatusText.begin(); i != formattedStatusText.end(); ++i) - if (*i == wxChar('\n')) - *i = wxChar(' '); + //remove linebreaks from currentStatusText + wxString formattedStatusText = currentStatusText.c_str(); + for (wxString::iterator i = formattedStatusText.begin(); i != formattedStatusText.end(); ++i) + if (*i == wxChar('\n')) + *i = wxChar(' '); - //status texts - if (m_textCtrlFilename->GetValue() != formattedStatusText && (screenChanged = true)) //avoid screen flicker - m_textCtrlFilename->SetValue(formattedStatusText); + //status texts + if (m_textCtrlStatus->GetValue() != formattedStatusText && (screenChanged = true)) //avoid screen flicker + m_textCtrlStatus->SetValue(formattedStatusText); - //nr of scanned objects - const wxString scannedObjTmp = globalFunctions::numberToWxString(scannedObjects); - if (m_staticTextScanned->GetLabel() != scannedObjTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextScanned->SetLabel(scannedObjTmp); + //nr of scanned objects + const wxString scannedObjTmp = globalFunctions::numberToWxString(scannedObjects); + if (m_staticTextScanned->GetLabel() != scannedObjTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextScanned->SetLabel(scannedObjTmp); - //progress indicator for "compare file content" - m_gauge2->SetValue(int(currentData.ToDouble() * scalingFactor)); + //progress indicator for "compare file content" + m_gauge2->SetValue(int(currentData.ToDouble() * scalingFactor)); - //remaining files left for file comparison - const wxString filesToCompareTmp = globalFunctions::numberToWxString(totalObjects - currentObjects); - if (m_staticTextFilesRemaining->GetLabel() != filesToCompareTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextFilesRemaining->SetLabel(filesToCompareTmp); + //remaining files left for file comparison + const wxString filesToCompareTmp = globalFunctions::numberToWxString(totalObjects - currentObjects); + if (m_staticTextFilesRemaining->GetLabel() != filesToCompareTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextFilesRemaining->SetLabel(filesToCompareTmp); - //remaining bytes left for file comparison - const wxString remainingBytesTmp = FreeFileSync::formatFilesizeToShortString(totalData - currentData); - if (m_staticTextDataRemaining->GetLabel() != remainingBytesTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextDataRemaining->SetLabel(remainingBytesTmp); + //remaining bytes left for file comparison + const wxString remainingBytesTmp = FreeFileSync::formatFilesizeToShortString(totalData - currentData); + if (m_staticTextDataRemaining->GetLabel() != remainingBytesTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextDataRemaining->SetLabel(remainingBytesTmp); - if (statistics.get()) - { - if (timeElapsed.Time() - lastStatCallSpeed >= 500) //call method every 500 ms + if (statistics.get()) { - lastStatCallSpeed = timeElapsed.Time(); + if (timeElapsed.Time() - lastStatCallSpeed >= 500) //call method every 500 ms + { + lastStatCallSpeed = timeElapsed.Time(); - statistics->addMeasurement(currentObjects, currentData.ToDouble()); + statistics->addMeasurement(currentObjects, currentData.ToDouble()); - //current speed - const wxString speedTmp = statistics->getBytesPerSecond(); - if (m_staticTextSpeed->GetLabel() != speedTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextSpeed->SetLabel(speedTmp); + //current speed + const wxString speedTmp = statistics->getBytesPerSecond(); + if (m_staticTextSpeed->GetLabel() != speedTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextSpeed->SetLabel(speedTmp); - if (timeElapsed.Time() - lastStatCallRemTime >= 2000) //call method every two seconds only - { - lastStatCallRemTime = timeElapsed.Time(); + if (timeElapsed.Time() - lastStatCallRemTime >= 2000) //call method every two seconds only + { + lastStatCallRemTime = timeElapsed.Time(); - //remaining time - const wxString timeRemainingTmp = statistics->getRemainingTime(); - if (m_staticTextTimeRemaining->GetLabel() != timeRemainingTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextTimeRemaining->SetLabel(timeRemainingTmp); + //remaining time + const wxString timeRemainingTmp = statistics->getRemainingTime(); + if (m_staticTextTimeRemaining->GetLabel() != timeRemainingTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextTimeRemaining->SetLabel(timeRemainingTmp); + } } } - } - //time elapsed - const wxString timeElapsedTmp = (wxTimeSpan::Milliseconds(timeElapsed.Time())).Format(); - if (m_staticTextTimeElapsed->GetLabel() != timeElapsedTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextTimeElapsed->SetLabel(timeElapsedTmp); - - //do the ui update - if (screenChanged) - bSizer42->Layout(); + //time elapsed + const wxString timeElapsedTmp = (wxTimeSpan::Milliseconds(timeElapsed.Time())).Format(); + if (m_staticTextTimeElapsed->GetLabel() != timeElapsedTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextTimeElapsed->SetLabel(timeElapsedTmp); + //do the ui update + if (screenChanged) + bSizer42->Layout(); + } updateUiNow(); } @@ -924,79 +1004,79 @@ void SyncStatus::setStatusText_NoUpdate(const Zstring& text) } -void SyncStatus::updateStatusDialogNow(bool flushWindowMessages) +void SyncStatus::updateStatusDialogNow() { //static RetrieveStatistics statistic; //statistic.writeEntry(currentData, currentObjects); + { + wxWindowUpdateLocker dummy(this); //reduce display distortion + bool screenChanged = false; //avoid screen flicker by calling layout() only if necessary - bool screenChanged = false; //avoid screen flicker by calling layout() only if necessary - - //progress indicator - m_gauge1->SetValue(globalFunctions::round(currentData.ToDouble() * scalingFactor)); + //progress indicator + m_gauge1->SetValue(globalFunctions::round(currentData.ToDouble() * scalingFactor)); - //status text - if (m_textCtrlInfo->GetValue() != wxString(currentStatusText.c_str()) && (screenChanged = true)) //avoid screen flicker - m_textCtrlInfo->SetValue(currentStatusText.c_str()); + //status text + if (m_textCtrlInfo->GetValue() != wxString(currentStatusText.c_str()) && (screenChanged = true)) //avoid screen flicker + m_textCtrlInfo->SetValue(currentStatusText.c_str()); - //remaining objects - const wxString remainingObjTmp = globalFunctions::numberToWxString(totalObjects - currentObjects); - if (m_staticTextRemainingObj->GetLabel() != remainingObjTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextRemainingObj->SetLabel(remainingObjTmp); + //remaining objects + const wxString remainingObjTmp = globalFunctions::numberToWxString(totalObjects - currentObjects); + if (m_staticTextRemainingObj->GetLabel() != remainingObjTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextRemainingObj->SetLabel(remainingObjTmp); - //remaining bytes left for copy - const wxString remainingBytesTmp = FreeFileSync::formatFilesizeToShortString(totalData - currentData); - if (m_staticTextDataRemaining->GetLabel() != remainingBytesTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextDataRemaining->SetLabel(remainingBytesTmp); + //remaining bytes left for copy + const wxString remainingBytesTmp = FreeFileSync::formatFilesizeToShortString(totalData - currentData); + if (m_staticTextDataRemaining->GetLabel() != remainingBytesTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextDataRemaining->SetLabel(remainingBytesTmp); - if (statistics.get()) - { - if (timeElapsed.Time() - lastStatCallSpeed >= 500) //call method every 500 ms + if (statistics.get()) { - lastStatCallSpeed = timeElapsed.Time(); + if (timeElapsed.Time() - lastStatCallSpeed >= 500) //call method every 500 ms + { + lastStatCallSpeed = timeElapsed.Time(); - statistics->addMeasurement(currentObjects, currentData.ToDouble()); + statistics->addMeasurement(currentObjects, currentData.ToDouble()); - //current speed - const wxString speedTmp = statistics->getBytesPerSecond(); - if (m_staticTextSpeed->GetLabel() != speedTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextSpeed->SetLabel(speedTmp); + //current speed + const wxString speedTmp = statistics->getBytesPerSecond(); + if (m_staticTextSpeed->GetLabel() != speedTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextSpeed->SetLabel(speedTmp); - if (timeElapsed.Time() - lastStatCallRemTime >= 2000) //call method every two seconds only - { - lastStatCallRemTime = timeElapsed.Time(); + if (timeElapsed.Time() - lastStatCallRemTime >= 2000) //call method every two seconds only + { + lastStatCallRemTime = timeElapsed.Time(); - //remaining time - const wxString timeRemainingTmp = statistics->getRemainingTime(); - if (m_staticTextTimeRemaining->GetLabel() != timeRemainingTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextTimeRemaining->SetLabel(timeRemainingTmp); + //remaining time + const wxString timeRemainingTmp = statistics->getRemainingTime(); + if (m_staticTextTimeRemaining->GetLabel() != timeRemainingTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextTimeRemaining->SetLabel(timeRemainingTmp); + } } } - } - //time elapsed - const wxString timeElapsedTmp = (wxTimeSpan::Milliseconds(timeElapsed.Time())).Format(); - if (m_staticTextTimeElapsed->GetLabel() != timeElapsedTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextTimeElapsed->SetLabel(timeElapsedTmp); + //time elapsed + const wxString timeElapsedTmp = (wxTimeSpan::Milliseconds(timeElapsed.Time())).Format(); + if (m_staticTextTimeElapsed->GetLabel() != timeElapsedTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextTimeElapsed->SetLabel(timeElapsedTmp); - //do the ui update - if (screenChanged) - { - bSizer28->Layout(); - bSizer31->Layout(); + //do the ui update + if (screenChanged) + { + bSizer28->Layout(); + bSizer31->Layout(); + } } - if (flushWindowMessages) - updateUiNow(); + updateUiNow(); //support for pause button while (processPaused && currentProcessIsRunning) { wxMilliSleep(UI_UPDATE_INTERVAL); - if (flushWindowMessages) - updateUiNow(); + updateUiNow(); } } @@ -1065,11 +1145,8 @@ void SyncStatus::processHasFinished(SyncStatusID id) //essential to call this in bSizerSpeed->Show(false); bSizerRemTime->Show(false); - //ATTENTION don't call wxAPP->Yield()! at this point in time there is a mismatch between - //gridDataView and currentGridData!! avoid grid repaint at all costs!! - - updateStatusDialogNow(false); //keep this sequence to avoid display distortion, if e.g. only 1 item is sync'ed - Layout(); // + updateStatusDialogNow(); //keep this sequence to avoid display distortion, if e.g. only 1 item is sync'ed + Layout(); // } diff --git a/ui/SmallDialogs.h b/ui/SmallDialogs.h index da627e82..f5ea53df 100644 --- a/ui/SmallDialogs.h +++ b/ui/SmallDialogs.h @@ -2,13 +2,18 @@ #define SMALLDIALOGS_H_INCLUDED #include "../structures.h" -#include "../library/statusHandler.h" #include "../library/processXml.h" #include "guiGenerated.h" #include #include class Statistics; +class StatusHandler; + +namespace FreeFileSync +{ + class SyncStatistics; +} class AboutDlg : public AboutDlgGenerated @@ -66,7 +71,8 @@ public: const FreeFileSync::FolderCompRef& rowsOnLeft, const FreeFileSync::FolderCompRef& rowsOnRight, bool& deleteOnBothSides, - bool& useRecycleBin); + bool& useRecycleBin, + int& totalDeleteCount); ~DeleteDialog() {} @@ -90,6 +96,7 @@ private: const FreeFileSync::FolderCompRef& rowsToDeleteOnRight; bool& m_deleteOnBothSides; bool& m_useRecycleBin; + int& totalDelCount; }; @@ -99,7 +106,7 @@ public: ErrorDlg(wxWindow* parentWindow, const int activeButtons, const wxString messageText, bool& ignoreNextErrors); ~ErrorDlg(); - enum + enum ReturnCodes { BUTTON_IGNORE = 1, BUTTON_RETRY = 2, @@ -122,7 +129,7 @@ public: WarningDlg(wxWindow* parentWindow, int activeButtons, const wxString messageText, bool& dontShowAgain); ~WarningDlg(); - enum + enum Response { BUTTON_IGNORE = 1, BUTTON_ABORT = 2 @@ -190,10 +197,7 @@ class SyncPreviewDlg : public SyncPreviewDlgGenerated public: SyncPreviewDlg(wxWindow* parentWindow, const wxString& variantName, - const wxString& toCreate, - const wxString& toUpdate, - const wxString& toDelete, - const wxString& data, + const FreeFileSync::SyncStatistics& statistics, bool& dontShowAgain); enum @@ -211,6 +215,27 @@ private: }; +class CompareCfgDialog : public CmpCfgDlgGenerated +{ +public: + CompareCfgDialog(wxWindow* parentWindow, FreeFileSync::CompareVariant& cmpVar); + + enum + { + BUTTON_OKAY = 10 + }; + +private: + void OnClose(wxCloseEvent& event); + void OnCancel(wxCommandEvent& event); + void OnTimeSize(wxCommandEvent& event); + void OnContent(wxCommandEvent& event); + void OnShowHelp(wxCommandEvent& event); + + FreeFileSync::CompareVariant& m_cmpVar; +}; + + class GlobalSettingsDlg : public GlobalSettingsDlgGenerated { public: @@ -287,7 +312,7 @@ public: void resetGauge(int totalObjectsToProcess, wxLongLong totalDataToProcess); void incProgressIndicator_NoUpdate(int objectsProcessed, wxLongLong dataProcessed); void setStatusText_NoUpdate(const Zstring& text); - void updateStatusDialogNow(bool flushWindowMessages = true); + void updateStatusDialogNow(); void setCurrentStatus(SyncStatusID id); void processHasFinished(SyncStatusID id); //essential to call this in StatusUpdater derived class destructor at the LATEST(!) to prevent access to currentStatusUpdater diff --git a/ui/SyncDialog.cpp b/ui/SyncDialog.cpp index 58abc753..3172a548 100644 --- a/ui/SyncDialog.cpp +++ b/ui/SyncDialog.cpp @@ -1,31 +1,37 @@ #include "syncDialog.h" -#include "../library/globalFunctions.h" +#include "../shared/globalFunctions.h" #include "../library/resources.h" #include -#include -#include -#include "../library/customButton.h" +#include "../shared/customButton.h" #include "../synchronization.h" #include "../algorithm.h" #include -#include "dragAndDrop.h" +#include "../shared/dragAndDrop.h" +#include "../shared/fileHandling.h" +#include "../shared/xmlBase.h" +#include using namespace FreeFileSync; -SyncDialog::SyncDialog(wxWindow* window, - const FolderComparison& folderCmpRef, - MainConfiguration& config, - bool& ignoreErrors) : - SyncDlgGenerated(window), +SyncCfgDialog::SyncCfgDialog(wxWindow* window, + const FolderComparison& folderCmpRef, + MainConfiguration& config, + bool& ignoreErrors) : + SyncCfgDlgGenerated(window), folderCmp(folderCmpRef), cfg(config), - m_ignoreErrors(ignoreErrors) + m_ignoreErrors(ignoreErrors), + dragDropCustomDelFolder(new DragDropOnDlg(m_panelCustomDeletionDir, m_dirPickerCustomDelFolder, m_textCtrlCustomDelFolder)) { //make working copy of mainDialog.cfg.syncConfiguration and recycler setting localSyncConfiguration = config.syncConfiguration; - m_checkBoxUseRecycler->SetValue(cfg.useRecycleBin); - m_checkBoxIgnoreErrors->SetValue(m_ignoreErrors); + + setDeletionHandling(cfg.handleDeletion); + m_textCtrlCustomDelFolder->SetValue(cfg.customDeletionDirectory); + + //error handling + setErrorHandling(m_ignoreErrors); //set sync config icons updateConfigIcons(cfg.compareVar, localSyncConfiguration); @@ -43,28 +49,30 @@ SyncDialog::SyncDialog(wxWindow* window, switch (localSyncConfiguration.getVariant()) { case SyncConfiguration::MIRROR: - m_radioBtn1->SetValue(true); //one way -> + m_radioBtn1->SetValue(true); //one way -> break; case SyncConfiguration::UPDATE: - m_radioBtnUpdate->SetValue(true); //Update -> + m_radioBtnUpdate->SetValue(true); //Update -> break; case SyncConfiguration::TWOWAY: - m_radioBtn2->SetValue(true); //two way <-> + m_radioBtn2->SetValue(true); //two way <-> break; case SyncConfiguration::CUSTOM: - m_radioBtn3->SetValue(true); //other + m_radioBtn3->SetValue(true); //other break; } + m_buttonApply->SetFocus(); + Fit(); } //################################################################################################################# -SyncDialog::~SyncDialog() {} +SyncCfgDialog::~SyncCfgDialog() {} -void SyncDialog::updateConfigIcons(const FreeFileSync::CompareVariant cmpVar, const FreeFileSync::SyncConfiguration& syncConfig) +void SyncCfgDialog::updateConfigIcons(const FreeFileSync::CompareVariant cmpVar, const FreeFileSync::SyncConfiguration& syncConfig) { updateConfigIcons(cmpVar, syncConfig, @@ -81,18 +89,18 @@ void SyncDialog::updateConfigIcons(const FreeFileSync::CompareVariant cmpVar, co } -void SyncDialog::updateConfigIcons(const CompareVariant compareVar, - const SyncConfiguration& syncConfig, - wxBitmapButton* buttonLeftOnly, - wxBitmapButton* buttonRightOnly, - wxBitmapButton* buttonLeftNewer, - wxBitmapButton* buttonRightNewer, - wxBitmapButton* buttonDifferent, - wxStaticBitmap* bitmapLeftOnly, - wxStaticBitmap* bitmapRightOnly, - wxStaticBitmap* bitmapLeftNewer, - wxStaticBitmap* bitmapRightNewer, - wxStaticBitmap* bitmapDifferent) +void SyncCfgDialog::updateConfigIcons(const CompareVariant compareVar, + const SyncConfiguration& syncConfig, + wxBitmapButton* buttonLeftOnly, + wxBitmapButton* buttonRightOnly, + wxBitmapButton* buttonLeftNewer, + wxBitmapButton* buttonRightNewer, + wxBitmapButton* buttonDifferent, + wxStaticBitmap* bitmapLeftOnly, + wxStaticBitmap* bitmapRightOnly, + wxStaticBitmap* bitmapLeftNewer, + wxStaticBitmap* bitmapRightNewer, + wxStaticBitmap* bitmapDifferent) { //display only relevant sync options switch (compareVar) @@ -127,125 +135,234 @@ void SyncDialog::updateConfigIcons(const CompareVariant compareVar, } - if (syncConfig.exLeftSideOnly == SYNC_DIR_RIGHT) + switch (syncConfig.exLeftSideOnly) { + case SYNC_DIR_RIGHT: buttonLeftOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowRightCr); buttonLeftOnly->SetToolTip(_("Copy from left to right")); - } - else if (syncConfig.exLeftSideOnly == SYNC_DIR_LEFT) - { + break; + case SYNC_DIR_LEFT: buttonLeftOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapDeleteLeft); buttonLeftOnly->SetToolTip(_("Delete files/folders existing on left side only")); - } - else if (syncConfig.exLeftSideOnly == SYNC_DIR_NONE) - { + break; + case SYNC_DIR_NONE: buttonLeftOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowNone); buttonLeftOnly->SetToolTip(_("Do nothing")); + break; } - if (syncConfig.exRightSideOnly == SYNC_DIR_RIGHT) + switch (syncConfig.exRightSideOnly) { + case SYNC_DIR_RIGHT: buttonRightOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapDeleteRight); buttonRightOnly->SetToolTip(_("Delete files/folders existing on right side only")); - } - else if (syncConfig.exRightSideOnly == SYNC_DIR_LEFT) - { + break; + case SYNC_DIR_LEFT: buttonRightOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowLeftCr); buttonRightOnly->SetToolTip(_("Copy from right to left")); - } - else if (syncConfig.exRightSideOnly == SYNC_DIR_NONE) - { + break; + case SYNC_DIR_NONE: buttonRightOnly->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowNone); buttonRightOnly->SetToolTip(_("Do nothing")); + break; } - if (syncConfig.leftNewer == SYNC_DIR_RIGHT) + switch (syncConfig.leftNewer) { + case SYNC_DIR_RIGHT: buttonLeftNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowRight); buttonLeftNewer->SetToolTip(_("Copy from left to right overwriting")); - } - else if (syncConfig.leftNewer == SYNC_DIR_LEFT) - { + break; + case SYNC_DIR_LEFT: buttonLeftNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowLeft); buttonLeftNewer->SetToolTip(_("Copy from right to left overwriting")); - } - else if (syncConfig.leftNewer == SYNC_DIR_NONE) - { + break; + case SYNC_DIR_NONE: buttonLeftNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowNone); buttonLeftNewer->SetToolTip(_("Do nothing")); + break; } - if (syncConfig.rightNewer == SYNC_DIR_RIGHT) + switch (syncConfig.rightNewer) { + case SYNC_DIR_RIGHT: buttonRightNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowRight); buttonRightNewer->SetToolTip(_("Copy from left to right overwriting")); - } - else if (syncConfig.rightNewer == SYNC_DIR_LEFT) - { + break; + case SYNC_DIR_LEFT: buttonRightNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowLeft); buttonRightNewer->SetToolTip(_("Copy from right to left overwriting")); - } - else if (syncConfig.rightNewer == SYNC_DIR_NONE) - { + break; + case SYNC_DIR_NONE: buttonRightNewer->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowNone); buttonRightNewer->SetToolTip(_("Do nothing")); + break; } - if (syncConfig.different == SYNC_DIR_RIGHT) + switch (syncConfig.different) { + case SYNC_DIR_RIGHT: buttonDifferent->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowRight); buttonDifferent->SetToolTip(_("Copy from left to right overwriting")); - } - else if (syncConfig.different == SYNC_DIR_LEFT) - { + break; + case SYNC_DIR_LEFT: buttonDifferent->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowLeft); buttonDifferent->SetToolTip(_("Copy from right to left overwriting")); - } - else if (syncConfig.different == SYNC_DIR_NONE) - { + break; + case SYNC_DIR_NONE: buttonDifferent->SetBitmapLabel(*GlobalResources::getInstance().bitmapArrowNone); buttonDifferent->SetToolTip(_("Do nothing")); + break; } } -void SyncDialog::OnClose(wxCloseEvent& event) +void SyncCfgDialog::OnClose(wxCloseEvent& event) { EndModal(0); } -void SyncDialog::OnCancel(wxCommandEvent& event) +void SyncCfgDialog::OnCancel(wxCommandEvent& event) { EndModal(0); } -void SyncDialog::OnApply(wxCommandEvent& event) +void SyncCfgDialog::OnApply(wxCommandEvent& event) { //write configuration to main dialog cfg.syncConfiguration = localSyncConfiguration; - cfg.useRecycleBin = m_checkBoxUseRecycler->GetValue(); - m_ignoreErrors = m_checkBoxIgnoreErrors->GetValue(); + cfg.handleDeletion = getDeletionHandling(); + cfg.customDeletionDirectory = m_textCtrlCustomDelFolder->GetValue(); + + m_ignoreErrors = getErrorHandling(); EndModal(BUTTON_OKAY); } -void SyncDialog::OnSelectRecycleBin(wxCommandEvent& event) +void updateToolTipErrorHandling(wxChoice* choiceHandleError, const xmlAccess::OnError value) { - if (event.IsChecked()) + switch (value) { - if (!FreeFileSync::recycleBinExists()) - { - wxMessageBox(_("It was not possible to initialize the Recycle Bin!\n\nIt's likely that you are not using Windows.\nIf you want this feature included, please contact the author. :)"), _("Error") , wxOK | wxICON_ERROR); - m_checkBoxUseRecycler->SetValue(false); - } + case xmlAccess::ON_ERROR_POPUP: + choiceHandleError->SetToolTip(_("Show popup on errors or warnings")); + break; + case xmlAccess::ON_ERROR_IGNORE: + choiceHandleError->SetToolTip(_("Hide all error and warning messages")); + break; + case xmlAccess::ON_ERROR_EXIT: + choiceHandleError->SetToolTip(_("Exit immediately and set returncode < 0")); + break; + default: + assert(false); + choiceHandleError->SetToolTip(wxEmptyString); + } +} + + +bool SyncCfgDialog::getErrorHandling() +{ + if (m_choiceHandleError->GetSelection() == 1) //Ignore errors + return true; + else + return false; // Show popup +} + + +void SyncCfgDialog::setErrorHandling(bool ignoreErrors) +{ + m_choiceHandleError->Clear(); + m_choiceHandleError->Append(_("Show popup")); + m_choiceHandleError->Append(_("Ignore errors")); + + if (ignoreErrors) + m_choiceHandleError->SetSelection(1); + else + m_choiceHandleError->SetSelection(0); + + updateToolTipErrorHandling(m_choiceHandleError, ignoreErrors ? xmlAccess::ON_ERROR_IGNORE : xmlAccess::ON_ERROR_POPUP); +} + + +void SyncCfgDialog::OnChangeErrorHandling(wxCommandEvent& event) +{ + updateToolTipErrorHandling(m_choiceHandleError, getErrorHandling() ? xmlAccess::ON_ERROR_IGNORE : xmlAccess::ON_ERROR_POPUP); +} + +//------------------- + +void updateToolTipDeletionHandling(wxChoice* choiceHandleError, wxPanel* customDir, const FreeFileSync::DeletionPolicy value) +{ + customDir->Disable(); + + switch (value) + { + case FreeFileSync::DELETE_PERMANENTLY: + choiceHandleError->SetToolTip(_("Delete or overwrite files permanently.")); + break; + + case FreeFileSync::MOVE_TO_RECYCLE_BIN: + choiceHandleError->SetToolTip(_("Use Recycle Bin when deleting or overwriting files.")); + break; + + case FreeFileSync::MOVE_TO_CUSTOM_DIRECTORY: + choiceHandleError->SetToolTip(_("Move files to a custom directory.")); + customDir->Enable(); + break; + } +} + + +FreeFileSync::DeletionPolicy SyncCfgDialog::getDeletionHandling() +{ + switch (m_choiceHandleDeletion->GetSelection()) + { + case 0: + return FreeFileSync::DELETE_PERMANENTLY; + case 1: + return FreeFileSync::MOVE_TO_RECYCLE_BIN; + case 2: + return FreeFileSync::MOVE_TO_CUSTOM_DIRECTORY; + default: + assert(false); + return FreeFileSync::MOVE_TO_RECYCLE_BIN; + } +} + + +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")); + + switch (newValue) + { + case FreeFileSync::DELETE_PERMANENTLY: + m_choiceHandleDeletion->SetSelection(0); + break; + case FreeFileSync::MOVE_TO_RECYCLE_BIN: + m_choiceHandleDeletion->SetSelection(1); + break; + case FreeFileSync::MOVE_TO_CUSTOM_DIRECTORY: + m_choiceHandleDeletion->SetSelection(2); + break; } + + updateToolTipDeletionHandling(m_choiceHandleDeletion, m_panelCustomDeletionDir, newValue); } -void SyncDialog::OnSyncLeftToRight(wxCommandEvent& event) +void SyncCfgDialog::OnChangeDeletionHandling(wxCommandEvent& event) +{ + updateToolTipDeletionHandling(m_choiceHandleDeletion, m_panelCustomDeletionDir, getDeletionHandling()); +} + + +void SyncCfgDialog::OnSyncLeftToRight(wxCommandEvent& event) { localSyncConfiguration.setVariant(SyncConfiguration::MIRROR); @@ -256,7 +373,7 @@ void SyncDialog::OnSyncLeftToRight(wxCommandEvent& event) } -void SyncDialog::OnSyncUpdate(wxCommandEvent& event) +void SyncCfgDialog::OnSyncUpdate(wxCommandEvent& event) { localSyncConfiguration.setVariant(SyncConfiguration::UPDATE); @@ -267,7 +384,7 @@ void SyncDialog::OnSyncUpdate(wxCommandEvent& event) } -void SyncDialog::OnSyncBothSides(wxCommandEvent& event) +void SyncCfgDialog::OnSyncBothSides(wxCommandEvent& event) { localSyncConfiguration.setVariant(SyncConfiguration::TWOWAY); @@ -278,20 +395,24 @@ void SyncDialog::OnSyncBothSides(wxCommandEvent& event) } -void toggleSyncDirection(SyncDirection& current) +void toggleSyncDirection(SyncDirectionCfg& current) { - if (current == SYNC_DIR_RIGHT) - current = SYNC_DIR_LEFT; - else if (current == SYNC_DIR_LEFT) - current = SYNC_DIR_NONE; - else if (current== SYNC_DIR_NONE) - current = SYNC_DIR_RIGHT; - else - assert (false); + switch (current) + { + case SYNC_DIR_CFG_RIGHT: + current = SYNC_DIR_CFG_LEFT; + break; + case SYNC_DIR_CFG_LEFT: + current = SYNC_DIR_CFG_NONE; + break; + case SYNC_DIR_CFG_NONE: + current = SYNC_DIR_CFG_RIGHT; + break; + } } -void SyncDialog::OnExLeftSideOnly( wxCommandEvent& event ) +void SyncCfgDialog::OnExLeftSideOnly( wxCommandEvent& event ) { toggleSyncDirection(localSyncConfiguration.exLeftSideOnly); updateConfigIcons(cfg.compareVar, localSyncConfiguration); @@ -300,7 +421,7 @@ void SyncDialog::OnExLeftSideOnly( wxCommandEvent& event ) } -void SyncDialog::OnExRightSideOnly( wxCommandEvent& event ) +void SyncCfgDialog::OnExRightSideOnly( wxCommandEvent& event ) { toggleSyncDirection(localSyncConfiguration.exRightSideOnly); updateConfigIcons(cfg.compareVar, localSyncConfiguration); @@ -309,7 +430,7 @@ void SyncDialog::OnExRightSideOnly( wxCommandEvent& event ) } -void SyncDialog::OnLeftNewer( wxCommandEvent& event ) +void SyncCfgDialog::OnLeftNewer( wxCommandEvent& event ) { toggleSyncDirection(localSyncConfiguration.leftNewer); updateConfigIcons(cfg.compareVar, localSyncConfiguration); @@ -318,7 +439,7 @@ void SyncDialog::OnLeftNewer( wxCommandEvent& event ) } -void SyncDialog::OnRightNewer( wxCommandEvent& event ) +void SyncCfgDialog::OnRightNewer( wxCommandEvent& event ) { toggleSyncDirection(localSyncConfiguration.rightNewer); updateConfigIcons(cfg.compareVar, localSyncConfiguration); @@ -327,7 +448,7 @@ void SyncDialog::OnRightNewer( wxCommandEvent& event ) } -void SyncDialog::OnDifferent( wxCommandEvent& event ) +void SyncCfgDialog::OnDifferent( wxCommandEvent& event ) { toggleSyncDirection(localSyncConfiguration.different); updateConfigIcons(cfg.compareVar, localSyncConfiguration); @@ -406,10 +527,18 @@ void BatchDialog::init() { //prepare drag & drop for loading of *.ffs_batch files SetDropTarget(new BatchFileDropEvent(this)); - dragDropOnLogfileDir.reset(new DragDropOnDlg(m_panelLogging, m_dirPickerLogfileDir, m_textCtrlLogfileDir)); + //support for drag and drop on main pair + dragDropOnLeft.reset( new DragDropOnDlg(m_panelLeft, m_dirPickerLeft, m_directoryLeft)); + dragDropOnRight.reset(new DragDropOnDlg(m_panelRight, m_dirPickerRight, m_directoryRight)); + + dragDropCustomDelFolder.reset(new DragDropOnDlg(m_panelCustomDeletionDir, m_dirPickerCustomDelFolder, m_textCtrlCustomDelFolder)); + + //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); @@ -418,8 +547,11 @@ void BatchDialog::init() m_bitmap8->SetBitmap(*GlobalResources::getInstance().bitmapInclude); m_bitmap9->SetBitmap(*GlobalResources::getInstance().bitmapExclude); m_bitmap27->SetBitmap(*GlobalResources::getInstance().bitmapBatch); + + m_buttonSave->SetFocus(); } +//------------------- error handling -------------------------- xmlAccess::OnError BatchDialog::getSelectionHandleError() { @@ -438,26 +570,6 @@ xmlAccess::OnError BatchDialog::getSelectionHandleError() } -void updateToolTip(wxChoice* choiceHandleError, const xmlAccess::OnError value) -{ - switch (value) - { - case xmlAccess::ON_ERROR_POPUP: - choiceHandleError->SetToolTip(_("Show popup on errors or warnings")); - break; - case xmlAccess::ON_ERROR_IGNORE: - choiceHandleError->SetToolTip(_("Hide all error and warning messages")); - break; - case xmlAccess::ON_ERROR_EXIT: - choiceHandleError->SetToolTip(_("Exit immediately and set returncode < 0")); - break; - default: - assert(false); - choiceHandleError->SetToolTip(wxEmptyString); - } -} - - void BatchDialog::setSelectionHandleError(const xmlAccess::OnError value) { m_choiceHandleError->Clear(); @@ -481,13 +593,13 @@ void BatchDialog::setSelectionHandleError(const xmlAccess::OnError value) m_choiceHandleError->SetSelection(0); } - updateToolTip(m_choiceHandleError, getSelectionHandleError()); + updateToolTipErrorHandling(m_choiceHandleError, getSelectionHandleError()); } void BatchDialog::OnChangeErrorHandling(wxCommandEvent& event) { - updateToolTip(m_choiceHandleError, getSelectionHandleError()); + updateToolTipErrorHandling(m_choiceHandleError, getSelectionHandleError()); } @@ -498,6 +610,56 @@ void BatchDialog::OnExLeftSideOnly(wxCommandEvent& event) } +//------------------- deletion handling -------------------------- + +FreeFileSync::DeletionPolicy BatchDialog::getDeletionHandling() +{ + switch (m_choiceHandleDeletion->GetSelection()) + { + case 0: + return FreeFileSync::DELETE_PERMANENTLY; + case 1: + return FreeFileSync::MOVE_TO_RECYCLE_BIN; + case 2: + return FreeFileSync::MOVE_TO_CUSTOM_DIRECTORY; + default: + assert(false); + return FreeFileSync::MOVE_TO_RECYCLE_BIN; + } +} + + +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")); + + switch (newValue) + { + case FreeFileSync::DELETE_PERMANENTLY: + m_choiceHandleDeletion->SetSelection(0); + break; + case FreeFileSync::MOVE_TO_RECYCLE_BIN: + m_choiceHandleDeletion->SetSelection(1); + break; + case FreeFileSync::MOVE_TO_CUSTOM_DIRECTORY: + m_choiceHandleDeletion->SetSelection(2); + break; + } + + updateToolTipDeletionHandling(m_choiceHandleDeletion, m_panelCustomDeletionDir, newValue); +} + + +void BatchDialog::OnChangeDeletionHandling(wxCommandEvent& event) +{ + updateToolTipDeletionHandling(m_choiceHandleDeletion, m_panelCustomDeletionDir, getDeletionHandling()); +} + + + void BatchDialog::OnExRightSideOnly(wxCommandEvent& event) { toggleSyncDirection(localSyncConfiguration.exRightSideOnly); @@ -575,19 +737,6 @@ void BatchDialog::showNotebookpage(wxWindow* page, const wxString& pageName, boo } -void BatchDialog::OnSelectRecycleBin(wxCommandEvent& event) -{ - if (m_checkBoxUseRecycler->GetValue()) - { - if (!FreeFileSync::recycleBinExists()) - { - wxMessageBox(_("It was not possible to initialize the Recycle Bin!\n\nIt's likely that you are not using Windows.\nIf you want this feature included, please contact the author. :)"), _("Error") , wxOK | wxICON_ERROR); - m_checkBoxUseRecycler->SetValue(false); - } - } -} - - CompareVariant BatchDialog::getCurrentCompareVar() { if (m_radioBtnSizeDate->GetValue()) @@ -604,24 +753,26 @@ CompareVariant BatchDialog::getCurrentCompareVar() void BatchDialog::updateConfigIcons(const FreeFileSync::CompareVariant cmpVar, const FreeFileSync::SyncConfiguration& syncConfig) { - SyncDialog::updateConfigIcons(cmpVar, - syncConfig, - m_bpButtonLeftOnly, - m_bpButtonRightOnly, - m_bpButtonLeftNewer, - m_bpButtonRightNewer, - m_bpButtonDifferent, - m_bitmapLeftOnly, - m_bitmapRightOnly, - m_bitmapLeftNewer, - m_bitmapRightNewer, - m_bitmapDifferent); + SyncCfgDialog::updateConfigIcons(cmpVar, + syncConfig, + m_bpButtonLeftOnly, + m_bpButtonRightOnly, + m_bpButtonLeftNewer, + m_bpButtonRightNewer, + m_bpButtonDifferent, + m_bitmapLeftOnly, + m_bitmapRightOnly, + m_bitmapLeftNewer, + m_bitmapRightNewer, + m_bitmapDifferent); } void BatchDialog::OnChangeCompareVar(wxCommandEvent& event) { updateConfigIcons(getCurrentCompareVar(), localSyncConfiguration); + + m_panelOverview->Layout(); //needed Fit(); } @@ -683,17 +834,12 @@ bool BatchDialog::saveBatchFile(const wxString& filename) batchCfg.mainCfg.filterIsActive = m_checkBoxFilter->GetValue(); batchCfg.mainCfg.includeFilter = m_textCtrlInclude->GetValue(); batchCfg.mainCfg.excludeFilter = m_textCtrlExclude->GetValue(); - batchCfg.mainCfg.useRecycleBin = m_checkBoxUseRecycler->GetValue(); - batchCfg.handleError = getSelectionHandleError(); + batchCfg.mainCfg.handleDeletion = getDeletionHandling(); + batchCfg.mainCfg.customDeletionDirectory = m_textCtrlCustomDelFolder->GetValue(); - for (unsigned int i = 0; i < localFolderPairs.size(); ++i) - { - FolderPair newPair; - newPair.leftDirectory = localFolderPairs[i]->m_directoryLeft->GetValue().c_str(); - newPair.rightDirectory = localFolderPairs[i]->m_directoryRight->GetValue().c_str(); + batchCfg.handleError = getSelectionHandleError(); - batchCfg.directoryPairs.push_back(newPair); - } + batchCfg.directoryPairs = getFolderPairs(); //load structure with batch settings "batchCfg" batchCfg.silent = m_checkBoxSilent->GetValue(); @@ -702,9 +848,9 @@ bool BatchDialog::saveBatchFile(const wxString& filename) //write config to XML try { - xmlAccess::writeBatchConfig(filename, batchCfg); + xmlAccess::writeBatchConfig(batchCfg, filename); } - catch (const FileError& error) + catch (const xmlAccess::XmlError& error) { wxMessageBox(error.show().c_str(), _("Error"), wxOK | wxICON_ERROR); return false; @@ -723,27 +869,35 @@ void BatchDialog::loadBatchFile(const wxString& filename) xmlAccess::XmlBatchConfig batchCfg; //structure to receive gui settings try { - batchCfg = xmlAccess::readBatchConfig(filename); + xmlAccess::readBatchConfig(filename, batchCfg); } - catch (const FileError& error) + catch (const xmlAccess::XmlError& error) { - wxMessageBox(error.show().c_str(), _("Error"), wxOK | wxICON_ERROR); - return; + if (error.getSeverity() == xmlAccess::XmlError::WARNING) + wxMessageBox(error.show(), _("Warning"), wxOK | wxICON_WARNING); + else + { + wxMessageBox(error.show(), _("Error"), wxOK | wxICON_ERROR); + return; + } } SetTitle(wxString(_("Create a batch job")) + wxT(" - ") + filename); proposedBatchFileName = filename; //may be used on next save - this->loadBatchCfg(batchCfg); } void BatchDialog::loadBatchCfg(const xmlAccess::XmlBatchConfig& batchCfg) { + wxWindowUpdateLocker dummy(this); //avoid display distortion + //make working copy of mainDialog.cfg.syncConfiguration and recycler setting localSyncConfiguration = batchCfg.mainCfg.syncConfiguration; - m_checkBoxUseRecycler->SetValue(batchCfg.mainCfg.useRecycleBin); + setDeletionHandling(batchCfg.mainCfg.handleDeletion); + m_textCtrlCustomDelFolder->SetValue(batchCfg.mainCfg.customDeletionDirectory); + setSelectionHandleError(batchCfg.handleError); switch (batchCfg.mainCfg.compareVar) @@ -766,35 +920,197 @@ void BatchDialog::loadBatchCfg(const xmlAccess::XmlBatchConfig& batchCfg) m_textCtrlLogfileDir->SetValue(batchCfg.logFileDirectory); //remove existing folder pairs - localFolderPairs.clear(); - bSizerFolderPairs->Clear(true); + FreeFileSync::setDirectoryName(wxEmptyString, m_directoryLeft, m_dirPickerLeft); + FreeFileSync::setDirectoryName(wxEmptyString, m_directoryRight, m_dirPickerRight); + clearAddFolderPairs(); //add folder pairs - int scrWindowHeight = 0; - for (std::vector::const_iterator i = batchCfg.directoryPairs.begin(); i != batchCfg.directoryPairs.end(); ++i) + if (batchCfg.directoryPairs.size() > 0) { - BatchFolderPairPanel* newPair = new BatchFolderPairPanel(m_scrolledWindow6); - newPair->m_directoryLeft->SetValue(i->leftDirectory.c_str()); - newPair->m_directoryRight->SetValue(i->rightDirectory.c_str()); + //set main folder pair + std::vector::const_iterator main = batchCfg.directoryPairs.begin(); - bSizerFolderPairs->Add( newPair, 0, wxEXPAND, 5); - localFolderPairs.push_back(newPair); + FreeFileSync::setDirectoryName(main->leftDirectory.c_str(), m_directoryLeft, m_dirPickerLeft); + FreeFileSync::setDirectoryName(main->rightDirectory.c_str(), m_directoryRight, m_dirPickerRight); - if (i == batchCfg.directoryPairs.begin()) - scrWindowHeight = newPair->GetSize().GetHeight(); + //set additional pairs + std::vector additionalPairs; //don't modify batchCfg.directoryPairs! + for (std::vector::const_iterator i = batchCfg.directoryPairs.begin() + 1; i != batchCfg.directoryPairs.end(); ++i) + additionalPairs.push_back(*i); + addFolderPair(additionalPairs); } - //set size of scrolled window - int pairCount = std::min(localFolderPairs.size(), size_t(3)); //up to 3 additional pairs shall be shown - m_scrolledWindow6->SetMinSize(wxSize( -1, scrWindowHeight * pairCount)); updateVisibleTabs(); - m_scrolledWindow6->Layout(); //needed - m_panelOverview->Layout(); //needed - Fit(); //needed + Refresh(); //needed Centre(); - m_buttonSave->SetFocus(); +} + + +void BatchDialog::OnAddFolderPair(wxCommandEvent& event) +{ + std::vector 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); +} + + +void BatchDialog::OnRemoveFolderPair(wxCommandEvent& event) +{ + //find folder pair originating the event + const wxObject* const eventObj = event.GetEventObject(); + for (std::vector::const_iterator i = additionalFolderPairs.begin(); i != additionalFolderPairs.end(); ++i) + { + if (eventObj == static_cast((*i)->m_bpButtonRemovePair)) + { + removeAddFolderPair(i - additionalFolderPairs.begin()); + return; + } + } +} + + +void BatchDialog::OnRemoveTopFolderPair(wxCommandEvent& event) +{ + if (additionalFolderPairs.size() > 0) + { + 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); + + removeAddFolderPair(0); //remove first of additional folder pairs + } +} + + +const size_t MAX_FOLDER_PAIRS = 3; + + +void BatchDialog::addFolderPair(const std::vector& newPairs, bool addFront) +{ + if (newPairs.size() == 0) + return; + + wxWindowUpdateLocker dummy(m_panelOverview); //avoid display distortion + + //add folder pairs + int pairHeight = 0; + for (std::vector::const_iterator i = newPairs.begin(); i != newPairs.end(); ++i) + { + BatchFolderPairPanel* newPair = new BatchFolderPairPanel(m_scrolledWindow6); + newPair->m_bpButtonRemovePair->SetBitmapLabel(*GlobalResources::getInstance().bitmapRemoveFolderPair); + + if (addFront) + { + bSizerAddFolderPairs->Insert(0, newPair, 0, wxEXPAND, 5); + additionalFolderPairs.insert(additionalFolderPairs.begin(), newPair); + } + else + { + bSizerAddFolderPairs->Add(newPair, 0, wxEXPAND, 5); + additionalFolderPairs.push_back(newPair); + } + + //get size of scrolled window + pairHeight = newPair->GetSize().GetHeight(); + + //register events + newPair->m_bpButtonRemovePair->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BatchDialog::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 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 + Fit(); //adapt dialog size + + //after changing folder pairs window focus is lost: results in scrolled window scrolling to top each time window is shown: we don't want this + m_bpButtonLeftOnly->SetFocus(); +} + + +void BatchDialog::removeAddFolderPair(const int pos) +{ + if (0 <= pos && pos < static_cast(additionalFolderPairs.size())) + { + wxWindowUpdateLocker dummy(m_panelOverview); //avoid display distortion + + //remove folder pairs from window + BatchFolderPairPanel* pairToDelete = additionalFolderPairs[pos]; + const int pairHeight = pairToDelete->GetSize().GetHeight(); + + bSizerAddFolderPairs->Detach(pairToDelete); //Remove() does not work on Window*, so do it manually + pairToDelete->Destroy(); // + additionalFolderPairs.erase(additionalFolderPairs.begin() + pos); //remove last element in vector + + //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)); + + 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 + + m_panelOverview->InvalidateBestSize(); //needed for Fit() to work correctly! + Fit(); //adapt dialog size + + //after changing folder pairs window focus is lost: results in scrolled window scrolling to top each time window is shown: we don't want this + m_bpButtonLeftOnly->SetFocus(); + } +} + + +void BatchDialog::clearAddFolderPairs() +{ + wxWindowUpdateLocker dummy(m_panelOverview); //avoid display distortion + + 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 BatchDialog::getFolderPairs() const +{ + std::vector output; + + //add main pair + output.push_back(FolderPair(m_directoryLeft->GetValue().c_str(), + m_directoryRight->GetValue().c_str())); + + //add additional pairs + for (std::vector::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; } diff --git a/ui/SyncDialog.h b/ui/SyncDialog.h index 940efac7..57d220d3 100644 --- a/ui/SyncDialog.h +++ b/ui/SyncDialog.h @@ -1,7 +1,6 @@ #ifndef SYNCDIALOG_H_INCLUDED #define SYNCDIALOG_H_INCLUDED -#include "../structures.h" #include "guiGenerated.h" #include "../library/processXml.h" #include @@ -15,15 +14,15 @@ namespace FreeFileSync } -class SyncDialog: public SyncDlgGenerated +class SyncCfgDialog : public SyncCfgDlgGenerated { public: - SyncDialog(wxWindow* window, - const FreeFileSync::FolderComparison& folderCmpRef, - FreeFileSync::MainConfiguration& config, - bool& ignoreErrors); + SyncCfgDialog(wxWindow* window, + const FreeFileSync::FolderComparison& folderCmpRef, + FreeFileSync::MainConfiguration& config, + bool& ignoreErrors); - ~SyncDialog(); + ~SyncCfgDialog(); enum { @@ -60,13 +59,23 @@ private: void OnCancel( wxCommandEvent& event); void OnApply( wxCommandEvent& event); - void OnSelectRecycleBin(wxCommandEvent& event); + //error handling + bool getErrorHandling(); + void setErrorHandling(bool ignoreErrors); + void OnChangeErrorHandling(wxCommandEvent& event); + + //deletion handling + FreeFileSync::DeletionPolicy getDeletionHandling(); + void setDeletionHandling(FreeFileSync::DeletionPolicy newValue); + void OnChangeDeletionHandling(wxCommandEvent& event); //temporal copy of maindialog.cfg.syncConfiguration FreeFileSync::SyncConfiguration localSyncConfiguration; const FreeFileSync::FolderComparison& folderCmp; FreeFileSync::MainConfiguration& cfg; bool& m_ignoreErrors; + + std::auto_ptr dragDropCustomDelFolder; }; @@ -87,47 +96,65 @@ public: private: void init(); - void OnChangeErrorHandling(wxCommandEvent& event); - - void OnExLeftSideOnly( wxCommandEvent& event); - void OnExRightSideOnly( wxCommandEvent& event); - void OnLeftNewer( wxCommandEvent& event); - void OnRightNewer( wxCommandEvent& event); - void OnDifferent( wxCommandEvent& event); - - void OnCheckFilter( wxCommandEvent& event); - void OnCheckLogging( wxCommandEvent& event); - void OnSelectRecycleBin(wxCommandEvent& event); - void OnChangeCompareVar(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 OnCheckFilter( wxCommandEvent& event); + virtual void OnCheckLogging( wxCommandEvent& event); + virtual void OnChangeCompareVar( wxCommandEvent& event); + virtual void OnClose( wxCloseEvent& event); + virtual void OnCancel( wxCommandEvent& event); + virtual void OnSaveBatchJob( wxCommandEvent& event); + virtual void OnLoadBatchJob( wxCommandEvent& event); + virtual void OnAddFolderPair( wxCommandEvent& event); + virtual void OnRemoveFolderPair( wxCommandEvent& event); + virtual void OnRemoveTopFolderPair(wxCommandEvent& event); + + void addFolderPair(const std::vector& newPairs, bool addFront = false); + void removeAddFolderPair(const int pos); + void clearAddFolderPairs(); + std::vector getFolderPairs() const; FreeFileSync::CompareVariant getCurrentCompareVar(); void updateConfigIcons(const FreeFileSync::CompareVariant cmpVar, const FreeFileSync::SyncConfiguration& syncConfig); - void updateVisibleTabs(); void showNotebookpage(wxWindow* page, const wxString& pageName, bool show); - void OnClose( wxCloseEvent& event); - void OnCancel( wxCommandEvent& event); - void OnSaveBatchJob( wxCommandEvent& event); - void OnLoadBatchJob( wxCommandEvent& event); - + //error handling xmlAccess::OnError getSelectionHandleError(); void setSelectionHandleError(const xmlAccess::OnError value); + void OnChangeErrorHandling(wxCommandEvent& event); + + //deletion handling + FreeFileSync::DeletionPolicy getDeletionHandling(); + void setDeletionHandling(FreeFileSync::DeletionPolicy newValue); + void OnChangeDeletionHandling(wxCommandEvent& event); + bool saveBatchFile(const wxString& filename); void loadBatchFile(const wxString& filename); void loadBatchCfg(const xmlAccess::XmlBatchConfig& batchCfg); + FreeFileSync::SyncConfiguration localSyncConfiguration; - std::vector localFolderPairs; + std::vector additionalFolderPairs; //used when saving batch file wxString proposedBatchFileName; //add drag & drop support when selecting logfile directory std::auto_ptr dragDropOnLogfileDir; + + //support for drag and drop on main pair + std::auto_ptr dragDropOnLeft; + std::auto_ptr dragDropOnRight; + + std::auto_ptr dragDropCustomDelFolder; }; #endif // SYNCDIALOG_H_INCLUDED diff --git a/ui/batchStatusHandler.cpp b/ui/batchStatusHandler.cpp index f7f0df9f..294613dd 100644 --- a/ui/batchStatusHandler.cpp +++ b/ui/batchStatusHandler.cpp @@ -1,11 +1,13 @@ #include "batchStatusHandler.h" #include "smallDialogs.h" -#include #include #include "../algorithm.h" #include #include -#include "../library/globalFunctions.h" +#include "../shared/globalFunctions.h" +#include "../shared/standardPaths.h" +#include "../shared/fileHandling.h" +#include "../library/resources.h" class LogFile @@ -14,11 +16,11 @@ public: LogFile(const wxString& logfileDirectory) { //create logfile directory - const Zstring logfileDir = logfileDirectory.empty() ? FreeFileSync::getDefaultLogDirectory().c_str() : logfileDirectory.c_str(); - if (!wxDirExists(logfileDir)) + const wxString logfileDir = logfileDirectory.empty() ? FreeFileSync::getDefaultLogDirectory() : logfileDirectory; + if (!FreeFileSync::dirExists(logfileDir)) try { - FreeFileSync::createDirectory(logfileDir, Zstring(), false); + FreeFileSync::createDirectory(logfileDir.c_str()); //create recursively if necessary } catch (FreeFileSync::FileError&) { @@ -27,9 +29,10 @@ public: } //assemble logfile name - wxString logfileName = logfileDir.c_str(); - if (!FreeFileSync::endsWithPathSeparator(logfileName.c_str())) - logfileName += FreeFileSync::FILE_NAME_SEPARATOR; + wxString logfileName = logfileDir; + if (!logfileName.empty() && logfileName.Last() != globalFunctions::FILE_NAME_SEPARATOR) + logfileName += globalFunctions::FILE_NAME_SEPARATOR; + wxString timeNow = wxDateTime::Now().FormatISOTime(); timeNow.Replace(wxT(":"), wxT("-")); logfileName += wxDateTime::Now().FormatISODate() + wxChar(' ') + timeNow + wxT(".log"); @@ -39,6 +42,7 @@ public: readyToWrite = logFile.IsOpened(); if (readyToWrite) { + //write header wxString headerLine = wxString(wxT("FreeFileSync - ")) + _("Batch execution") + wxT(" (") + _("Date") + wxT(": ") + wxDateTime::Now().FormatDate() + wxT(" ") + //"Date" is used at other places too @@ -50,8 +54,7 @@ public: logFile.Write(caption + wxChar('\n')); logFile.Write(wxString().Pad(caption.Len(), wxChar('-')) + wxChar('\n')); - write(_("Start")); //attention: write() replaces '\n'-characters - logFile.Write(wxChar('\n')); // + logFile.Write(wxString(wxT("[")) + wxDateTime::Now().FormatTime() + wxT("] ") + _("Start") + wxChar('\n') + wxChar('\n')); totalTime.Start(); //measure total time } @@ -59,48 +62,57 @@ public: ~LogFile() { - if (readyToWrite) - close(); - } + if (readyToWrite) //could be reached when creation of logfile failed + { + //write actual logfile + const std::vector& messages = errorLog.getFormattedMessages(); + for (std::vector::const_iterator i = messages.begin(); i != messages.end(); ++i) + logFile.Write(*i + wxChar('\n')); - bool isOkay() - { - return readyToWrite; - } + //write ending + logFile.Write(wxChar('\n')); - void write(const wxString& logText, const wxString& problemType = wxEmptyString) - { - logFile.Write(wxString(wxT("[")) + wxDateTime::Now().FormatTime() + wxT("] ")); + const long time = totalTime.Time(); //retrieve total time + logFile.Write(wxString(wxT("[")) + wxDateTime::Now().FormatTime() + wxT("] ")); + logFile.Write(wxString(_("Stop")) + wxT(" (") + _("Total time:") + wxT(" ") + (wxTimeSpan::Milliseconds(time)).Format() + wxT(")")); - if (problemType != wxEmptyString) - logFile.Write(problemType + wxT(": ")); + //logFile.close(); <- not needed + } + } - //remove linebreaks - wxString formattedText = logText; - for (wxString::iterator i = formattedText.begin(); i != formattedText.end(); ++i) - if (*i == wxChar('\n')) - *i = wxChar(' '); - logFile.Write(formattedText + wxChar('\n')); + bool isOkay() //has to be checked before LogFile can be used! + { + return readyToWrite; } -private: - void close() + void logError(const wxString& errorMessage) { - logFile.Write(wxChar('\n')); + errorLog.logError(errorMessage); + } - long time = totalTime.Time(); //retrieve total time + void logWarning(const wxString& warningMessage) + { + errorLog.logWarning(warningMessage); + } - logFile.Write(wxString(wxT("[")) + wxDateTime::Now().FormatTime() + wxT("] ")); - logFile.Write(wxString(_("Stop")) + wxT(" (") + _("Total time:") + wxT(" ") + (wxTimeSpan::Milliseconds(time)).Format() + wxT(")")); + void logInfo(const wxString& infoMessage) + { + errorLog.logInfo(infoMessage); + } - //logFile.close(); <- not needed + bool errorsOccured() + { + return errorLog.errorsTotal() > 0; } +private: bool readyToWrite; wxFFile logFile; wxStopWatch totalTime; + + FreeFileSync::ErrorLogging errorLog; }; @@ -109,18 +121,22 @@ class FfsTrayIcon : public wxTaskBarIcon public: FfsTrayIcon(StatusHandler* statusHandler) : m_statusHandler(statusHandler), - processPaused(false) + processPaused(false), + percentage(_("%x Percent")), + currentProcess(StatusHandler::PROCESS_NONE), + totalObjects(0), + currentObjects(0) { running.reset(new wxIcon(*GlobalResources::getInstance().programIcon)); paused.reset(new wxIcon); paused->CopyFromBitmap(*GlobalResources::getInstance().bitmapFFSPaused); - wxTaskBarIcon::SetIcon(*running); + wxTaskBarIcon::SetIcon(*running, wxT("FreeFileSync")); } ~FfsTrayIcon() {} - enum + enum Selection { CONTEXT_PAUSE, CONTEXT_ABORT, @@ -132,9 +148,9 @@ public: wxMenu* contextMenu = new wxMenu; contextMenu->Append(CONTEXT_PAUSE, _("&Pause"), wxEmptyString, wxITEM_CHECK); contextMenu->Check(CONTEXT_PAUSE, processPaused); - contextMenu->Append(CONTEXT_ABORT, _("&Abort")); - contextMenu->AppendSeparator(); contextMenu->Append(CONTEXT_ABOUT, _("&About...")); + contextMenu->AppendSeparator(); + contextMenu->Append(CONTEXT_ABORT, _("&Exit")); //event handling contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(FfsTrayIcon::onContextMenuSelection), NULL, this); @@ -143,46 +159,100 @@ public: void onContextMenuSelection(wxCommandEvent& event) { - int eventId = event.GetId(); - if (eventId == CONTEXT_PAUSE) + const Selection eventId = static_cast(event.GetId()); + switch (eventId) { + case CONTEXT_PAUSE: processPaused = !processPaused; - if (processPaused) - wxTaskBarIcon::SetIcon(*paused); - else - wxTaskBarIcon::SetIcon(*running); - } - else if (eventId == CONTEXT_ABORT) - { + break; + case CONTEXT_ABORT: processPaused = false; - wxTaskBarIcon::SetIcon(*running); m_statusHandler->requestAbortion(); - } - else if (eventId == CONTEXT_ABOUT) + break; + case CONTEXT_ABOUT: { AboutDlg* aboutDlg = new AboutDlg(NULL); aboutDlg->ShowModal(); aboutDlg->Destroy(); } + break; + } + } + + wxString calcPercentage(const wxLongLong& current, const wxLongLong& total) + { + const double ratio = current.ToDouble() * 100 / total.ToDouble(); + wxString output = percentage; + output.Replace(wxT("%x"), wxString::Format(wxT("%3.2f"), ratio), false); + return output; } void updateSysTray() { + switch (currentProcess) + { + case StatusHandler::PROCESS_SCANNING: + wxTaskBarIcon::SetIcon(*running, wxString(wxT("FreeFileSync - ")) + wxString(_("Scanning...")) + wxT(" ") + + globalFunctions::numberToWxString(currentObjects)); + break; + case StatusHandler::PROCESS_COMPARING_CONTENT: + wxTaskBarIcon::SetIcon(*running, wxString(wxT("FreeFileSync - ")) + wxString(_("Comparing content...")) + wxT(" ") + + calcPercentage(currentData, totalData)); + break; + case StatusHandler::PROCESS_SYNCHRONIZING: + wxTaskBarIcon::SetIcon(*running, wxString(wxT("FreeFileSync - ")) + wxString(_("Synchronizing...")) + wxT(" ") + + calcPercentage(currentData, totalData)); + break; + case StatusHandler::PROCESS_NONE: + assert(false); + break; + } + updateUiNow(); + //support for pause button - while (processPaused) + if (processPaused) { - wxMilliSleep(UI_UPDATE_INTERVAL); - updateUiNow(); + wxTaskBarIcon::SetIcon(*paused, wxString(wxT("FreeFileSync - ")) + _("Paused")); + while (processPaused) + { + wxMilliSleep(UI_UPDATE_INTERVAL); + updateUiNow(); + } } } + void initNewProcess(int objectsTotal, wxLongLong dataTotal, StatusHandler::Process processID) + { + totalObjects = objectsTotal; + totalData = dataTotal; + currentObjects = 0; + currentData = 0; + currentProcess = processID; + } + + void updateProcessedData(int objectsProcessed, wxLongLong dataProcessed) + { + currentObjects += objectsProcessed; + currentData += dataProcessed; + } + + private: StatusHandler* m_statusHandler; bool processPaused; std::auto_ptr running; std::auto_ptr paused; + const wxString percentage; + + //status variables + StatusHandler::Process currentProcess; + int totalObjects; + wxLongLong totalData; + int currentObjects; //each object represents a file or directory processed + wxLongLong currentData; //each data element represents one byte for proper progress indicator scaling + }; @@ -199,6 +269,7 @@ BatchStatusHandlerSilent::BatchStatusHandlerSilent(const xmlAccess::OnError hand if (!m_log->isOkay()) { //handle error: file load wxMessageBox(_("Unable to create logfile!"), _("Error"), wxOK | wxICON_ERROR); + returnValue = -7; throw FreeFileSync::AbortThisProcess(); } } @@ -206,21 +277,19 @@ BatchStatusHandlerSilent::BatchStatusHandlerSilent(const xmlAccess::OnError hand BatchStatusHandlerSilent::~BatchStatusHandlerSilent() { - unsigned int failedItems = unhandledErrors.GetCount(); - //write result if (abortIsRequested()) { returnValue = -4; - m_log->write(_("Synchronization aborted!"), _("Error")); + m_log->logError(_("Synchronization aborted!")); } - else if (failedItems) + else if (m_log->errorsOccured()) { returnValue = -5; - m_log->write(_("Synchronization completed with errors!"), _("Info")); + m_log->logInfo(_("Synchronization completed with errors!")); } else - m_log->write(_("Synchronization completed successfully!"), _("Info")); + m_log->logInfo(_("Synchronization completed successfully!")); } @@ -233,7 +302,7 @@ void BatchStatusHandlerSilent::updateStatusText(const Zstring& text) case StatusHandler::PROCESS_COMPARING_CONTENT: break; case StatusHandler::PROCESS_SYNCHRONIZING: - m_log->write(text.c_str(), _("Info")); + m_log->logInfo(text.c_str()); break; case StatusHandler::PROCESS_NONE: assert(false); @@ -246,10 +315,18 @@ inline void BatchStatusHandlerSilent::initNewProcess(int objectsTotal, wxLongLong dataTotal, StatusHandler::Process processID) { currentProcess = processID; + + trayIcon->initNewProcess(objectsTotal, dataTotal, processID); } -ErrorHandler::Response BatchStatusHandlerSilent::reportError(const Zstring& errorMessage) +void BatchStatusHandlerSilent::updateProcessedData(int objectsProcessed, wxLongLong dataProcessed) +{ + trayIcon->updateProcessedData(objectsProcessed, dataProcessed); +} + + +ErrorHandler::Response BatchStatusHandlerSilent::reportError(const wxString& errorMessage) { switch (m_handleError) { @@ -258,38 +335,34 @@ ErrorHandler::Response BatchStatusHandlerSilent::reportError(const Zstring& erro bool ignoreNextErrors = false; ErrorDlg* errorDlg = new ErrorDlg(NULL, ErrorDlg::BUTTON_IGNORE | ErrorDlg::BUTTON_RETRY | ErrorDlg::BUTTON_ABORT, - wxString(errorMessage) + wxT("\n\n") + _("Ignore this error, retry or abort?"), + errorMessage + wxT("\n\n\n") + _("Ignore this error, retry or abort?"), ignoreNextErrors); - const int rv = errorDlg->ShowModal(); + const ErrorDlg::ReturnCodes rv = static_cast(errorDlg->ShowModal()); errorDlg->Destroy(); switch (rv) { case ErrorDlg::BUTTON_IGNORE: if (ignoreNextErrors) //falsify only m_handleError = xmlAccess::ON_ERROR_IGNORE; - unhandledErrors.Add(errorMessage.c_str()); - m_log->write(errorMessage.c_str(), _("Error")); + m_log->logError(errorMessage); return ErrorHandler::IGNORE_ERROR; case ErrorDlg::BUTTON_RETRY: return ErrorHandler::RETRY; case ErrorDlg::BUTTON_ABORT: - unhandledErrors.Add(errorMessage.c_str()); - m_log->write(errorMessage.c_str(), _("Error")); + m_log->logError(errorMessage); abortThisProcess(); } } break; //used if last switch didn't find a match case xmlAccess::ON_ERROR_EXIT: //abort - unhandledErrors.Add(errorMessage.c_str()); - m_log->write(errorMessage.c_str(), _("Error")); + m_log->logError(errorMessage); abortThisProcess(); case xmlAccess::ON_ERROR_IGNORE: - unhandledErrors.Add(errorMessage.c_str()); - m_log->write(errorMessage.c_str(), _("Error")); + m_log->logError(errorMessage); return ErrorHandler::IGNORE_ERROR; } @@ -298,7 +371,7 @@ ErrorHandler::Response BatchStatusHandlerSilent::reportError(const Zstring& erro } -void BatchStatusHandlerSilent::reportFatalError(const Zstring& errorMessage) +void BatchStatusHandlerSilent::reportFatalError(const wxString& errorMessage) { switch (m_handleError) { @@ -307,7 +380,7 @@ void BatchStatusHandlerSilent::reportFatalError(const Zstring& errorMessage) bool dummy = false; ErrorDlg* errorDlg = new ErrorDlg(NULL, ErrorDlg::BUTTON_ABORT, - errorMessage.c_str(), dummy); + errorMessage, dummy); errorDlg->ShowModal(); errorDlg->Destroy(); } @@ -320,14 +393,18 @@ void BatchStatusHandlerSilent::reportFatalError(const Zstring& errorMessage) break; } - unhandledErrors.Add(errorMessage.c_str()); - m_log->write(errorMessage.c_str(), _("Error")); + m_log->logError(errorMessage); abortThisProcess(); } -void BatchStatusHandlerSilent::reportWarning(const Zstring& warningMessage, bool& dontShowAgain) +void BatchStatusHandlerSilent::reportWarning(const wxString& warningMessage, bool& warningActive) { + m_log->logWarning(warningMessage); + + if (!warningActive) + return; + switch (m_handleError) { case xmlAccess::ON_ERROR_POPUP: @@ -336,41 +413,36 @@ void BatchStatusHandlerSilent::reportWarning(const Zstring& warningMessage, bool bool dontWarnAgain = false; WarningDlg* warningDlg = new WarningDlg(NULL, WarningDlg::BUTTON_IGNORE | WarningDlg::BUTTON_ABORT, - warningMessage.c_str(), + warningMessage, dontWarnAgain); - const int rv = warningDlg->ShowModal(); + const WarningDlg::Response rv = static_cast(warningDlg->ShowModal()); warningDlg->Destroy(); switch (rv) { case WarningDlg::BUTTON_ABORT: - unhandledErrors.Add(warningMessage.c_str()); - m_log->write(warningMessage.c_str(), _("Warning")); abortThisProcess(); + break; + case WarningDlg::BUTTON_IGNORE: //no unhandled error situation! - dontShowAgain = dontWarnAgain; - m_log->write(warningMessage.c_str(), _("Warning")); - return; + warningActive = !dontWarnAgain; + break; } } break; //keep it! last switch might not find match case xmlAccess::ON_ERROR_EXIT: //abort - unhandledErrors.Add(warningMessage.c_str()); - m_log->write(warningMessage.c_str(), _("Warning")); abortThisProcess(); + break; case xmlAccess::ON_ERROR_IGNORE: //no unhandled error situation! - m_log->write(warningMessage.c_str(), _("Warning")); - return; + break; } - - assert(false); } -void BatchStatusHandlerSilent::addFinalInfo(const Zstring& infoMessage) +void BatchStatusHandlerSilent::addFinalInfo(const wxString& infoMessage) { - m_log->write(infoMessage.c_str(), _("Info")); + m_log->logInfo(infoMessage); } @@ -390,10 +462,26 @@ void BatchStatusHandlerSilent::abortThisProcess() //used by sys-tray menu BatchStatusHandlerGui::BatchStatusHandlerGui(const xmlAccess::OnError handleError, int& returnVal) : - m_handleError(handleError), + showPopups(true), 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; + } + + syncStatusFrame = new SyncStatus(this, NULL); syncStatusFrame->Show(); } @@ -401,24 +489,24 @@ BatchStatusHandlerGui::BatchStatusHandlerGui(const xmlAccess::OnError handleErro BatchStatusHandlerGui::~BatchStatusHandlerGui() { - //display result + //print the results list wxString finalMessage; - - unsigned int failedItems = unhandledErrors.GetCount(); - if (failedItems) + if (errorLog.messageCount() > 0) { - finalMessage = wxString(_("Warning: Synchronization failed for %x item(s):")) + wxT("\n\n"); - finalMessage.Replace(wxT("%x"), globalFunctions::numberToWxString(failedItems), false); - - for (unsigned int j = 0; j < failedItems; ++j) - { //remove linebreaks - wxString errorMessage = unhandledErrors[j]; - for (wxString::iterator i = errorMessage.begin(); i != errorMessage.end(); ++i) - if (*i == wxChar('\n')) - *i = wxChar(' '); + if (errorLog.errorsTotal() > 0) + { + wxString header(_("Warning: Synchronization failed for %x item(s):")); + header.Replace(wxT("%x"), globalFunctions::numberToWxString(errorLog.errorsTotal()), false); + finalMessage += header + wxT("\n\n"); + } - finalMessage += errorMessage + wxT("\n"); + const std::vector& messages = errorLog.getFormattedMessages(); + for (std::vector::const_iterator i = messages.begin(); i != messages.end(); ++i) + { + finalMessage += *i; + finalMessage += wxChar('\n'); } + finalMessage += wxT("\n"); } @@ -433,7 +521,7 @@ BatchStatusHandlerGui::~BatchStatusHandlerGui() syncStatusFrame->setStatusText_NoUpdate(finalMessage.c_str()); syncStatusFrame->processHasFinished(SyncStatus::ABORTED); //enable okay and close events } - else if (failedItems) + else if (errorLog.errorsTotal()) { returnValue = -5; finalMessage += _("Synchronization completed with errors!"); @@ -499,69 +587,57 @@ void BatchStatusHandlerGui::updateProcessedData(int objectsProcessed, wxLongLong } -ErrorHandler::Response BatchStatusHandlerGui::reportError(const Zstring& errorMessage) +ErrorHandler::Response BatchStatusHandlerGui::reportError(const wxString& errorMessage) { - //add current time before error message - const wxString errorWithTime = wxString(wxT("[")) + wxDateTime::Now().FormatTime() + wxT("] ") + errorMessage.c_str(); - - switch (m_handleError) - { - case xmlAccess::ON_ERROR_POPUP: + if (showPopups) { syncStatusFrame->updateStatusDialogNow(); bool ignoreNextErrors = false; ErrorDlg* errorDlg = new ErrorDlg(syncStatusFrame, ErrorDlg::BUTTON_IGNORE | ErrorDlg::BUTTON_RETRY | ErrorDlg::BUTTON_ABORT, - wxString(errorMessage) + wxT("\n\n") + _("Ignore this error, retry or abort?"), + errorMessage + wxT("\n\n\n") + _("Ignore this error, retry or abort?"), ignoreNextErrors); - switch (errorDlg->ShowModal()) + switch (static_cast(errorDlg->ShowModal())) { case ErrorDlg::BUTTON_IGNORE: - if (ignoreNextErrors) //falsify only - m_handleError = xmlAccess::ON_ERROR_IGNORE; - unhandledErrors.Add(errorWithTime); + showPopups = !ignoreNextErrors; + errorLog.logError(errorMessage); return ErrorHandler::IGNORE_ERROR; case ErrorDlg::BUTTON_RETRY: return ErrorHandler::RETRY; case ErrorDlg::BUTTON_ABORT: - unhandledErrors.Add(errorWithTime); + errorLog.logError(errorMessage); abortThisProcess(); } } - break; //used IF last switch didn't find a match - - case xmlAccess::ON_ERROR_EXIT: //abort - unhandledErrors.Add(errorWithTime); - abortThisProcess(); - - case xmlAccess::ON_ERROR_IGNORE: - unhandledErrors.Add(errorWithTime); + else + { + errorLog.logError(errorMessage); return ErrorHandler::IGNORE_ERROR; } assert(false); - return ErrorHandler::IGNORE_ERROR; //dummy value + errorLog.logError(errorMessage); + return ErrorHandler::IGNORE_ERROR; //dummy } -void BatchStatusHandlerGui::reportFatalError(const Zstring& errorMessage) -{ //add current time before error message - wxString errorWithTime = wxString(wxT("[")) + wxDateTime::Now().FormatTime() + wxT("] ") + errorMessage.c_str(); - - unhandledErrors.Add(errorWithTime); +void BatchStatusHandlerGui::reportFatalError(const wxString& errorMessage) +{ + errorLog.logError(errorMessage); abortThisProcess(); } -void BatchStatusHandlerGui::reportWarning(const Zstring& warningMessage, bool& dontShowAgain) -{ //add current time before warning message - wxString warningWithTime = wxString(wxT("[")) + wxDateTime::Now().FormatTime() + wxT("] ") + warningMessage.c_str(); +void BatchStatusHandlerGui::reportWarning(const wxString& warningMessage, bool& warningActive) +{ + errorLog.logWarning(warningMessage); - switch (m_handleError) - { - case xmlAccess::ON_ERROR_POPUP: - case xmlAccess::ON_ERROR_EXIT: //show popup in this case also + if (!warningActive) + return; + + if (showPopups) { syncStatusFrame->updateStatusDialogNow(); @@ -569,27 +645,21 @@ void BatchStatusHandlerGui::reportWarning(const Zstring& warningMessage, bool& d bool dontWarnAgain = false; WarningDlg* warningDlg = new WarningDlg(NULL, WarningDlg::BUTTON_IGNORE | WarningDlg::BUTTON_ABORT, - warningMessage.c_str(), + warningMessage, dontWarnAgain); - const int rv = warningDlg->ShowModal(); + const WarningDlg::Response rv = static_cast(warningDlg->ShowModal()); warningDlg->Destroy(); switch (rv) { case WarningDlg::BUTTON_IGNORE: //no unhandled error situation! - dontShowAgain = dontWarnAgain; - return; + warningActive = !dontWarnAgain; + break; + case WarningDlg::BUTTON_ABORT: - unhandledErrors.Add(warningWithTime); abortThisProcess(); + break; } } - break; //keep it! last switch might not find match - - case xmlAccess::ON_ERROR_IGNORE: //no unhandled error situation! - return; - } - - assert(false); } @@ -610,7 +680,7 @@ void BatchStatusHandlerGui::abortThisProcess() } -void BatchStatusHandlerGui::addFinalInfo(const Zstring& infoMessage) +void BatchStatusHandlerGui::addFinalInfo(const wxString& infoMessage) { - finalInfo = infoMessage.c_str(); + finalInfo = infoMessage; } diff --git a/ui/batchStatusHandler.h b/ui/batchStatusHandler.h index 7087d3c9..a075d7d7 100644 --- a/ui/batchStatusHandler.h +++ b/ui/batchStatusHandler.h @@ -4,7 +4,7 @@ #include "../library/statusHandler.h" #include #include "../library/processXml.h" -#include +#include "../library/errorLogging.h" class LogFile; class FfsTrayIcon; @@ -14,10 +14,7 @@ class SyncStatus; class BatchStatusHandler : public StatusHandler { public: - BatchStatusHandler() {} - virtual ~BatchStatusHandler() {} - - virtual void addFinalInfo(const Zstring& infoMessage) = 0; + virtual void addFinalInfo(const wxString& infoMessage) = 0; }; @@ -30,19 +27,19 @@ public: virtual void updateStatusText(const Zstring& text); virtual void initNewProcess(int objectsTotal, wxLongLong dataTotal, Process processID); - virtual void updateProcessedData(int objectsProcessed, wxLongLong dataProcessed) {} + virtual void updateProcessedData(int objectsProcessed, wxLongLong dataProcessed); virtual void forceUiRefresh(); - virtual ErrorHandler::Response reportError(const Zstring& errorMessage); - virtual void reportFatalError(const Zstring& errorMessage); - virtual void reportWarning(const Zstring& warningMessage, bool& dontShowAgain); - virtual void addFinalInfo(const Zstring& infoMessage); + virtual ErrorHandler::Response reportError(const wxString& errorMessage); + virtual void reportFatalError(const wxString& errorMessage); + virtual void reportWarning(const wxString& warningMessage, bool& warningActive); + virtual void addFinalInfo(const wxString& infoMessage); private: virtual void abortThisProcess(); xmlAccess::OnError m_handleError; - wxArrayString unhandledErrors; //list of non-resolved errors + Process currentProcess; int& returnValue; std::auto_ptr trayIcon; @@ -62,16 +59,16 @@ public: virtual void updateProcessedData(int objectsProcessed, wxLongLong dataProcessed); virtual void forceUiRefresh(); - virtual ErrorHandler::Response reportError(const Zstring& errorMessage); - virtual void reportFatalError(const Zstring& errorMessage); - virtual void reportWarning(const Zstring& warningMessage, bool& dontShowAgain); - virtual void addFinalInfo(const Zstring& infoMessage); + virtual ErrorHandler::Response reportError(const wxString& errorMessage); + virtual void reportFatalError(const wxString& errorMessage); + virtual void reportWarning(const wxString& warningMessage, bool& warningActive); + virtual void addFinalInfo(const wxString& infoMessage); private: virtual void abortThisProcess(); - xmlAccess::OnError m_handleError; - wxArrayString unhandledErrors; //list of non-resolved errors + bool showPopups; + FreeFileSync::ErrorLogging errorLog; //list of non-resolved errors and warnings Process currentProcess; int& returnValue; diff --git a/ui/checkVersion.cpp b/ui/checkVersion.cpp index 16d37036..41677094 100644 --- a/ui/checkVersion.cpp +++ b/ui/checkVersion.cpp @@ -6,7 +6,7 @@ #include #include #include -#include "../library/globalFunctions.h" +#include "../shared/globalFunctions.h" class CloseConnectionOnExit @@ -69,28 +69,19 @@ bool newerVersionExists(const wxString& onlineVersion) const wxChar VERSION_SEP = wxT('.'); - while ( currentVersionCpy.Find(VERSION_SEP) != wxNOT_FOUND && + while ( currentVersionCpy.Find(VERSION_SEP) != wxNOT_FOUND || onlineVersionCpy.Find(VERSION_SEP) != wxNOT_FOUND) { - const wxString currentMajor = currentVersionCpy.BeforeFirst(VERSION_SEP); - const wxString onlineMajor = onlineVersionCpy.BeforeFirst(VERSION_SEP); + const int currentMajor = globalFunctions::wxStringToInt(currentVersionCpy.BeforeFirst(VERSION_SEP)); //Returns the whole string if VERSION_SEP is not found. + const int onlineMajor = globalFunctions::wxStringToInt(onlineVersionCpy.BeforeFirst(VERSION_SEP)); //Returns the whole string if VERSION_SEP is not found. if (currentMajor != onlineMajor) - return globalFunctions::wxStringToInt(currentMajor) < globalFunctions::wxStringToInt(onlineMajor); + return currentMajor < onlineMajor; - currentVersionCpy = currentVersionCpy.AfterFirst(VERSION_SEP); - onlineVersionCpy = onlineVersionCpy.AfterFirst(VERSION_SEP); + currentVersionCpy = currentVersionCpy.AfterFirst(VERSION_SEP); //Returns the empty string if VERSION_SEP is not found. + onlineVersionCpy = onlineVersionCpy.AfterFirst(VERSION_SEP); //Returns the empty string if VERSION_SEP is not found. } - const wxString currentMinor = currentVersionCpy.BeforeFirst(VERSION_SEP); //Returns the whole string if VERSION_SEP is not found. - const wxString onlineMinor = onlineVersionCpy.BeforeFirst(VERSION_SEP); //Returns the whole string if VERSION_SEP is not found. - - if (currentMinor != onlineMinor) - return globalFunctions::wxStringToInt(currentMinor) < globalFunctions::wxStringToInt(onlineMinor); - - currentVersionCpy = currentVersionCpy.AfterFirst(VERSION_SEP); //Returns the empty string if VERSION_SEP is not found. - onlineVersionCpy = onlineVersionCpy.AfterFirst(VERSION_SEP); //Returns the empty string if VERSION_SEP is not found. - return globalFunctions::wxStringToInt(currentVersionCpy) < globalFunctions::wxStringToInt(onlineVersionCpy); } diff --git a/ui/gridView.cpp b/ui/gridView.cpp index aa1867fd..5406422b 100644 --- a/ui/gridView.cpp +++ b/ui/gridView.cpp @@ -1,5 +1,6 @@ #include "gridView.h" #include "sorting.h" +#include "../synchronization.h" using FreeFileSync::GridView; @@ -12,6 +13,10 @@ GridView::GridView(FreeFileSync::FolderComparison& results) : differentFilesActive(false), equalFilesActive(false), conflictFilesActive(false), + syncCreateLeftActive(false), + syncCreateRightActive(false), + syncDeleteLeftActive(false), + syncDeleteRightActive(false), syncDirLeftActive(false), syncDirRightActive(false), syncDirNoneActive(false), @@ -26,7 +31,10 @@ GridView::StatusInfo::StatusInfo() : existsDifferent(false), existsEqual(false), existsConflict(false), - + existsSyncCreateLeft(false), + existsSyncCreateRight(false), + existsSyncDeleteLeft(false), + existsSyncDeleteRight(false), existsSyncDirLeft(false), existsSyncDirRight(false), existsSyncDirNone(false), @@ -67,21 +75,37 @@ GridView::StatusInfo GridView::update_sub(const bool hideFiltered) continue; - switch (i->direction) + switch (FreeFileSync::getSyncOperation(*i)) //evaluate comparison result and sync direction { - case SYNC_DIR_LEFT: - output.existsSyncDirLeft = true; - if (!syncDirLeftActive) continue; + 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 SYNC_DIR_RIGHT: + case SO_OVERWRITE_RIGHT: output.existsSyncDirRight = true; if (!syncDirRightActive) continue; break; - case SYNC_DIR_NONE: + case SO_OVERWRITE_LEFT: + output.existsSyncDirLeft = true; + if (!syncDirLeftActive) continue; + break; + case SO_DO_NOTHING: output.existsSyncDirNone = true; if (!syncDirNoneActive) continue; break; - case SYNC_UNRESOLVED_CONFLICT: + case SO_UNRESOLVED_CONFLICT: output.existsConflict = true; if (!conflictFilesActive) continue; break; @@ -168,6 +192,33 @@ GridView::StatusInfo GridView::update(const bool hideFiltered, const bool syncPr } +void GridView::resetSettings() +{ + 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; +} + + +void GridView::clearView() +{ + refView.clear(); +} + + void GridView::viewRefToFolderRef(const std::set& viewRef, FreeFileSync::FolderCompRef& output) { output.clear(); @@ -212,24 +263,41 @@ void bubbleSort(FreeFileSync::FolderComparison& folderCmp, CompareFct compare) } +template +struct CompareGreater +{ + typedef bool (*CmpLess) (const T& a, const T& b); + CompareGreater(CmpLess cmpFct) : m_cmpFct(cmpFct) {} + + bool operator()(const T& a, const T& b) const + { + return m_cmpFct(b, a); + } +private: + CmpLess m_cmpFct; +}; + + void GridView::sortView(const SortType type, const bool onLeft, const bool ascending) { using namespace FreeFileSync; + typedef CompareGreater FolderReverse; if (type == SORT_BY_DIRECTORY) { //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); - else if (ascending && !onLeft) bubbleSort(folderCmp, sortByDirectory); - else if (!ascending && onLeft) bubbleSort(folderCmp, sortByDirectory); - else if (!ascending && !onLeft) bubbleSort(folderCmp, sortByDirectory); + if (ascending && onLeft) bubbleSort(folderCmp, sortByDirectory); + else if (ascending && !onLeft) bubbleSort(folderCmp, sortByDirectory); + else if (!ascending && onLeft) bubbleSort(folderCmp, FolderReverse(sortByDirectory)); + else if (!ascending && !onLeft) bubbleSort(folderCmp, FolderReverse(sortByDirectory)); //then sort by relative name GridView::sortView(SORT_BY_REL_NAME, onLeft, ascending); return; } + typedef CompareGreater FileReverse; for (FolderComparison::iterator j = folderCmp.begin(); j != folderCmp.end(); ++j) { @@ -238,38 +306,38 @@ void GridView::sortView(const SortType type, const bool onLeft, const bool ascen switch (type) { case SORT_BY_REL_NAME: - if ( ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByRelativeName); - else if ( ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByRelativeName); - else if (!ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByRelativeName); - else if (!ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByRelativeName); + if ( ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByRelativeName); + else if ( ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByRelativeName); + else if (!ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), FileReverse(sortByRelativeName)); + else if (!ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), FileReverse(sortByRelativeName)); break; case SORT_BY_FILENAME: - if ( ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByFileName); - else if ( ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByFileName); - else if (!ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByFileName); - else if (!ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByFileName); + if ( ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByFileName); + else if ( ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByFileName); + else if (!ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), FileReverse(sortByFileName)); + else if (!ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), FileReverse(sortByFileName)); break; case SORT_BY_FILESIZE: - if ( ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByFileSize); - else if ( ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByFileSize); - else if (!ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByFileSize); - else if (!ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByFileSize); + if ( ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByFileSize); + else if ( ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByFileSize); + else if (!ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), FileReverse(sortByFileSize)); + else if (!ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), FileReverse(sortByFileSize)); break; case SORT_BY_DATE: - if ( ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByDate); - else if ( ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByDate); - else if (!ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByDate); - else if (!ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByDate); + if ( ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByDate); + else if ( ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), sortByDate); + else if (!ascending && onLeft) std::sort(fileCmp.begin(), fileCmp.end(), FileReverse(sortByDate)); + else if (!ascending && !onLeft) std::sort(fileCmp.begin(), fileCmp.end(), FileReverse(sortByDate)); break; case SORT_BY_CMP_RESULT: - if ( ascending) std::sort(fileCmp.begin(), fileCmp.end(), sortByCmpResult); - else if (!ascending) std::sort(fileCmp.begin(), fileCmp.end(), sortByCmpResult); + 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(), sortBySyncDirection); + if ( ascending) std::sort(fileCmp.begin(), fileCmp.end(), sortBySyncDirection); + else if (!ascending) std::sort(fileCmp.begin(), fileCmp.end(), FileReverse(sortBySyncDirection)); break; - default: + case SORT_BY_DIRECTORY: assert(false); } } diff --git a/ui/gridView.h b/ui/gridView.h index b531093d..8603bbd2 100644 --- a/ui/gridView.h +++ b/ui/gridView.h @@ -15,8 +15,6 @@ namespace FreeFileSync const FileCompareLine& operator[] (unsigned row) const; FileCompareLine& operator[] (unsigned row); - //unsigned getResultsIndex(const unsigned viewIndex); //convert index on GridView to index on FolderComparison - unsigned int elementsOnView() const; //only the currently visible elements bool refGridIsEmpty() const; @@ -38,6 +36,10 @@ namespace FreeFileSync bool existsEqual; bool existsConflict; + bool existsSyncCreateLeft; + bool existsSyncCreateRight; + bool existsSyncDeleteLeft; + bool existsSyncDeleteRight; bool existsSyncDirLeft; bool existsSyncDirRight; bool existsSyncDirNone; @@ -55,6 +57,8 @@ namespace FreeFileSync 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; @@ -65,10 +69,15 @@ namespace FreeFileSync bool equalFilesActive; bool conflictFilesActive; //sync preview + bool syncCreateLeftActive; + bool syncCreateRightActive; + bool syncDeleteLeftActive; + bool syncDeleteRightActive; bool syncDirLeftActive; bool syncDirRightActive; bool syncDirNoneActive; + void resetSettings(); //sorting... enum SortType diff --git a/ui/guiGenerated.cpp b/ui/guiGenerated.cpp index de21b0f8..a3db4dd8 100644 --- a/ui/guiGenerated.cpp +++ b/ui/guiGenerated.cpp @@ -5,8 +5,8 @@ // PLEASE DO "NOT" EDIT THIS FILE! /////////////////////////////////////////////////////////////////////////// -#include "../library/customButton.h" #include "../library/customGrid.h" +#include "../shared/customButton.h" #include "guiGenerated.h" @@ -87,60 +87,48 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer6->Add( 15, 0, 0, wxALIGN_CENTER_VERTICAL, 5 ); + wxFlexGridSizer* fgSizer121; + fgSizer121 = new wxFlexGridSizer( 2, 2, 0, 0 ); + fgSizer121->SetFlexibleDirection( wxBOTH ); + fgSizer121->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_staticTextCmpVariant = new wxStaticText( m_panel71, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextCmpVariant->Wrap( -1 ); + m_staticTextCmpVariant->SetFont( wxFont( 8, 74, 90, 92, false, wxT("Arial") ) ); + m_staticTextCmpVariant->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) ); + + fgSizer121->Add( m_staticTextCmpVariant, 1, wxALIGN_CENTER_HORIZONTAL, 5 ); + + + fgSizer121->Add( 0, 0, 1, 0, 5 ); + wxBoxSizer* bSizer30; bSizer30 = new wxBoxSizer( wxHORIZONTAL ); - m_buttonCompare = new wxButtonWithImage( m_panel71, wxID_OK, _("Compare"), wxDefaultPosition, wxSize( 180,40 ), 0 ); + m_buttonCompare = new wxButtonWithImage( m_panel71, wxID_OK, _("Compare"), wxDefaultPosition, wxSize( 180,42 ), 0 ); m_buttonCompare->SetDefault(); m_buttonCompare->SetFont( wxFont( 14, 74, 90, 92, false, wxT("Arial Black") ) ); m_buttonCompare->SetToolTip( _("Compare both sides") ); - bSizer30->Add( m_buttonCompare, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + bSizer30->Add( m_buttonCompare, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); - m_buttonAbort = new wxButton( m_panel71, wxID_CANCEL, _("&Abort"), wxDefaultPosition, wxSize( 180,40 ), 0 ); + m_buttonAbort = new wxButton( m_panel71, wxID_CANCEL, _("&Abort"), wxDefaultPosition, wxSize( 180,42 ), 0 ); m_buttonAbort->SetFont( wxFont( 14, 74, 90, 92, false, wxT("Tahoma") ) ); m_buttonAbort->Enable( false ); m_buttonAbort->Hide(); - bSizer30->Add( m_buttonAbort, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxRIGHT, 5 ); + bSizer30->Add( m_buttonAbort, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - bSizer6->Add( bSizer30, 0, wxALIGN_CENTER_VERTICAL, 5 ); + fgSizer121->Add( bSizer30, 0, wxALIGN_CENTER_VERTICAL, 5 ); - wxBoxSizer* bSizer55; - bSizer55 = new wxBoxSizer( wxVERTICAL ); + m_bpButtonCmpConfig = new wxBitmapButton( m_panel71, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,42 ), wxBU_AUTODRAW ); + m_bpButtonCmpConfig->SetToolTip( _("Comparison settings") ); - wxStaticBoxSizer* sbSizer6; - sbSizer6 = new wxStaticBoxSizer( new wxStaticBox( m_panel71, wxID_ANY, _("Compare by...") ), wxHORIZONTAL ); + m_bpButtonCmpConfig->SetToolTip( _("Comparison settings") ); - wxBoxSizer* bSizer45; - bSizer45 = new wxBoxSizer( wxVERTICAL ); + fgSizer121->Add( m_bpButtonCmpConfig, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 3 ); - m_radioBtnSizeDate = new wxRadioButton( m_panel71, wxID_ANY, _("File size and date"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP ); - m_radioBtnSizeDate->SetValue( true ); - m_radioBtnSizeDate->SetToolTip( _("Files are found equal if\n - filesize\n - last write time and date\nare the same.") ); - - bSizer45->Add( m_radioBtnSizeDate, 0, 0, 5 ); - - m_radioBtnContent = new wxRadioButton( m_panel71, wxID_ANY, _("File content"), wxDefaultPosition, wxDefaultSize, 0 ); - m_radioBtnContent->SetToolTip( _("Files are found equal if\n - file content\nis the same.") ); - - bSizer45->Add( m_radioBtnContent, 0, wxTOP, 5 ); - - sbSizer6->Add( bSizer45, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - m_bpButton14 = new wxBitmapButton( m_panel71, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); - m_bpButton14->SetToolTip( _("Help") ); - - m_bpButton14->SetToolTip( _("Help") ); - - sbSizer6->Add( m_bpButton14, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - - bSizer55->Add( sbSizer6, 0, wxALIGN_CENTER_VERTICAL, 2 ); - - - bSizer55->Add( 0, 4, 0, 0, 5 ); - - bSizer6->Add( bSizer55, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer6->Add( fgSizer121, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 ); bSizer6->Add( 0, 0, 1, 0, 5 ); @@ -153,27 +141,27 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const fgSizer12->Add( 0, 0, 1, wxEXPAND, 5 ); - m_staticTextVariant = new wxStaticText( m_panel71, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextVariant->Wrap( -1 ); - m_staticTextVariant->SetFont( wxFont( 8, 74, 90, 92, false, wxT("Arial") ) ); - m_staticTextVariant->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) ); + m_staticTextSyncVariant = new wxStaticText( m_panel71, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextSyncVariant->Wrap( -1 ); + m_staticTextSyncVariant->SetFont( wxFont( 8, 74, 90, 92, false, wxT("Arial") ) ); + m_staticTextSyncVariant->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) ); - fgSizer12->Add( m_staticTextVariant, 1, wxALIGN_CENTER_HORIZONTAL, 5 ); + fgSizer12->Add( m_staticTextSyncVariant, 1, wxALIGN_CENTER_HORIZONTAL, 5 ); - m_bpButtonSyncConfig = new wxBitmapButton( m_panel71, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,40 ), wxBU_AUTODRAW ); + m_bpButtonSyncConfig = new wxBitmapButton( m_panel71, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,42 ), wxBU_AUTODRAW ); m_bpButtonSyncConfig->SetToolTip( _("Synchronization settings") ); m_bpButtonSyncConfig->SetToolTip( _("Synchronization settings") ); fgSizer12->Add( m_bpButtonSyncConfig, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3 ); - m_buttonStartSync = new wxButtonWithImage( m_panel71, wxID_ANY, _("Synchronize..."), wxDefaultPosition, wxSize( -1,40 ), 0 ); + m_buttonStartSync = new wxButtonWithImage( m_panel71, wxID_ANY, _("Synchronize..."), wxDefaultPosition, wxSize( -1,42 ), 0 ); m_buttonStartSync->SetFont( wxFont( 14, 74, 90, 92, false, wxT("Arial Black") ) ); m_buttonStartSync->SetToolTip( _("Start synchronization") ); fgSizer12->Add( m_buttonStartSync, 0, wxALIGN_CENTER_VERTICAL, 5 ); - bSizer6->Add( fgSizer12, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer6->Add( fgSizer12, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 ); bSizer6->Add( 15, 0, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -195,7 +183,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_directoryLeft = new wxComboBox( m_panelTopLeft, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); sbSizer2->Add( m_directoryLeft, 1, wxALIGN_CENTER_VERTICAL, 5 ); - m_dirPickerLeft = new wxDirPickerCtrl( m_panelTopLeft, wxID_ANY, wxEmptyString, _("Select a folder"), wxDefaultPosition, wxDefaultSize, wxDIRP_DIR_MUST_EXIST ); + m_dirPickerLeft = new wxDirPickerCtrl( m_panelTopLeft, wxID_ANY, wxEmptyString, _("Select a folder"), wxDefaultPosition, wxDefaultSize, 0 ); m_dirPickerLeft->SetToolTip( _("Select a folder") ); sbSizer2->Add( m_dirPickerLeft, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -237,39 +225,34 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const wxBoxSizer* bSizer77; bSizer77 = new wxBoxSizer( wxHORIZONTAL ); - wxBoxSizer* bSizer781; - bSizer781 = new wxBoxSizer( wxVERTICAL ); + wxStaticBoxSizer* sbSizer3; + sbSizer3 = new wxStaticBoxSizer( new wxStaticBox( m_panelTopRight, wxID_ANY, _("Drag && drop") ), wxHORIZONTAL ); m_bpButtonAddPair = new wxBitmapButton( m_panelTopRight, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 19,21 ), wxBU_AUTODRAW ); m_bpButtonAddPair->SetToolTip( _("Add folder pair") ); m_bpButtonAddPair->SetToolTip( _("Add folder pair") ); - bSizer781->Add( m_bpButtonAddPair, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP, 3 ); + 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") ); - bSizer781->Add( m_bpButtonRemoveTopPair, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); - - bSizer77->Add( bSizer781, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - - wxStaticBoxSizer* sbSizer3; - sbSizer3 = new wxStaticBoxSizer( new wxStaticBox( m_panelTopRight, wxID_ANY, _("Drag && drop") ), wxHORIZONTAL ); + 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 ); - m_dirPickerRight = new wxDirPickerCtrl( m_panelTopRight, wxID_ANY, wxEmptyString, _("Select a folder"), wxDefaultPosition, wxDefaultSize, wxDIRP_DIR_MUST_EXIST ); + m_dirPickerRight = new wxDirPickerCtrl( m_panelTopRight, wxID_ANY, wxEmptyString, _("Select a folder"), wxDefaultPosition, wxDefaultSize, 0 ); m_dirPickerRight->SetToolTip( _("Select a folder") ); sbSizer3->Add( m_dirPickerRight, 0, wxALIGN_CENTER_VERTICAL, 5 ); - bSizer77->Add( sbSizer3, 1, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 3 ); + bSizer77->Add( sbSizer3, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 3 ); - bSizer94->Add( bSizer77, 0, wxEXPAND, 5 ); + bSizer94->Add( bSizer77, 0, wxEXPAND|wxLEFT, 3 ); m_panelTopRight->SetSizer( bSizer94 ); m_panelTopRight->Layout(); @@ -278,26 +261,16 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer1->Add( bSizer91, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 ); - bSizer106 = new wxBoxSizer( wxHORIZONTAL ); - - m_bitmapShift = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_bitmapShift->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) ); - m_bitmapShift->Hide(); - - bSizer106->Add( m_bitmapShift, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - m_scrolledWindowFolderPairs = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), wxHSCROLL|wxVSCROLL ); m_scrolledWindowFolderPairs->SetScrollRate( 5, 5 ); m_scrolledWindowFolderPairs->SetMinSize( wxSize( -1,0 ) ); - bSizerFolderPairs = new wxBoxSizer( wxVERTICAL ); + bSizerAddFolderPairs = new wxBoxSizer( wxVERTICAL ); - m_scrolledWindowFolderPairs->SetSizer( bSizerFolderPairs ); + m_scrolledWindowFolderPairs->SetSizer( bSizerAddFolderPairs ); m_scrolledWindowFolderPairs->Layout(); - bSizerFolderPairs->Fit( m_scrolledWindowFolderPairs ); - bSizer106->Add( m_scrolledWindowFolderPairs, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - bSizer1->Add( bSizer106, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + bSizerAddFolderPairs->Fit( m_scrolledWindowFolderPairs ); + bSizer1->Add( m_scrolledWindowFolderPairs, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); wxBoxSizer* bSizer2; bSizer2 = new wxBoxSizer( wxHORIZONTAL ); @@ -411,14 +384,14 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer1->Add( bSizer2, 1, wxEXPAND, 5 ); - wxPanel* m_panel4; - m_panel4 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxPanel* m_panelBottom; + m_panelBottom = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); bSizer3 = new wxBoxSizer( wxHORIZONTAL ); wxBoxSizer* bSizer120; bSizer120 = new wxBoxSizer( wxVERTICAL ); - m_notebookBottomLeft = new wxNotebook( m_panel4, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + m_notebookBottomLeft = new wxNotebook( m_panelBottom, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); m_panel30 = new wxPanel( m_notebookBottomLeft, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bSizer139; bSizer139 = new wxBoxSizer( wxHORIZONTAL ); @@ -481,7 +454,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer3->Add( bSizer120, 1, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 ); - m_panel112 = new wxPanel( m_panel4, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_panel112 = new wxPanel( m_panelBottom, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bSizer64; bSizer64 = new wxBoxSizer( wxVERTICAL ); @@ -510,15 +483,27 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_bpButtonRightOnly = new wxBitmapButton( 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 ); + 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_bpButtonSyncDeleteLeft = new wxBitmapButton( 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 ); sbSizer31->Add( m_bpButtonSyncDirNone, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_bpButtonSyncDeleteRight = new wxBitmapButton( 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_bpButtonSyncCreateRight = new wxBitmapButton( 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 ); sbSizer31->Add( m_bpButtonConflict, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); @@ -537,7 +522,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizerBottomRight->Add( 5, 0, 1, 0, 5 ); - m_panelSyncPreview = new wxPanel( m_panel4, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_panelSyncPreview = new wxPanel( m_panelBottom, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bSizer121; bSizer121 = new wxBoxSizer( wxVERTICAL ); @@ -613,7 +598,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer121->Fit( m_panelSyncPreview ); bSizerBottomRight->Add( m_panelSyncPreview, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_bpButton10 = new wxBitmapButton( m_panel4, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 50,50 ), wxBU_AUTODRAW ); + m_bpButton10 = new wxBitmapButton( m_panelBottom, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 50,50 ), wxBU_AUTODRAW ); m_bpButton10->SetToolTip( _("Quit") ); m_bpButton10->SetToolTip( _("Quit") ); @@ -622,10 +607,10 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer3->Add( bSizerBottomRight, 1, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 ); - m_panel4->SetSizer( bSizer3 ); - m_panel4->Layout(); - bSizer3->Fit( m_panel4 ); - bSizer1->Add( m_panel4, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + m_panelBottom->SetSizer( bSizer3 ); + m_panelBottom->Layout(); + bSizer3->Fit( m_panelBottom ); + bSizer1->Add( m_panelBottom, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); m_panel7 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSTATIC_BORDER|wxTAB_TRAVERSAL ); wxBoxSizer* bSizer451; @@ -705,8 +690,8 @@ 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::OnMenuSaveConfig ) ); - this->Connect( m_menuItem13->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuLoadConfig ) ); + 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_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 ) ); @@ -714,10 +699,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const this->Connect( m_menuItemCheckVer->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuCheckVersion ) ); this->Connect( m_menuItemAbout->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuAbout ) ); m_buttonCompare->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnCompare ), NULL, this ); - m_buttonAbort->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnAbortCompare ), NULL, this ); - m_radioBtnSizeDate->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnCompareByTimeSize ), NULL, this ); - m_radioBtnContent->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnCompareByContent ), NULL, this ); - m_bpButton14->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnShowHelpDialog ), NULL, this ); + m_bpButtonCmpConfig->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnCmpSettings ), NULL, this ); m_bpButtonSyncConfig->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncSettings ), NULL, this ); m_buttonStartSync->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnStartSync ), NULL, this ); m_directoryLeft->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( MainDialogGenerated::OnFolderHistoryKeyEvent ), NULL, this ); @@ -751,9 +733,13 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_bpButtonDifferent->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnDifferentFiles ), NULL, this ); 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_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_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 ); } @@ -765,8 +751,8 @@ 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::OnMenuSaveConfig ) ); - this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuLoadConfig ) ); + 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 ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuGlobalSettings ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuBatchJob ) ); @@ -774,10 +760,7 @@ MainDialogGenerated::~MainDialogGenerated() this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuCheckVersion ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuAbout ) ); m_buttonCompare->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnCompare ), NULL, this ); - m_buttonAbort->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnAbortCompare ), NULL, this ); - m_radioBtnSizeDate->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnCompareByTimeSize ), NULL, this ); - m_radioBtnContent->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnCompareByContent ), NULL, this ); - m_bpButton14->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnShowHelpDialog ), NULL, this ); + m_bpButtonCmpConfig->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnCmpSettings ), NULL, this ); m_bpButtonSyncConfig->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncSettings ), NULL, this ); m_buttonStartSync->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnStartSync ), NULL, this ); m_directoryLeft->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( MainDialogGenerated::OnFolderHistoryKeyEvent ), NULL, this ); @@ -811,9 +794,13 @@ MainDialogGenerated::~MainDialogGenerated() m_bpButtonDifferent->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnDifferentFiles ), NULL, this ); 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_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_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 ); } @@ -824,21 +811,21 @@ FolderPairGenerated::FolderPairGenerated( wxWindow* parent, wxWindowID id, const bSizer74 = new wxBoxSizer( wxHORIZONTAL ); m_panelLeft = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - wxStaticBoxSizer* sbSizer21; - sbSizer21 = new wxStaticBoxSizer( new wxStaticBox( m_panelLeft, wxID_ANY, wxEmptyString ), wxHORIZONTAL ); + wxBoxSizer* bSizer134; + bSizer134 = new wxBoxSizer( wxHORIZONTAL ); m_directoryLeft = new wxTextCtrl( m_panelLeft, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - sbSizer21->Add( m_directoryLeft, 1, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer134->Add( m_directoryLeft, 1, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); m_dirPickerLeft = new wxDirPickerCtrl( m_panelLeft, wxID_ANY, wxEmptyString, _("Select a folder"), wxDefaultPosition, wxDefaultSize, 0 ); m_dirPickerLeft->SetToolTip( _("Select a folder") ); - sbSizer21->Add( m_dirPickerLeft, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer134->Add( m_dirPickerLeft, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - m_panelLeft->SetSizer( sbSizer21 ); + m_panelLeft->SetSizer( bSizer134 ); m_panelLeft->Layout(); - sbSizer21->Fit( m_panelLeft ); - bSizer74->Add( m_panelLeft, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + bSizer134->Fit( m_panelLeft ); + bSizer74->Add( m_panelLeft, 0, wxALIGN_CENTER_VERTICAL, 5 ); m_panel20 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); m_panel20->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_APPWORKSPACE ) ); @@ -847,13 +834,13 @@ FolderPairGenerated::FolderPairGenerated( wxWindow* parent, wxWindowID id, const bSizer95 = new wxBoxSizer( wxHORIZONTAL ); m_panel21 = new wxPanel( m_panel20, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - m_panel21->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) ); + m_panel21->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); wxBoxSizer* bSizer96; bSizer96 = new wxBoxSizer( wxVERTICAL ); - bSizer96->Add( 0, 15, 0, 0, 5 ); + bSizer96->Add( 0, 5, 0, 0, 5 ); m_bitmap23 = new wxStaticBitmap( m_panel21, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 44,17 ), 0 ); m_bitmap23->SetToolTip( _("Folder pair") ); @@ -871,33 +858,28 @@ FolderPairGenerated::FolderPairGenerated( wxWindow* parent, wxWindowID id, const bSizer74->Add( m_panel20, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_panelRight = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - wxBoxSizer* bSizer105; - bSizer105 = new wxBoxSizer( wxHORIZONTAL ); + wxBoxSizer* bSizer135; + bSizer135 = new wxBoxSizer( wxHORIZONTAL ); m_bpButtonRemovePair = new wxBitmapButton( m_panelRight, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 19,21 ), wxBU_AUTODRAW ); m_bpButtonRemovePair->SetToolTip( _("Remove folder pair") ); m_bpButtonRemovePair->SetToolTip( _("Remove folder pair") ); - bSizer105->Add( m_bpButtonRemovePair, 0, wxALIGN_CENTER_VERTICAL|wxTOP, 5 ); - - wxStaticBoxSizer* sbSizer23; - sbSizer23 = new wxStaticBoxSizer( new wxStaticBox( m_panelRight, wxID_ANY, wxEmptyString ), wxHORIZONTAL ); + bSizer135->Add( m_bpButtonRemovePair, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); m_directoryRight = new wxTextCtrl( m_panelRight, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - sbSizer23->Add( m_directoryRight, 1, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer135->Add( m_directoryRight, 1, wxALIGN_CENTER_VERTICAL, 5 ); m_dirPickerRight = new wxDirPickerCtrl( m_panelRight, wxID_ANY, wxEmptyString, _("Select a folder"), wxDefaultPosition, wxDefaultSize, 0 ); m_dirPickerRight->SetToolTip( _("Select a folder") ); - sbSizer23->Add( m_dirPickerRight, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - bSizer105->Add( sbSizer23, 1, wxALIGN_CENTER_VERTICAL|wxLEFT, 3 ); + bSizer135->Add( m_dirPickerRight, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - m_panelRight->SetSizer( bSizer105 ); + m_panelRight->SetSizer( bSizer135 ); m_panelRight->Layout(); - bSizer105->Fit( m_panelRight ); - bSizer74->Add( m_panelRight, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + bSizer135->Fit( m_panelRight ); + bSizer74->Add( m_panelRight, 1, wxALIGN_CENTER_VERTICAL, 5 ); this->SetSizer( bSizer74 ); this->Layout(); @@ -910,20 +892,62 @@ FolderPairGenerated::~FolderPairGenerated() BatchFolderPairGenerated::BatchFolderPairGenerated( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) { - wxStaticBoxSizer* sbSizer20; - sbSizer20 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxEmptyString ), wxVERTICAL ); + wxBoxSizer* bSizer142; + bSizer142 = new wxBoxSizer( wxVERTICAL ); - wxFlexGridSizer* fgSizer9; - fgSizer9 = new wxFlexGridSizer( 2, 2, 5, 5 ); - fgSizer9->AddGrowableCol( 1 ); - fgSizer9->SetFlexibleDirection( wxHORIZONTAL ); - fgSizer9->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + wxBoxSizer* bSizer140; + bSizer140 = new wxBoxSizer( wxHORIZONTAL ); - m_staticText53 = new wxStaticText( this, wxID_ANY, _("Left:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_panel32 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDOUBLE_BORDER ); + wxBoxSizer* bSizer147; + bSizer147 = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizer136; + bSizer136 = new wxBoxSizer( wxVERTICAL ); + + m_bpButtonRemovePair = new wxBitmapButton( m_panel32, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 19,21 ), wxBU_AUTODRAW ); + m_bpButtonRemovePair->SetToolTip( _("Remove folder pair") ); + + m_bpButtonRemovePair->SetToolTip( _("Remove folder pair") ); + + bSizer136->Add( m_bpButtonRemovePair, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer147->Add( bSizer136, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + wxBoxSizer* bSizer143; + bSizer143 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer145; + bSizer145 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText53 = new wxStaticText( m_panel32, wxID_ANY, _("Left"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText53->Wrap( -1 ); m_staticText53->SetFont( wxFont( 8, 74, 90, 92, false, wxT("Tahoma") ) ); - fgSizer9->Add( m_staticText53, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + bSizer145->Add( m_staticText53, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer143->Add( bSizer145, 1, 0, 5 ); + + wxBoxSizer* bSizer146; + bSizer146 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText541 = new wxStaticText( m_panel32, wxID_ANY, _("Right"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText541->Wrap( -1 ); + m_staticText541->SetFont( wxFont( 8, 74, 90, 92, false, wxT("Tahoma") ) ); + + bSizer146->Add( m_staticText541, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer143->Add( bSizer146, 1, 0, 5 ); + + bSizer147->Add( bSizer143, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + m_panel32->SetSizer( bSizer147 ); + m_panel32->Layout(); + bSizer147->Fit( m_panel32 ); + bSizer140->Add( m_panel32, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + wxBoxSizer* bSizer144; + bSizer144 = new wxBoxSizer( wxVERTICAL ); m_panelLeft = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bSizer114; @@ -940,13 +964,7 @@ BatchFolderPairGenerated::BatchFolderPairGenerated( wxWindow* parent, wxWindowID m_panelLeft->SetSizer( bSizer114 ); m_panelLeft->Layout(); bSizer114->Fit( m_panelLeft ); - fgSizer9->Add( m_panelLeft, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_staticText541 = new wxStaticText( this, wxID_ANY, _("Right:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText541->Wrap( -1 ); - m_staticText541->SetFont( wxFont( 8, 74, 90, 92, false, wxT("Tahoma") ) ); - - fgSizer9->Add( m_staticText541, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + bSizer144->Add( m_panelLeft, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_panelRight = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bSizer115; @@ -963,13 +981,18 @@ BatchFolderPairGenerated::BatchFolderPairGenerated( wxWindow* parent, wxWindowID m_panelRight->SetSizer( bSizer115 ); m_panelRight->Layout(); bSizer115->Fit( m_panelRight ); - fgSizer9->Add( m_panelRight, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer144->Add( m_panelRight, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer140->Add( bSizer144, 1, wxALIGN_CENTER_VERTICAL, 5 ); - sbSizer20->Add( fgSizer9, 0, wxEXPAND, 5 ); + bSizer142->Add( bSizer140, 0, wxEXPAND, 5 ); - this->SetSizer( sbSizer20 ); + + bSizer142->Add( 0, 5, 0, 0, 5 ); + + this->SetSizer( bSizer142 ); this->Layout(); - sbSizer20->Fit( this ); + bSizer142->Fit( this ); } BatchFolderPairGenerated::~BatchFolderPairGenerated() @@ -1047,24 +1070,124 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS m_scrolledWindow6 = new wxScrolledWindow( m_panelOverview, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL ); m_scrolledWindow6->SetScrollRate( 5, 5 ); - bSizerFolderPairs = new wxBoxSizer( wxVERTICAL ); + wxBoxSizer* bSizer141; + bSizer141 = new wxBoxSizer( wxVERTICAL ); + + sbSizerMainPair = new wxBoxSizer( wxHORIZONTAL ); + + m_panelMainPair = new wxPanel( m_scrolledWindow6, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDOUBLE_BORDER ); + wxBoxSizer* bSizer147; + bSizer147 = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizer1361; + bSizer1361 = new wxBoxSizer( wxVERTICAL ); + + m_bpButtonAddPair = new wxBitmapButton( m_panelMainPair, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 19,21 ), wxBU_AUTODRAW ); + m_bpButtonAddPair->SetToolTip( _("Add folder pair") ); + + m_bpButtonAddPair->SetToolTip( _("Add folder pair") ); - m_scrolledWindow6->SetSizer( bSizerFolderPairs ); + 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; + bSizer143 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer145; + bSizer145 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText532 = new wxStaticText( m_panelMainPair, wxID_ANY, _("Left"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText532->Wrap( -1 ); + m_staticText532->SetFont( wxFont( 8, 74, 90, 92, false, wxT("Tahoma") ) ); + + bSizer145->Add( m_staticText532, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer143->Add( bSizer145, 1, 0, 5 ); + + wxBoxSizer* bSizer146; + bSizer146 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText5411 = new wxStaticText( m_panelMainPair, wxID_ANY, _("Right"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText5411->Wrap( -1 ); + m_staticText5411->SetFont( wxFont( 8, 74, 90, 92, false, wxT("Tahoma") ) ); + + bSizer146->Add( m_staticText5411, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer143->Add( bSizer146, 1, 0, 5 ); + + bSizer147->Add( bSizer143, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT|wxEXPAND, 5 ); + + m_panelMainPair->SetSizer( bSizer147 ); + m_panelMainPair->Layout(); + bSizer147->Fit( m_panelMainPair ); + sbSizerMainPair->Add( m_panelMainPair, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxBOTTOM, 5 ); + + wxBoxSizer* bSizer158; + bSizer158 = new wxBoxSizer( wxVERTICAL ); + + m_panelLeft = new wxPanel( m_scrolledWindow6, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer1141; + bSizer1141 = new wxBoxSizer( wxHORIZONTAL ); + + m_directoryLeft = new wxTextCtrl( m_panelLeft, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + bSizer1141->Add( m_directoryLeft, 1, wxALIGN_CENTER_VERTICAL, 5 ); + + m_dirPickerLeft = new wxDirPickerCtrl( m_panelLeft, wxID_ANY, wxEmptyString, _("Select a folder"), wxDefaultPosition, wxDefaultSize, 0 ); + m_dirPickerLeft->SetToolTip( _("Select a folder") ); + + bSizer1141->Add( m_dirPickerLeft, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + m_panelLeft->SetSizer( bSizer1141 ); + m_panelLeft->Layout(); + bSizer1141->Fit( m_panelLeft ); + bSizer158->Add( m_panelLeft, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_panelRight = new wxPanel( m_scrolledWindow6, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer115; + bSizer115 = new wxBoxSizer( wxHORIZONTAL ); + + m_directoryRight = new wxTextCtrl( m_panelRight, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + bSizer115->Add( m_directoryRight, 1, wxALIGN_CENTER_VERTICAL, 5 ); + + m_dirPickerRight = new wxDirPickerCtrl( m_panelRight, wxID_ANY, wxEmptyString, _("Select a folder"), wxDefaultPosition, wxDefaultSize, 0 ); + m_dirPickerRight->SetToolTip( _("Select a folder") ); + + bSizer115->Add( m_dirPickerRight, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + m_panelRight->SetSizer( bSizer115 ); + m_panelRight->Layout(); + bSizer115->Fit( m_panelRight ); + bSizer158->Add( m_panelRight, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + sbSizerMainPair->Add( bSizer158, 1, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 ); + + bSizer141->Add( sbSizerMainPair, 0, wxEXPAND, 5 ); + + bSizerAddFolderPairs = new wxBoxSizer( wxVERTICAL ); + + bSizer141->Add( bSizerAddFolderPairs, 0, wxEXPAND, 5 ); + + m_scrolledWindow6->SetSizer( bSizer141 ); m_scrolledWindow6->Layout(); - bSizerFolderPairs->Fit( m_scrolledWindow6 ); + bSizer141->Fit( m_scrolledWindow6 ); bSizer100->Add( m_scrolledWindow6, 0, wxEXPAND, 5 ); bSizer100->Add( 0, 10, 0, 0, 5 ); wxBoxSizer* bSizer57; - bSizer57 = new wxBoxSizer( wxHORIZONTAL ); + bSizer57 = new wxBoxSizer( wxVERTICAL ); - wxBoxSizer* bSizer71; - bSizer71 = new wxBoxSizer( wxHORIZONTAL ); - - wxBoxSizer* bSizer721; - bSizer721 = new wxBoxSizer( wxVERTICAL ); + wxBoxSizer* bSizer156; + bSizer156 = new wxBoxSizer( wxHORIZONTAL ); wxStaticBoxSizer* sbSizer6; sbSizer6 = new wxStaticBoxSizer( new wxStaticBox( m_panelOverview, wxID_ANY, _("Compare by...") ), wxVERTICAL ); @@ -1080,25 +1203,10 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS sbSizer6->Add( m_radioBtnContent, 0, wxTOP, 5 ); - bSizer721->Add( sbSizer6, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + bSizer156->Add( sbSizer6, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - bSizer721->Add( 0, 10, 0, 0, 5 ); - - wxStaticBoxSizer* sbSizer25; - sbSizer25 = new wxStaticBoxSizer( new wxStaticBox( m_panelOverview, wxID_ANY, _("Error handling") ), wxVERTICAL ); - - wxArrayString m_choiceHandleErrorChoices; - m_choiceHandleError = new wxChoice( m_panelOverview, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceHandleErrorChoices, 0 ); - m_choiceHandleError->SetSelection( 0 ); - sbSizer25->Add( m_choiceHandleError, 0, wxALL, 5 ); - - bSizer721->Add( sbSizer25, 1, wxEXPAND, 5 ); - - bSizer71->Add( bSizer721, 0, 0, 5 ); - - - bSizer71->Add( 10, 0, 1, wxEXPAND, 5 ); + bSizer156->Add( 10, 10, 0, wxEXPAND, 5 ); wxStaticBoxSizer* sbSizer24; sbSizer24 = new wxStaticBoxSizer( new wxStaticBox( m_panelOverview, wxID_ANY, wxEmptyString ), wxVERTICAL ); @@ -1106,12 +1214,6 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS sbSizer24->Add( 0, 0, 1, wxEXPAND, 5 ); - m_checkBoxUseRecycler = new wxCheckBox( m_panelOverview, wxID_ANY, _("Use Recycle Bin"), wxDefaultPosition, wxDefaultSize, 0 ); - - m_checkBoxUseRecycler->SetToolTip( _("Use Recycle Bin when deleting or overwriting files during synchronization") ); - - sbSizer24->Add( m_checkBoxUseRecycler, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - m_checkBoxFilter = new wxCheckBox( m_panelOverview, wxID_ANY, _("Filter files"), wxDefaultPosition, wxDefaultSize, 0 ); m_checkBoxFilter->SetToolTip( _("Enable filter to exclude files from synchronization") ); @@ -1127,15 +1229,57 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS sbSizer24->Add( 0, 0, 1, wxEXPAND, 5 ); - bSizer71->Add( sbSizer24, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer156->Add( sbSizer24, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer57->Add( bSizer156, 0, 0, 5 ); - bSizer71->Add( 150, 0, 0, 0, 5 ); - bSizer57->Add( bSizer71, 0, wxEXPAND, 5 ); + bSizer57->Add( 10, 10, 0, 0, 5 ); + wxBoxSizer* bSizer721; + bSizer721 = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticBoxSizer* sbSizer25; + sbSizer25 = new wxStaticBoxSizer( new wxStaticBox( m_panelOverview, wxID_ANY, _("Error handling") ), wxHORIZONTAL ); + + wxArrayString m_choiceHandleErrorChoices; + m_choiceHandleError = new wxChoice( m_panelOverview, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceHandleErrorChoices, 0 ); + 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 ); - bSizer57->Add( 10, 0, 1, wxEXPAND, 5 ); + wxStaticBoxSizer* sbSizer23; + sbSizer23 = new wxStaticBoxSizer( new wxStaticBox( m_panelOverview, wxID_ANY, _("Deletion handling") ), wxVERTICAL ); + + wxArrayString m_choiceHandleDeletionChoices; + m_choiceHandleDeletion = new wxChoice( m_panelOverview, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceHandleDeletionChoices, 0 ); + m_choiceHandleDeletion->SetSelection( 0 ); + sbSizer23->Add( m_choiceHandleDeletion, 0, wxBOTTOM, 5 ); + + m_panelCustomDeletionDir = new wxPanel( m_panelOverview, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer1151; + bSizer1151 = new wxBoxSizer( wxHORIZONTAL ); + + m_textCtrlCustomDelFolder = new wxTextCtrl( m_panelCustomDeletionDir, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_RIGHT ); + m_textCtrlCustomDelFolder->SetMinSize( wxSize( 160,-1 ) ); + + bSizer1151->Add( m_textCtrlCustomDelFolder, 1, wxALIGN_CENTER_VERTICAL, 5 ); + + m_dirPickerCustomDelFolder = new wxDirPickerCtrl( m_panelCustomDeletionDir, wxID_ANY, wxEmptyString, _("Select a folder"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer1151->Add( m_dirPickerCustomDelFolder, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + m_panelCustomDeletionDir->SetSizer( bSizer1151 ); + m_panelCustomDeletionDir->Layout(); + bSizer1151->Fit( m_panelCustomDeletionDir ); + sbSizer23->Add( m_panelCustomDeletionDir, 0, 0, 5 ); + + bSizer721->Add( sbSizer23, 0, wxEXPAND, 5 ); + + bSizer57->Add( bSizer721, 0, 0, 5 ); bSizer100->Add( bSizer57, 0, 0, 5 ); @@ -1389,12 +1533,14 @@ 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_choiceHandleError->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( BatchDlgGenerated::OnChangeErrorHandling ), NULL, this ); - m_checkBoxUseRecycler->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnSelectRecycleBin ), NULL, this ); m_checkBoxFilter->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnCheckFilter ), NULL, this ); m_checkBoxSilent->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnCheckLogging ), NULL, this ); + m_choiceHandleError->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( BatchDlgGenerated::OnChangeErrorHandling ), NULL, this ); + m_choiceHandleDeletion->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( BatchDlgGenerated::OnChangeDeletionHandling ), NULL, this ); m_bpButtonLeftOnly->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnExLeftSideOnly ), NULL, this ); m_bpButtonRightOnly->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnExRightSideOnly ), NULL, this ); m_bpButtonLeftNewer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnLeftNewer ), NULL, this ); @@ -1409,12 +1555,14 @@ 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_choiceHandleError->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( BatchDlgGenerated::OnChangeErrorHandling ), NULL, this ); - m_checkBoxUseRecycler->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnSelectRecycleBin ), NULL, this ); m_checkBoxFilter->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnCheckFilter ), NULL, this ); m_checkBoxSilent->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnCheckLogging ), NULL, this ); + m_choiceHandleError->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( BatchDlgGenerated::OnChangeErrorHandling ), NULL, this ); + m_choiceHandleDeletion->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( BatchDlgGenerated::OnChangeDeletionHandling ), NULL, this ); m_bpButtonLeftOnly->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnExLeftSideOnly ), NULL, this ); m_bpButtonRightOnly->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnExRightSideOnly ), NULL, this ); m_bpButtonLeftNewer->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnLeftNewer ), NULL, this ); @@ -1552,14 +1700,14 @@ CompareStatusGenerated::CompareStatusGenerated( wxWindow* parent, wxWindowID id, bSizer48->Add( m_staticText30, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 ); - m_textCtrlFilename = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY ); - m_textCtrlFilename->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVEBORDER ) ); + m_textCtrlStatus = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY ); + m_textCtrlStatus->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVEBORDER ) ); - bSizer48->Add( m_textCtrlFilename, 1, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer48->Add( m_textCtrlStatus, 1, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); bSizer40->Add( bSizer48, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); - m_gauge2 = new wxGauge( this, wxID_ANY, 100, wxDefaultPosition, wxSize( -1,20 ), wxGA_HORIZONTAL ); + m_gauge2 = new wxGauge( this, wxID_ANY, 100, wxDefaultPosition, wxSize( -1,14 ), wxGA_HORIZONTAL|wxGA_SMOOTH ); bSizer40->Add( m_gauge2, 0, wxALL|wxEXPAND, 5 ); this->SetSizer( bSizer40 ); @@ -1571,7 +1719,7 @@ CompareStatusGenerated::~CompareStatusGenerated() { } -SyncDlgGenerated::SyncDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) { this->SetSizeHints( wxDefaultSize, wxDefaultSize ); @@ -1676,17 +1824,45 @@ SyncDlgGenerated::SyncDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr bSizer201 = new wxBoxSizer( wxHORIZONTAL ); - m_checkBoxUseRecycler = new wxCheckBox( this, wxID_ANY, _("Use Recycle Bin"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticBoxSizer* sbSizer27; + sbSizer27 = 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 ); + + + bSizer201->Add( 10, 0, 0, 0, 5 ); + + wxStaticBoxSizer* sbSizer231; + sbSizer231 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Deletion handling") ), wxVERTICAL ); - m_checkBoxUseRecycler->SetToolTip( _("Use Recycle Bin when deleting or overwriting files during synchronization") ); + wxArrayString m_choiceHandleDeletionChoices; + m_choiceHandleDeletion = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceHandleDeletionChoices, 0 ); + m_choiceHandleDeletion->SetSelection( 0 ); + sbSizer231->Add( m_choiceHandleDeletion, 0, wxBOTTOM, 5 ); - bSizer201->Add( m_checkBoxUseRecycler, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + m_panelCustomDeletionDir = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer1151; + bSizer1151 = new wxBoxSizer( wxHORIZONTAL ); - m_checkBoxIgnoreErrors = new wxCheckBox( this, wxID_ANY, _("Ignore errors"), wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlCustomDelFolder = new wxTextCtrl( m_panelCustomDeletionDir, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_RIGHT ); + m_textCtrlCustomDelFolder->SetMinSize( wxSize( 160,-1 ) ); - m_checkBoxIgnoreErrors->SetToolTip( _("Hides error messages during synchronization:\nThey are collected and shown as a list at the end of the process") ); + bSizer1151->Add( m_textCtrlCustomDelFolder, 1, wxALIGN_CENTER_VERTICAL, 5 ); - bSizer201->Add( m_checkBoxIgnoreErrors, 0, wxALL, 5 ); + m_dirPickerCustomDelFolder = new wxDirPickerCtrl( m_panelCustomDeletionDir, wxID_ANY, wxEmptyString, _("Select a folder"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer1151->Add( m_dirPickerCustomDelFolder, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + m_panelCustomDeletionDir->SetSizer( bSizer1151 ); + m_panelCustomDeletionDir->Layout(); + bSizer1151->Fit( m_panelCustomDeletionDir ); + sbSizer231->Add( m_panelCustomDeletionDir, 0, 0, 5 ); + + bSizer201->Add( sbSizer231, 0, wxEXPAND, 5 ); bSizer29->Add( bSizer201, 0, wxTOP|wxBOTTOM, 5 ); @@ -1696,11 +1872,11 @@ SyncDlgGenerated::SyncDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr wxBoxSizer* bSizer291; bSizer291 = new wxBoxSizer( wxHORIZONTAL ); - m_button6 = new wxButton( this, wxID_OK, _("&Apply"), wxDefaultPosition, wxSize( 120,35 ), 0 ); - m_button6->SetDefault(); - m_button6->SetFont( wxFont( 10, 74, 90, 92, false, wxT("Tahoma") ) ); + m_buttonApply = new wxButton( this, wxID_OK, _("&Apply"), wxDefaultPosition, wxSize( 120,35 ), 0 ); + m_buttonApply->SetDefault(); + m_buttonApply->SetFont( wxFont( 10, 74, 90, 92, false, wxT("Tahoma") ) ); - bSizer291->Add( m_button6, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + bSizer291->Add( m_buttonApply, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); m_button16 = new wxButton( this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxSize( -1,30 ), 0 ); m_button16->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); @@ -1836,43 +2012,136 @@ SyncDlgGenerated::SyncDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr this->Centre( wxBOTH ); // Connect Events - this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( SyncDlgGenerated::OnClose ) ); - m_radioBtn1->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncDlgGenerated::OnSyncLeftToRight ), NULL, this ); - m_buttonOneWay->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnSyncLeftToRight ), NULL, this ); - m_radioBtnUpdate->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncDlgGenerated::OnSyncUpdate ), NULL, this ); - m_buttonUpdate->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnSyncUpdate ), NULL, this ); - m_radioBtn2->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncDlgGenerated::OnSyncBothSides ), NULL, this ); - m_buttonTwoWay->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnSyncBothSides ), NULL, this ); - m_radioBtn3->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncDlgGenerated::OnSyncCostum ), NULL, this ); - m_checkBoxUseRecycler->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnSelectRecycleBin ), NULL, this ); - m_button6->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnApply ), NULL, this ); - m_button16->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnCancel ), NULL, this ); - m_bpButtonLeftOnly->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnExLeftSideOnly ), NULL, this ); - m_bpButtonRightOnly->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnExRightSideOnly ), NULL, this ); - m_bpButtonLeftNewer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnLeftNewer ), NULL, this ); - m_bpButtonRightNewer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnRightNewer ), NULL, this ); - m_bpButtonDifferent->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnDifferent ), NULL, this ); + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( SyncCfgDlgGenerated::OnClose ) ); + m_radioBtn1->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncLeftToRight ), NULL, this ); + m_buttonOneWay->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncLeftToRight ), NULL, this ); + m_radioBtnUpdate->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncUpdate ), NULL, this ); + m_buttonUpdate->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncUpdate ), NULL, this ); + m_radioBtn2->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncBothSides ), NULL, this ); + m_buttonTwoWay->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncBothSides ), NULL, this ); + m_radioBtn3->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncCostum ), NULL, this ); + m_choiceHandleError->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnChangeErrorHandling ), NULL, this ); + m_choiceHandleDeletion->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnChangeDeletionHandling ), NULL, this ); + m_buttonApply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnApply ), NULL, this ); + m_button16->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnCancel ), NULL, this ); + m_bpButtonLeftOnly->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnExLeftSideOnly ), NULL, this ); + m_bpButtonRightOnly->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnExRightSideOnly ), NULL, this ); + 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 ); +} + +SyncCfgDlgGenerated::~SyncCfgDlgGenerated() +{ + // Disconnect Events + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( SyncCfgDlgGenerated::OnClose ) ); + m_radioBtn1->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncLeftToRight ), NULL, this ); + m_buttonOneWay->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncLeftToRight ), NULL, this ); + m_radioBtnUpdate->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncUpdate ), NULL, this ); + m_buttonUpdate->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncUpdate ), NULL, this ); + m_radioBtn2->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncBothSides ), NULL, this ); + m_buttonTwoWay->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncBothSides ), NULL, this ); + m_radioBtn3->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncCostum ), NULL, this ); + m_choiceHandleError->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnChangeErrorHandling ), NULL, this ); + m_choiceHandleDeletion->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnChangeDeletionHandling ), NULL, this ); + m_buttonApply->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnApply ), NULL, this ); + m_button16->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnCancel ), NULL, this ); + m_bpButtonLeftOnly->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnExLeftSideOnly ), NULL, this ); + m_bpButtonRightOnly->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnExRightSideOnly ), NULL, this ); + 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 ); +} + +CmpCfgDlgGenerated::CmpCfgDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer136; + bSizer136 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer55; + bSizer55 = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* sbSizer6; + sbSizer6 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Compare by...") ), wxHORIZONTAL ); + + wxFlexGridSizer* fgSizer16; + fgSizer16 = new wxFlexGridSizer( 2, 2, 0, 0 ); + fgSizer16->SetFlexibleDirection( wxBOTH ); + fgSizer16->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_radioBtnSizeDate = new wxRadioButton( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxRB_GROUP ); + m_radioBtnSizeDate->SetValue( true ); + m_radioBtnSizeDate->SetToolTip( _("Files are found equal if\n - filesize\n - last write time and date\nare the same.") ); + + fgSizer16->Add( m_radioBtnSizeDate, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonTimeSize = new wxButton( this, wxID_ANY, _("File size and date"), wxDefaultPosition, wxSize( -1,40 ), 0 ); + m_buttonTimeSize->SetFont( wxFont( 11, 74, 90, 92, false, wxT("Tahoma") ) ); + m_buttonTimeSize->SetToolTip( _("Files are found equal if\n - filesize\n - last write time and date\nare the same.") ); + + fgSizer16->Add( m_buttonTimeSize, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_radioBtnContent = new wxRadioButton( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_radioBtnContent->SetToolTip( _("Files are found equal if\n - file content\nis the same.") ); + + fgSizer16->Add( m_radioBtnContent, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonContent = new wxButton( this, wxID_ANY, _("File content"), wxDefaultPosition, wxSize( -1,40 ), 0 ); + m_buttonContent->SetFont( wxFont( 11, 74, 90, 92, false, wxT("Tahoma") ) ); + m_buttonContent->SetToolTip( _("Files are found equal if\n - file content\nis the same.") ); + + fgSizer16->Add( m_buttonContent, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + sbSizer6->Add( fgSizer16, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_staticline14 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ); + sbSizer6->Add( m_staticline14, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + m_bpButtonHelp = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); + m_bpButtonHelp->SetToolTip( _("Help") ); + + m_bpButtonHelp->SetToolTip( _("Help") ); + + sbSizer6->Add( m_bpButtonHelp, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer55->Add( sbSizer6, 0, wxALIGN_CENTER_VERTICAL, 2 ); + + + bSizer55->Add( 0, 4, 0, 0, 5 ); + + m_button6 = new wxButton( this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxSize( -1,30 ), 0 ); + m_button6->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); + + bSizer55->Add( m_button6, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + bSizer136->Add( bSizer55, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + this->SetSizer( bSizer136 ); + this->Layout(); + bSizer136->Fit( this ); + + // Connect Events + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CmpCfgDlgGenerated::OnClose ) ); + m_radioBtnSizeDate->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( CmpCfgDlgGenerated::OnTimeSize ), NULL, this ); + m_buttonTimeSize->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CmpCfgDlgGenerated::OnTimeSize ), NULL, this ); + m_radioBtnContent->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( CmpCfgDlgGenerated::OnContent ), NULL, this ); + m_buttonContent->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CmpCfgDlgGenerated::OnContent ), NULL, this ); + m_bpButtonHelp->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CmpCfgDlgGenerated::OnShowHelp ), NULL, this ); + m_button6->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CmpCfgDlgGenerated::OnCancel ), NULL, this ); } -SyncDlgGenerated::~SyncDlgGenerated() +CmpCfgDlgGenerated::~CmpCfgDlgGenerated() { // Disconnect Events - this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( SyncDlgGenerated::OnClose ) ); - m_radioBtn1->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncDlgGenerated::OnSyncLeftToRight ), NULL, this ); - m_buttonOneWay->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnSyncLeftToRight ), NULL, this ); - m_radioBtnUpdate->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncDlgGenerated::OnSyncUpdate ), NULL, this ); - m_buttonUpdate->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnSyncUpdate ), NULL, this ); - m_radioBtn2->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncDlgGenerated::OnSyncBothSides ), NULL, this ); - m_buttonTwoWay->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnSyncBothSides ), NULL, this ); - m_radioBtn3->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncDlgGenerated::OnSyncCostum ), NULL, this ); - m_checkBoxUseRecycler->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnSelectRecycleBin ), NULL, this ); - m_button6->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnApply ), NULL, this ); - m_button16->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnCancel ), NULL, this ); - m_bpButtonLeftOnly->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnExLeftSideOnly ), NULL, this ); - m_bpButtonRightOnly->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnExRightSideOnly ), NULL, this ); - m_bpButtonLeftNewer->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnLeftNewer ), NULL, this ); - m_bpButtonRightNewer->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnRightNewer ), NULL, this ); - m_bpButtonDifferent->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncDlgGenerated::OnDifferent ), NULL, this ); + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CmpCfgDlgGenerated::OnClose ) ); + m_radioBtnSizeDate->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( CmpCfgDlgGenerated::OnTimeSize ), NULL, this ); + m_buttonTimeSize->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CmpCfgDlgGenerated::OnTimeSize ), NULL, this ); + m_radioBtnContent->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( CmpCfgDlgGenerated::OnContent ), NULL, this ); + m_buttonContent->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CmpCfgDlgGenerated::OnContent ), NULL, this ); + m_bpButtonHelp->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CmpCfgDlgGenerated::OnShowHelp ), NULL, this ); + m_button6->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CmpCfgDlgGenerated::OnCancel ), NULL, this ); } SyncStatusDlgGenerated::SyncStatusDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) @@ -2306,34 +2575,33 @@ AboutDlgGenerated::AboutDlgGenerated( wxWindow* parent, wxWindowID id, const wxS wxBoxSizer* bSizer53; bSizer53 = new wxBoxSizer( wxVERTICAL ); - m_scrolledWindow4 = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDOUBLE_BORDER|wxHSCROLL|wxVSCROLL ); - m_scrolledWindow4->SetScrollRate( 5, 5 ); - m_scrolledWindow4->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVEBORDER ) ); - m_scrolledWindow4->SetMinSize( wxSize( -1,125 ) ); + m_scrolledWindowCodeInfo = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDOUBLE_BORDER|wxHSCROLL|wxVSCROLL ); + m_scrolledWindowCodeInfo->SetScrollRate( 5, 5 ); + m_scrolledWindowCodeInfo->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVEBORDER ) ); + m_scrolledWindowCodeInfo->SetMinSize( wxSize( -1,125 ) ); - wxBoxSizer* bSizer73; - bSizer73 = new wxBoxSizer( wxVERTICAL ); + bSizerCodeInfo = new wxBoxSizer( wxVERTICAL ); - m_staticText72 = new wxStaticText( m_scrolledWindow4, wxID_ANY, _("Source code written completely in C++ utilizing:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText72 = new wxStaticText( m_scrolledWindowCodeInfo, wxID_ANY, _("Source code written completely in C++ utilizing:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText72->Wrap( -1 ); m_staticText72->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 74, 90, 92, false, wxT("Tahoma") ) ); - bSizer73->Add( m_staticText72, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizerCodeInfo->Add( m_staticText72, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP|wxBOTTOM, 5 ); - m_staticText73 = new wxStaticText( m_scrolledWindow4, wxID_ANY, _(" MinGW \t- Windows port of GNU Compiler Collection\n wxWidgets \t- Open-Source GUI framework\n wxFormBuilder\t- wxWidgets GUI-builder\n CodeBlocks \t- Open-Source IDE"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText73 = new wxStaticText( m_scrolledWindowCodeInfo, wxID_ANY, _(" MinGW \t- Windows port of GNU Compiler Collection\n wxWidgets \t- Open-Source GUI framework\n wxFormBuilder\t- wxWidgets GUI-builder\n CodeBlocks \t- Open-Source IDE"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText73->Wrap( -1 ); - bSizer73->Add( m_staticText73, 0, wxEXPAND|wxALL, 5 ); + bSizerCodeInfo->Add( m_staticText73, 0, wxALL|wxEXPAND, 5 ); - m_staticText74 = new wxStaticText( m_scrolledWindow4, wxID_ANY, _("- ZenJu -"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText74 = new wxStaticText( m_scrolledWindowCodeInfo, wxID_ANY, _("- ZenJu -"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText74->Wrap( -1 ); m_staticText74->SetFont( wxFont( 10, 74, 93, 90, false, wxT("Tahoma") ) ); - bSizer73->Add( m_staticText74, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizerCodeInfo->Add( m_staticText74, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP|wxRIGHT|wxLEFT, 5 ); - m_scrolledWindow4->SetSizer( bSizer73 ); - m_scrolledWindow4->Layout(); - bSizer73->Fit( m_scrolledWindow4 ); - bSizer53->Add( m_scrolledWindow4, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxBOTTOM, 10 ); + m_scrolledWindowCodeInfo->SetSizer( bSizerCodeInfo ); + m_scrolledWindowCodeInfo->Layout(); + bSizerCodeInfo->Fit( m_scrolledWindowCodeInfo ); + bSizer53->Add( m_scrolledWindowCodeInfo, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxBOTTOM, 10 ); m_scrolledWindowTranslators = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), wxDOUBLE_BORDER|wxHSCROLL|wxVSCROLL ); m_scrolledWindowTranslators->SetScrollRate( 5, 5 ); @@ -2361,69 +2629,71 @@ AboutDlgGenerated::AboutDlgGenerated( wxWindow* parent, wxWindowID id, const wxS m_scrolledWindowTranslators->SetSizer( bSizerTranslators ); m_scrolledWindowTranslators->Layout(); bSizerTranslators->Fit( m_scrolledWindowTranslators ); - bSizer53->Add( m_scrolledWindowTranslators, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + bSizer53->Add( m_scrolledWindowTranslators, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxBOTTOM, 5 ); - bSizer31->Add( bSizer53, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxRIGHT|wxLEFT, 25 ); + bSizer31->Add( bSizer53, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT|wxEXPAND, 25 ); m_staticline3 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); bSizer31->Add( m_staticline3, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 ); - m_panel22 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER ); - wxBoxSizer* bSizer104; - bSizer104 = new wxBoxSizer( wxVERTICAL ); - - m_staticText131 = new wxStaticText( m_panel22, wxID_ANY, _("Feedback and suggestions are welcome at:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText131 = new wxStaticText( this, wxID_ANY, _("Feedback and suggestions are welcome at:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText131->Wrap( -1 ); m_staticText131->SetFont( wxFont( 11, 74, 93, 92, false, wxT("Tahoma") ) ); - bSizer104->Add( m_staticText131, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP, 5 ); + bSizer31->Add( m_staticText131, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_staticline12 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bSizer31->Add( m_staticline12, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 ); - m_staticline12 = new wxStaticLine( m_panel22, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - bSizer104->Add( m_staticline12, 0, wxEXPAND | wxALL, 5 ); + wxBoxSizer* bSizer104; + bSizer104 = new wxBoxSizer( wxVERTICAL ); wxBoxSizer* bSizer103; bSizer103 = new wxBoxSizer( wxHORIZONTAL ); - m_bitmap9 = new wxStaticBitmap( m_panel22, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 48,48 ), 0 ); + m_bitmap9 = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 48,48 ), 0 ); m_bitmap9->SetToolTip( _("FreeFileSync at Sourceforge") ); - bSizer103->Add( m_bitmap9, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + bSizer103->Add( m_bitmap9, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - m_hyperlink1 = new wxHyperlinkCtrl( m_panel22, wxID_ANY, _("Homepage"), wxT("http://sourceforge.net/projects/freefilesync/"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_hyperlink1 = new wxHyperlinkCtrl( this, wxID_ANY, _("Homepage"), wxT("http://sourceforge.net/projects/freefilesync/"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); m_hyperlink1->SetFont( wxFont( 10, 74, 90, 92, true, wxT("Tahoma") ) ); m_hyperlink1->SetToolTip( _("http://sourceforge.net/projects/freefilesync/") ); bSizer103->Add( m_hyperlink1, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - bSizer103->Add( 30, 0, 1, wxEXPAND, 5 ); + bSizer103->Add( 20, 0, 1, wxEXPAND, 5 ); + + m_hyperlink6 = new wxHyperlinkCtrl( this, wxID_ANY, _("Report translation error"), wxT("http://sourceforge.net/forum/forum.php?forum_id=976976"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_hyperlink6->SetFont( wxFont( 10, 74, 90, 92, true, wxT("Tahoma") ) ); + m_hyperlink6->SetToolTip( _("https://sourceforge.net/forum/forum.php?forum_id=976976") ); + + bSizer103->Add( m_hyperlink6, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + + bSizer104->Add( bSizer103, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); - m_bitmap10 = new wxStaticBitmap( m_panel22, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 48,48 ), 0 ); + wxBoxSizer* bSizer108; + bSizer108 = new wxBoxSizer( wxHORIZONTAL ); + + m_bitmap10 = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 48,48 ), 0 ); m_bitmap10->SetToolTip( _("Email") ); - bSizer103->Add( m_bitmap10, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + bSizer108->Add( m_bitmap10, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - m_hyperlink2 = new wxHyperlinkCtrl( m_panel22, wxID_ANY, _("Email"), wxT("mailto:zhnmju123@gmx.de"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_hyperlink2 = new wxHyperlinkCtrl( this, wxID_ANY, _("Email"), wxT("mailto:zhnmju123@gmx.de"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); m_hyperlink2->SetFont( wxFont( 10, 74, 90, 92, true, wxT("Tahoma") ) ); m_hyperlink2->SetToolTip( _("zhnmju123@gmx.de") ); - bSizer103->Add( m_hyperlink2, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - bSizer104->Add( bSizer103, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer108->Add( m_hyperlink2, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - m_panel22->SetSizer( bSizer104 ); - m_panel22->Layout(); - bSizer104->Fit( m_panel22 ); - bSizer31->Add( m_panel22, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); - wxBoxSizer* bSizer108; - bSizer108 = new wxBoxSizer( wxHORIZONTAL ); + bSizer108->Add( 30, 0, 1, wxEXPAND, 5 ); m_animationControl1 = new wxAnimationCtrl(this, wxID_ANY, wxNullAnimation); - m_animationControl1->Hide(); m_animationControl1->SetToolTip( _("Donate with PayPal") ); - bSizer108->Add( m_animationControl1, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + bSizer108->Add( m_animationControl1, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); m_hyperlink3 = new wxHyperlinkCtrl( this, wxID_ANY, _("If you like FFS"), wxT("https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=zhnmju123%40gmx%2ede&no_shipping=0&no_note=1&tax=0¤cy_code=EUR&lc=EN&bn=PP%2dDonationsBF&charset=UTF%2d8"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); m_hyperlink3->SetFont( wxFont( 10, 74, 90, 92, true, wxT("Tahoma") ) ); @@ -2431,7 +2701,9 @@ AboutDlgGenerated::AboutDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer108->Add( m_hyperlink3, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - bSizer31->Add( bSizer108, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer104->Add( bSizer108, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + bSizer31->Add( bSizer104, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); bSizer31->Add( m_staticline2, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 ); @@ -2453,11 +2725,11 @@ AboutDlgGenerated::AboutDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer31->Add( sbSizer14, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxRIGHT|wxLEFT, 5 ); - m_button8 = new wxButton( this, wxID_OK, _("&OK"), wxDefaultPosition, wxSize( 100,32 ), 0 ); - m_button8->SetDefault(); - m_button8->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); + m_buttonOkay = new wxButton( this, wxID_OK, _("&OK"), wxDefaultPosition, wxSize( 100,32 ), 0 ); + m_buttonOkay->SetDefault(); + m_buttonOkay->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); - bSizer31->Add( m_button8, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); + bSizer31->Add( m_buttonOkay, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); this->SetSizer( bSizer31 ); this->Layout(); @@ -2467,14 +2739,14 @@ AboutDlgGenerated::AboutDlgGenerated( wxWindow* parent, wxWindowID id, const wxS // Connect Events this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( AboutDlgGenerated::OnClose ) ); - m_button8->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AboutDlgGenerated::OnOK ), NULL, this ); + m_buttonOkay->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AboutDlgGenerated::OnOK ), NULL, this ); } AboutDlgGenerated::~AboutDlgGenerated() { // Disconnect Events this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( AboutDlgGenerated::OnClose ) ); - m_button8->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AboutDlgGenerated::OnOK ), NULL, this ); + m_buttonOkay->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AboutDlgGenerated::OnOK ), NULL, this ); } ErrorDlgGenerated::ErrorDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) @@ -2872,7 +3144,7 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w wxBoxSizer* bSizer66; bSizer66 = new wxBoxSizer( wxHORIZONTAL ); - m_staticText181 = new wxStaticText( m_panel13, wxID_ANY, _("Include: *.doc;*.zip;*.exe\nExclude: \\temp\\*"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText181 = new wxStaticText( m_panel13, wxID_ANY, _("Include: *.doc;*.zip;*.exe\nExclude: temp\\*"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText181->Wrap( -1 ); bSizer66->Add( m_staticText181, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 ); @@ -3162,16 +3434,12 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind wxBoxSizer* bSizer104; bSizer104 = new wxBoxSizer( wxHORIZONTAL ); - m_staticText97 = new wxStaticText( this, wxID_ANY, _("File Manager integration:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText97->Wrap( -1 ); - m_staticText97->SetToolTip( _("This commandline will be executed each time you doubleclick on a filename. %name serves as a placeholder for the selected file.") ); - - bSizer104->Add( m_staticText97, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlFileManager = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 150,-1 ), 0 ); - m_textCtrlFileManager->SetToolTip( _("This commandline will be executed each time you doubleclick on a filename. %name serves as a placeholder for the selected file.") ); + 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 ); - bSizer104->Add( m_textCtrlFileManager, 1, 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 ); @@ -3204,11 +3472,11 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind wxBoxSizer* bSizer97; bSizer97 = new wxBoxSizer( wxHORIZONTAL ); - m_button28 = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,30 ), 0 ); - m_button28->SetDefault(); - m_button28->SetFont( wxFont( 10, 74, 90, 92, false, wxT("Tahoma") ) ); + m_buttonOkay = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,30 ), 0 ); + m_buttonOkay->SetDefault(); + m_buttonOkay->SetFont( wxFont( 10, 74, 90, 92, false, wxT("Tahoma") ) ); - bSizer97->Add( m_button28, 0, wxALL, 5 ); + bSizer97->Add( m_buttonOkay, 0, wxALL, 5 ); m_button9 = new wxButton( this, wxID_DEFAULT, _("&Default"), wxDefaultPosition, wxSize( -1,30 ), 0 ); m_button9->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); @@ -3229,7 +3497,7 @@ 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_button28->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnOkay ), 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 ); } @@ -3239,7 +3507,7 @@ 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_button28->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnOkay ), 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 ); } @@ -3251,6 +3519,19 @@ SyncPreviewDlgGenerated::SyncPreviewDlgGenerated( wxWindow* parent, wxWindowID i wxBoxSizer* bSizer134; bSizer134 = new wxBoxSizer( wxVERTICAL ); + wxBoxSizer* bSizer158; + bSizer158 = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonStartSync = new wxButtonWithImage( this, wxID_ANY, _("Start"), wxDefaultPosition, wxSize( -1,40 ), 0 ); + m_buttonStartSync->SetDefault(); + m_buttonStartSync->SetFont( wxFont( 14, 74, 90, 92, false, wxT("Arial Black") ) ); + m_buttonStartSync->SetToolTip( _("Start synchronization") ); + + bSizer158->Add( m_buttonStartSync, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_staticline16 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ); + bSizer158->Add( m_staticline16, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + wxStaticBoxSizer* sbSizer28; sbSizer28 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Variant") ), wxVERTICAL ); @@ -3260,88 +3541,142 @@ SyncPreviewDlgGenerated::SyncPreviewDlgGenerated( wxWindow* parent, wxWindowID i sbSizer28->Add( m_staticTextVariant, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - bSizer134->Add( sbSizer28, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + bSizer158->Add( sbSizer28, 1, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); - wxBoxSizer* bSizer141; - bSizer141 = new wxBoxSizer( wxHORIZONTAL ); + bSizer134->Add( bSizer158, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); - m_buttonStartSync = new wxButtonWithImage( this, wxID_ANY, _("Start"), wxDefaultPosition, wxSize( -1,40 ), 0 ); - m_buttonStartSync->SetDefault(); - m_buttonStartSync->SetFont( wxFont( 14, 74, 90, 92, false, wxT("Arial Black") ) ); - m_buttonStartSync->SetToolTip( _("Start synchronization") ); + m_staticline14 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bSizer134->Add( m_staticline14, 0, wxEXPAND, 5 ); - bSizer141->Add( m_buttonStartSync, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_staticline14 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ); - bSizer141->Add( m_staticline14, 0, wxEXPAND|wxRIGHT, 5 ); - - - bSizer141->Add( 0, 0, 1, wxEXPAND, 5 ); + wxBoxSizer* bSizer141; + bSizer141 = new wxBoxSizer( wxHORIZONTAL ); wxStaticBoxSizer* sbSizer161; - sbSizer161 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Statistics") ), wxHORIZONTAL ); + sbSizer161 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Statistics") ), wxVERTICAL ); + + wxBoxSizer* bSizer157; + bSizer157 = new wxBoxSizer( wxHORIZONTAL ); wxFlexGridSizer* fgSizer5; fgSizer5 = new wxFlexGridSizer( 4, 2, 0, 5 ); fgSizer5->SetFlexibleDirection( wxHORIZONTAL ); fgSizer5->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + fgSizer5->Add( 0, 0, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_staticText94 = new wxStaticText( this, wxID_ANY, _("Left"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText94->Wrap( -1 ); + m_staticText94->SetFont( wxFont( 9, 74, 90, 92, false, wxT("Arial") ) ); + + fgSizer5->Add( m_staticText94, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + m_bitmapCreate = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); m_bitmapCreate->SetToolTip( _("Number of files and directories that will be created") ); fgSizer5->Add( m_bitmapCreate, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - m_textCtrlCreate = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY ); - m_textCtrlCreate->SetFont( wxFont( 8, 74, 90, 90, false, wxT("Tahoma") ) ); - m_textCtrlCreate->SetBackgroundColour( wxColour( 222, 222, 236 ) ); - m_textCtrlCreate->SetToolTip( _("Number of files and directories that will be created") ); + m_textCtrlCreateL = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY ); + m_textCtrlCreateL->SetFont( wxFont( 8, 74, 90, 90, false, wxT("Tahoma") ) ); + m_textCtrlCreateL->SetBackgroundColour( wxColour( 222, 222, 236 ) ); + m_textCtrlCreateL->SetToolTip( _("Number of files and directories that will be created") ); - fgSizer5->Add( m_textCtrlCreate, 0, wxALIGN_CENTER_VERTICAL, 5 ); + fgSizer5->Add( m_textCtrlCreateL, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + m_bitmapUpdate = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); + m_bitmapUpdate->SetToolTip( _("Number of files that will be overwritten") ); + + fgSizer5->Add( m_bitmapUpdate, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_textCtrlUpdateL = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY ); + m_textCtrlUpdateL->SetFont( wxFont( 8, 74, 90, 90, false, wxT("Tahoma") ) ); + m_textCtrlUpdateL->SetBackgroundColour( wxColour( 222, 222, 236 ) ); + m_textCtrlUpdateL->SetToolTip( _("Number of files that will be overwritten") ); + + fgSizer5->Add( m_textCtrlUpdateL, 0, wxALIGN_CENTER_VERTICAL, 5 ); m_bitmapDelete = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); m_bitmapDelete->SetToolTip( _("Number of files and directories that will be deleted") ); fgSizer5->Add( m_bitmapDelete, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); - m_textCtrlDelete = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY ); - m_textCtrlDelete->SetFont( wxFont( 8, 74, 90, 90, false, wxT("Tahoma") ) ); - m_textCtrlDelete->SetBackgroundColour( wxColour( 222, 222, 236 ) ); - m_textCtrlDelete->SetToolTip( _("Number of files and directories that will be deleted") ); + m_textCtrlDeleteL = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY ); + m_textCtrlDeleteL->SetFont( wxFont( 8, 74, 90, 90, false, wxT("Tahoma") ) ); + m_textCtrlDeleteL->SetBackgroundColour( wxColour( 222, 222, 236 ) ); + m_textCtrlDeleteL->SetToolTip( _("Number of files and directories that will be deleted") ); - fgSizer5->Add( m_textCtrlDelete, 0, wxALIGN_CENTER_VERTICAL, 5 ); + fgSizer5->Add( m_textCtrlDeleteL, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_bitmapUpdate = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); - m_bitmapUpdate->SetToolTip( _("Number of files that will be overwritten") ); + bSizer157->Add( fgSizer5, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - fgSizer5->Add( m_bitmapUpdate, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + wxFlexGridSizer* fgSizer51; + fgSizer51 = new wxFlexGridSizer( 3, 1, 0, 5 ); + fgSizer51->SetFlexibleDirection( wxHORIZONTAL ); + fgSizer51->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - m_textCtrlUpdate = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY ); - m_textCtrlUpdate->SetFont( wxFont( 8, 74, 90, 90, false, wxT("Tahoma") ) ); - m_textCtrlUpdate->SetBackgroundColour( wxColour( 222, 222, 236 ) ); - m_textCtrlUpdate->SetToolTip( _("Number of files that will be overwritten") ); + m_staticText95 = new wxStaticText( this, wxID_ANY, _("Right"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText95->Wrap( -1 ); + m_staticText95->SetFont( wxFont( 9, 74, 90, 92, false, wxT("Arial") ) ); + + fgSizer51->Add( m_staticText95, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlCreateR = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY ); + m_textCtrlCreateR->SetFont( wxFont( 8, 74, 90, 90, false, wxT("Tahoma") ) ); + m_textCtrlCreateR->SetBackgroundColour( wxColour( 222, 222, 236 ) ); + m_textCtrlCreateR->SetToolTip( _("Number of files and directories that will be created") ); + + fgSizer51->Add( m_textCtrlCreateR, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlUpdateR = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY ); + m_textCtrlUpdateR->SetFont( wxFont( 8, 74, 90, 90, false, wxT("Tahoma") ) ); + m_textCtrlUpdateR->SetBackgroundColour( wxColour( 222, 222, 236 ) ); + m_textCtrlUpdateR->SetToolTip( _("Number of files that will be overwritten") ); + + fgSizer51->Add( m_textCtrlUpdateR, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlDeleteR = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY ); + m_textCtrlDeleteR->SetFont( wxFont( 8, 74, 90, 90, false, wxT("Tahoma") ) ); + m_textCtrlDeleteR->SetBackgroundColour( wxColour( 222, 222, 236 ) ); + m_textCtrlDeleteR->SetToolTip( _("Number of files and directories that will be deleted") ); + + fgSizer51->Add( m_textCtrlDeleteR, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer157->Add( fgSizer51, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); - fgSizer5->Add( m_textCtrlUpdate, 0, wxALIGN_CENTER_VERTICAL, 5 ); + sbSizer161->Add( bSizer157, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + + sbSizer161->Add( 0, 10, 0, 0, 5 ); + + wxBoxSizer* bSizer156; + bSizer156 = new wxBoxSizer( wxHORIZONTAL ); m_bitmapData = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); m_bitmapData->SetToolTip( _("Total amount of data that will be transferred") ); - fgSizer5->Add( m_bitmapData, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer156->Add( m_bitmapData, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxRIGHT, 5 ); + + + bSizer156->Add( 0, 0, 1, wxEXPAND, 5 ); m_textCtrlData = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY ); m_textCtrlData->SetFont( wxFont( 8, 74, 90, 90, false, wxT("Tahoma") ) ); m_textCtrlData->SetBackgroundColour( wxColour( 222, 222, 236 ) ); m_textCtrlData->SetToolTip( _("Total amount of data that will be transferred") ); - fgSizer5->Add( m_textCtrlData, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer156->Add( m_textCtrlData, 0, wxALIGN_CENTER_VERTICAL, 5 ); - sbSizer161->Add( fgSizer5, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - bSizer141->Add( sbSizer161, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + bSizer156->Add( 0, 0, 1, wxEXPAND, 5 ); + + sbSizer161->Add( bSizer156, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT|wxEXPAND, 5 ); + + bSizer141->Add( sbSizer161, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); - bSizer134->Add( bSizer141, 0, wxEXPAND, 5 ); + bSizer134->Add( bSizer141, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); m_staticline12 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - bSizer134->Add( m_staticline12, 0, wxEXPAND|wxBOTTOM, 5 ); + bSizer134->Add( m_staticline12, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 ); wxBoxSizer* bSizer142; bSizer142 = new wxBoxSizer( wxHORIZONTAL ); @@ -3377,3 +3712,27 @@ SyncPreviewDlgGenerated::~SyncPreviewDlgGenerated() m_buttonStartSync->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncPreviewDlgGenerated::OnStartSync ), NULL, this ); m_button16->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncPreviewDlgGenerated::OnCancel ), NULL, this ); } + +PopupFrameGenerated1::PopupFrameGenerated1( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetBackgroundColour( wxColour( 255, 255, 255 ) ); + + wxBoxSizer* bSizer158; + bSizer158 = new wxBoxSizer( wxHORIZONTAL ); + + m_bitmapLeft = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); + 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 ); + bSizer158->Add( m_staticTextMain, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + + this->SetSizer( bSizer158 ); + this->Layout(); + bSizer158->Fit( this ); +} + +PopupFrameGenerated1::~PopupFrameGenerated1() +{ +} diff --git a/ui/guiGenerated.h b/ui/guiGenerated.h index 5230128b..79c07c47 100644 --- a/ui/guiGenerated.h +++ b/ui/guiGenerated.h @@ -24,25 +24,25 @@ class wxButtonWithImage; #include #include #include +#include #include #include -#include #include -#include -#include #include #include #include -#include +#include #include #include #include #include #include #include +#include #include #include #include +#include #include #include #include @@ -76,15 +76,14 @@ class MainDialogGenerated : public wxFrame wxPanel* m_panel71; wxBoxSizer* bSizer6; + wxStaticText* m_staticTextCmpVariant; + wxButtonWithImage* m_buttonCompare; wxButton* m_buttonAbort; - wxRadioButton* m_radioBtnSizeDate; - wxRadioButton* m_radioBtnContent; - wxBitmapButton* m_bpButton14; - + wxBitmapButton* m_bpButtonCmpConfig; - wxStaticText* m_staticTextVariant; + wxStaticText* m_staticTextSyncVariant; wxBitmapButton* m_bpButtonSyncConfig; wxButtonWithImage* m_buttonStartSync; @@ -101,10 +100,8 @@ class MainDialogGenerated : public wxFrame wxBitmapButton* m_bpButtonRemoveTopPair; wxComboBox* m_directoryRight; wxDirPickerCtrl* m_dirPickerRight; - wxBoxSizer* bSizer106; - wxStaticBitmap* m_bitmapShift; wxScrolledWindow* m_scrolledWindowFolderPairs; - wxBoxSizer* bSizerFolderPairs; + wxBoxSizer* bSizerAddFolderPairs; wxPanel* m_panelLeft; CustomGridLeft* m_gridLeft; wxPanel* m_panelMiddle; @@ -129,9 +126,13 @@ class MainDialogGenerated : public wxFrame 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; wxBoxSizer* bSizerBottomRight; @@ -165,18 +166,15 @@ 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 OnMenuSaveConfig( wxCommandEvent& event ){ event.Skip(); } - virtual void OnMenuLoadConfig( 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(); } virtual void OnMenuGlobalSettings( wxCommandEvent& event ){ event.Skip(); } virtual void OnMenuBatchJob( wxCommandEvent& event ){ event.Skip(); } virtual void OnMenuExportFileList( wxCommandEvent& event ){ event.Skip(); } virtual void OnMenuCheckVersion( wxCommandEvent& event ){ event.Skip(); } virtual void OnMenuAbout( wxCommandEvent& event ){ event.Skip(); } - virtual void OnAbortCompare( wxCommandEvent& event ){ event.Skip(); } - virtual void OnCompareByTimeSize( wxCommandEvent& event ){ event.Skip(); } - virtual void OnCompareByContent( wxCommandEvent& event ){ event.Skip(); } - virtual void OnShowHelpDialog( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCmpSettings( wxCommandEvent& event ){ event.Skip(); } virtual void OnSyncSettings( wxCommandEvent& event ){ event.Skip(); } virtual void OnFolderHistoryKeyEvent( wxKeyEvent& event ){ event.Skip(); } virtual void OnDirSelected( wxFileDirPickerEvent& event ){ event.Skip(); } @@ -193,8 +191,6 @@ class MainDialogGenerated : public wxFrame virtual void OnRightGridDoubleClick( wxGridEvent& event ){ event.Skip(); } virtual void OnSortRightGrid( wxGridEvent& event ){ event.Skip(); } virtual void OnContextRimLabelRight( wxGridEvent& event ){ event.Skip(); } - virtual void OnSaveConfig( wxCommandEvent& event ){ event.Skip(); } - virtual void OnLoadConfig( wxCommandEvent& event ){ event.Skip(); } virtual void OnCfgHistoryKeyEvent( wxKeyEvent& event ){ event.Skip(); } virtual void OnLoadFromHistory( wxCommandEvent& event ){ event.Skip(); } virtual void OnFilterButton( wxCommandEvent& event ){ event.Skip(); } @@ -206,9 +202,13 @@ class MainDialogGenerated : public wxFrame virtual void OnDifferentFiles( wxCommandEvent& event ){ event.Skip(); } virtual void OnRightNewerFiles( wxCommandEvent& event ){ event.Skip(); } virtual void OnRightOnlyFiles( wxCommandEvent& event ){ event.Skip(); } + virtual void OnSyncCreateLeft( wxCommandEvent& event ){ event.Skip(); } virtual void OnSyncDirLeft( wxCommandEvent& event ){ event.Skip(); } + virtual void OnSyncDeleteLeft( wxCommandEvent& event ){ event.Skip(); } virtual void OnSyncDirNone( wxCommandEvent& event ){ event.Skip(); } + virtual void OnSyncDeleteRight( wxCommandEvent& event ){ event.Skip(); } virtual void OnSyncDirRight( wxCommandEvent& event ){ event.Skip(); } + virtual void OnSyncCreateRight( wxCommandEvent& event ){ event.Skip(); } virtual void OnConflictFiles( wxCommandEvent& event ){ event.Skip(); } virtual void OnQuit( wxCommandEvent& event ){ event.Skip(); } @@ -253,12 +253,15 @@ class BatchFolderPairGenerated : public wxPanel private: protected: + wxPanel* m_panel32; wxStaticText* m_staticText53; - wxPanel* m_panelLeft; wxStaticText* m_staticText541; + wxPanel* m_panelLeft; wxPanel* m_panelRight; + public: + wxBitmapButton* m_bpButtonRemovePair; wxTextCtrl* m_directoryLeft; wxDirPickerCtrl* m_dirPickerLeft; wxTextCtrl* m_directoryRight; @@ -289,20 +292,28 @@ class BatchDlgGenerated : public wxDialog wxNotebook* m_notebookSettings; wxPanel* m_panelOverview; wxScrolledWindow* m_scrolledWindow6; - wxBoxSizer* bSizerFolderPairs; + wxBoxSizer* sbSizerMainPair; + wxPanel* m_panelMainPair; + wxStaticText* m_staticText532; + wxStaticText* m_staticText5411; + wxPanel* m_panelLeft; + wxPanel* m_panelRight; + wxBoxSizer* bSizerAddFolderPairs; wxRadioButton* m_radioBtnSizeDate; wxRadioButton* m_radioBtnContent; - wxChoice* m_choiceHandleError; - - wxCheckBox* m_checkBoxUseRecycler; wxCheckBox* m_checkBoxFilter; wxCheckBox* m_checkBoxSilent; + wxChoice* m_choiceHandleError; + wxChoice* m_choiceHandleDeletion; + wxPanel* m_panelCustomDeletionDir; + wxTextCtrl* m_textCtrlCustomDelFolder; + wxDirPickerCtrl* m_dirPickerCustomDelFolder; wxStaticText* m_staticText21; wxStaticText* m_staticText31; @@ -341,11 +352,13 @@ 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 OnChangeErrorHandling( wxCommandEvent& event ){ event.Skip(); } - virtual void OnSelectRecycleBin( wxCommandEvent& event ){ event.Skip(); } virtual void OnCheckFilter( wxCommandEvent& event ){ event.Skip(); } virtual void OnCheckLogging( wxCommandEvent& event ){ event.Skip(); } + virtual void OnChangeErrorHandling( wxCommandEvent& event ){ event.Skip(); } + virtual void OnChangeDeletionHandling( wxCommandEvent& event ){ event.Skip(); } virtual void OnExLeftSideOnly( wxCommandEvent& event ){ event.Skip(); } virtual void OnExRightSideOnly( wxCommandEvent& event ){ event.Skip(); } virtual void OnLeftNewer( wxCommandEvent& event ){ event.Skip(); } @@ -357,6 +370,12 @@ class BatchDlgGenerated : public wxDialog public: + wxBitmapButton* m_bpButtonAddPair; + wxBitmapButton* m_bpButtonRemoveTopPair; + wxTextCtrl* m_directoryLeft; + wxDirPickerCtrl* m_dirPickerLeft; + wxTextCtrl* m_directoryRight; + wxDirPickerCtrl* m_dirPickerRight; BatchDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Create a batch job"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~BatchDlgGenerated(); @@ -387,7 +406,7 @@ class CompareStatusGenerated : public wxPanel wxStaticText* m_staticText37; wxStaticText* m_staticTextTimeElapsed; wxStaticText* m_staticText30; - wxTextCtrl* m_textCtrlFilename; + wxTextCtrl* m_textCtrlStatus; wxGauge* m_gauge2; public: @@ -397,9 +416,9 @@ class CompareStatusGenerated : public wxPanel }; /////////////////////////////////////////////////////////////////////////////// -/// Class SyncDlgGenerated +/// Class SyncCfgDlgGenerated /////////////////////////////////////////////////////////////////////////////// -class SyncDlgGenerated : public wxDialog +class SyncCfgDlgGenerated : public wxDialog { private: @@ -421,10 +440,14 @@ class SyncDlgGenerated : public wxDialog wxStaticText* m_staticText9; wxBoxSizer* bSizer201; - wxCheckBox* m_checkBoxUseRecycler; - wxCheckBox* m_checkBoxIgnoreErrors; + wxChoice* m_choiceHandleError; - wxButton* m_button6; + wxChoice* m_choiceHandleDeletion; + wxPanel* m_panelCustomDeletionDir; + wxTextCtrl* m_textCtrlCustomDelFolder; + wxDirPickerCtrl* m_dirPickerCustomDelFolder; + + wxButton* m_buttonApply; wxButton* m_button16; @@ -453,7 +476,8 @@ class SyncDlgGenerated : public wxDialog virtual void OnSyncUpdate( wxCommandEvent& event ){ event.Skip(); } virtual void OnSyncBothSides( wxCommandEvent& event ){ event.Skip(); } virtual void OnSyncCostum( wxCommandEvent& event ){ event.Skip(); } - virtual void OnSelectRecycleBin( wxCommandEvent& event ){ event.Skip(); } + virtual void OnChangeErrorHandling( wxCommandEvent& event ){ event.Skip(); } + virtual void OnChangeDeletionHandling( wxCommandEvent& event ){ event.Skip(); } virtual void OnApply( wxCommandEvent& event ){ event.Skip(); } virtual void OnCancel( wxCommandEvent& event ){ event.Skip(); } virtual void OnExLeftSideOnly( wxCommandEvent& event ){ event.Skip(); } @@ -464,8 +488,39 @@ class SyncDlgGenerated : public wxDialog public: - SyncDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Synchronization settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE ); - ~SyncDlgGenerated(); + SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Synchronization settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~SyncCfgDlgGenerated(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CmpCfgDlgGenerated +/////////////////////////////////////////////////////////////////////////////// +class CmpCfgDlgGenerated : public wxDialog +{ + private: + + protected: + wxRadioButton* m_radioBtnSizeDate; + wxButton* m_buttonTimeSize; + wxRadioButton* m_radioBtnContent; + wxButton* m_buttonContent; + wxStaticLine* m_staticline14; + wxBitmapButton* m_bpButtonHelp; + + wxButton* m_button6; + + // Virtual event handlers, overide them in your derived class + virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } + virtual void OnTimeSize( wxCommandEvent& event ){ event.Skip(); } + virtual void OnContent( wxCommandEvent& event ){ event.Skip(); } + virtual void OnShowHelp( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCancel( wxCommandEvent& event ){ event.Skip(); } + + + public: + CmpCfgDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Comparison settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + ~CmpCfgDlgGenerated(); }; @@ -588,7 +643,8 @@ class AboutDlgGenerated : public wxDialog wxStaticText* m_staticText15; wxStaticText* m_build; - wxScrolledWindow* m_scrolledWindow4; + wxScrolledWindow* m_scrolledWindowCodeInfo; + wxBoxSizer* bSizerCodeInfo; wxStaticText* m_staticText72; wxStaticText* m_staticText73; wxStaticText* m_staticText74; @@ -598,14 +654,15 @@ class AboutDlgGenerated : public wxDialog wxFlexGridSizer* fgSizerTranslators; wxStaticLine* m_staticline3; - wxPanel* m_panel22; wxStaticText* m_staticText131; wxStaticLine* m_staticline12; wxStaticBitmap* m_bitmap9; wxHyperlinkCtrl* m_hyperlink1; + wxHyperlinkCtrl* m_hyperlink6; wxStaticBitmap* m_bitmap10; wxHyperlinkCtrl* m_hyperlink2; + wxAnimationCtrl* m_animationControl1; wxHyperlinkCtrl* m_hyperlink3; wxStaticLine* m_staticline2; @@ -613,7 +670,7 @@ class AboutDlgGenerated : public wxDialog wxStaticBitmap* m_bitmap13; wxHyperlinkCtrl* m_hyperlink5; - wxButton* m_button8; + wxButton* m_buttonOkay; // Virtual event handlers, overide them in your derived class virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } @@ -652,7 +709,7 @@ class ErrorDlgGenerated : public wxDialog public: - ErrorDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Error"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 404,268 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ErrorDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Error"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 420,270 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~ErrorDlgGenerated(); }; @@ -682,7 +739,7 @@ class WarningDlgGenerated : public wxDialog public: wxStaticBitmap* m_bitmap10; - WarningDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Warning"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 382,249 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + WarningDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Warning"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 420,270 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~WarningDlgGenerated(); }; @@ -713,7 +770,7 @@ class QuestionDlgGenerated : public wxDialog public: - QuestionDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Question"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 391,237 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + QuestionDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Question"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 420,260 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~QuestionDlgGenerated(); }; @@ -853,14 +910,14 @@ class GlobalSettingsDlgGenerated : public wxDialog wxCheckBox* m_checkBoxIgnoreOneHour; wxStaticLine* m_staticline10; - wxStaticText* m_staticText97; - wxTextCtrl* m_textCtrlFileManager; + wxStaticText* m_staticTextCommand; + wxTextCtrl* m_textCtrlCommand; wxStaticLine* m_staticline101; wxStaticText* m_staticText100; wxButtonWithImage* m_buttonResetWarnings; - wxButton* m_button28; + wxButton* m_buttonOkay; wxButton* m_button9; wxButton* m_button29; @@ -886,18 +943,27 @@ class SyncPreviewDlgGenerated : public wxDialog private: protected: - wxStaticText* m_staticTextVariant; wxButtonWithImage* m_buttonStartSync; + wxStaticLine* m_staticline16; + wxStaticText* m_staticTextVariant; wxStaticLine* m_staticline14; + wxStaticText* m_staticText94; wxStaticBitmap* m_bitmapCreate; - wxTextCtrl* m_textCtrlCreate; - wxStaticBitmap* m_bitmapDelete; - wxTextCtrl* m_textCtrlDelete; + wxTextCtrl* m_textCtrlCreateL; wxStaticBitmap* m_bitmapUpdate; - wxTextCtrl* m_textCtrlUpdate; + wxTextCtrl* m_textCtrlUpdateL; + wxStaticBitmap* m_bitmapDelete; + wxTextCtrl* m_textCtrlDeleteL; + wxStaticText* m_staticText95; + wxTextCtrl* m_textCtrlCreateR; + wxTextCtrl* m_textCtrlUpdateR; + wxTextCtrl* m_textCtrlDeleteR; + wxStaticBitmap* m_bitmapData; + wxTextCtrl* m_textCtrlData; + wxStaticLine* m_staticline12; wxCheckBox* m_checkBoxDontShowAgain; @@ -915,4 +981,21 @@ class SyncPreviewDlgGenerated : public wxDialog }; +/////////////////////////////////////////////////////////////////////////////// +/// Class PopupFrameGenerated1 +/////////////////////////////////////////////////////////////////////////////// +class PopupFrameGenerated1 : public wxFrame +{ + private: + + protected: + + public: + wxStaticBitmap* m_bitmapLeft; + wxStaticText* m_staticTextMain; + PopupFrameGenerated1( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxFRAME_NO_TASKBAR|wxSTAY_ON_TOP|wxSTATIC_BORDER ); + ~PopupFrameGenerated1(); + +}; + #endif //__guiGenerated__ diff --git a/ui/guiStatusHandler.cpp b/ui/guiStatusHandler.cpp index 7929c122..280328da 100644 --- a/ui/guiStatusHandler.cpp +++ b/ui/guiStatusHandler.cpp @@ -1,8 +1,8 @@ #include "guiStatusHandler.h" -#include "../library/customButton.h" #include "smallDialogs.h" -#include "../library/globalFunctions.h" +#include "../shared/globalFunctions.h" #include "mainDialog.h" +#include CompareStatusHandler::CompareStatusHandler(MainDialog* dlg) : @@ -10,47 +10,10 @@ CompareStatusHandler::CompareStatusHandler(MainDialog* dlg) : ignoreErrors(false), currentProcess(StatusHandler::PROCESS_NONE) { + wxWindowUpdateLocker dummy(mainDialog); //avoid display distortion + //prevent user input during "compare", do not disable maindialog since abort-button would also be disabled - //it's not nice, but works - mainDialog->m_notebookBottomLeft->Disable(); - mainDialog->m_radioBtnSizeDate->Disable(); - mainDialog->m_radioBtnContent->Disable(); - mainDialog->m_bpButtonFilter->Disable(); - mainDialog->m_hyperlinkCfgFilter->Disable(); - mainDialog->m_checkBoxHideFilt->Disable(); - mainDialog->m_bpButtonSyncConfig->Disable(); - mainDialog->m_buttonStartSync->Disable(); - mainDialog->m_dirPickerLeft->Disable(); - mainDialog->m_dirPickerRight->Disable(); - mainDialog->m_bpButtonSwapSides->Disable(); - mainDialog->m_bpButtonLeftOnly->Disable(); - mainDialog->m_bpButtonLeftNewer->Disable(); - mainDialog->m_bpButtonEqual->Disable(); - mainDialog->m_bpButtonDifferent->Disable(); - mainDialog->m_bpButtonRightNewer->Disable(); - mainDialog->m_bpButtonRightOnly->Disable(); - mainDialog->m_panelLeft->Disable(); - mainDialog->m_panelMiddle->Disable(); - mainDialog->m_panelRight->Disable(); - mainDialog->m_panelTopLeft->Disable(); - mainDialog->m_panelTopMiddle->Disable(); - mainDialog->m_panelTopRight->Disable(); - mainDialog->m_bpButtonSave->Disable(); - mainDialog->m_bpButtonLoad->Disable(); - mainDialog->m_choiceHistory->Disable(); - mainDialog->m_bpButton10->Disable(); - mainDialog->m_bpButton14->Disable(); - mainDialog->m_scrolledWindowFolderPairs->Disable(); - mainDialog->m_menubar1->EnableTop(0, false); - mainDialog->m_menubar1->EnableTop(1, false); - mainDialog->m_menubar1->EnableTop(2, false); - - //show abort button - mainDialog->m_buttonAbort->Enable(); - mainDialog->m_buttonAbort->Show(); - mainDialog->m_buttonCompare->Disable(); - mainDialog->m_buttonCompare->Hide(); - mainDialog->m_buttonAbort->SetFocus(); + mainDialog->disableAllElements(); //display status panel during compare mainDialog->compareStatus->init(); //clear old values @@ -59,65 +22,34 @@ CompareStatusHandler::CompareStatusHandler(MainDialog* dlg) : mainDialog->bSizer1->Layout(); //both sizers need to recalculate! mainDialog->bSizer6->Layout(); //adapt layout for wxBitmapWithImage mainDialog->Refresh(); + + //register abort button + mainDialog->m_buttonAbort->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CompareStatusHandler::OnAbortCompare ), NULL, this ); } CompareStatusHandler::~CompareStatusHandler() { - //ATTENTION don't call wxAPP->Yield()! at this point in time there is a mismatch between - //gridDataView and currentGridData!! avoid grid repaint at all costs!! + //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!! - //just DON'T: updateUiNow(); //ui update before enabling buttons again: prevent strange behaviour of delayed button clicks + updateUiNow(); //ui update before enabling buttons again: prevent strange behaviour of delayed button clicks //reenable complete main dialog - mainDialog->m_notebookBottomLeft->Enable(); - mainDialog->m_radioBtnSizeDate->Enable(); - mainDialog->m_radioBtnContent->Enable(); - mainDialog->m_bpButtonFilter->Enable(); - mainDialog->m_hyperlinkCfgFilter->Enable(); - mainDialog->m_checkBoxHideFilt->Enable(); - mainDialog->m_bpButtonSyncConfig->Enable(); - mainDialog->m_buttonStartSync->Enable(); - mainDialog->m_dirPickerLeft->Enable(); - mainDialog->m_dirPickerRight->Enable(); - mainDialog->m_bpButtonSwapSides->Enable(); - mainDialog->m_bpButtonLeftOnly->Enable(); - mainDialog->m_bpButtonLeftNewer->Enable(); - mainDialog->m_bpButtonEqual->Enable(); - mainDialog->m_bpButtonDifferent->Enable(); - mainDialog->m_bpButtonRightNewer->Enable(); - mainDialog->m_bpButtonRightOnly->Enable(); - mainDialog->m_panelLeft->Enable(); - mainDialog->m_panelMiddle->Enable(); - mainDialog->m_panelRight->Enable(); - mainDialog->m_panelTopLeft->Enable(); - mainDialog->m_panelTopMiddle->Enable(); - mainDialog->m_panelTopRight->Enable(); - mainDialog->m_bpButtonSave->Enable(); - mainDialog->m_bpButtonLoad->Enable(); - mainDialog->m_choiceHistory->Enable(); - mainDialog->m_bpButton10->Enable(); - mainDialog->m_bpButton14->Enable(); - mainDialog->m_scrolledWindowFolderPairs->Enable(); - mainDialog->m_menubar1->EnableTop(0, true); - mainDialog->m_menubar1->EnableTop(1, true); - mainDialog->m_menubar1->EnableTop(2, true); + mainDialog->enableAllElements(); if (abortIsRequested()) mainDialog->pushStatusInformation(_("Operation aborted!")); - mainDialog->m_buttonAbort->Disable(); - mainDialog->m_buttonAbort->Hide(); - mainDialog->m_buttonCompare->Enable(); //enable compare button - mainDialog->m_buttonCompare->Show(); - //hide status panel from main window mainDialog->compareStatus->Hide(); mainDialog->bSizer6->Layout(); //adapt layout for wxBitmapWithImage - mainDialog->Layout(); mainDialog->Refresh(); + + //de-register abort button + mainDialog->m_buttonAbort->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CompareStatusHandler::OnAbortCompare ), NULL, this ); } @@ -167,7 +99,7 @@ void CompareStatusHandler::updateProcessedData(int objectsProcessed, wxLongLong } -ErrorHandler::Response CompareStatusHandler::reportError(const Zstring& text) +ErrorHandler::Response CompareStatusHandler::reportError(const wxString& message) { if (ignoreErrors) return ErrorHandler::IGNORE_ERROR; @@ -175,7 +107,7 @@ ErrorHandler::Response CompareStatusHandler::reportError(const Zstring& text) mainDialog->compareStatus->updateStatusPanelNow(); bool ignoreNextErrors = false; - wxString errorMessage = wxString(text.c_str()) + wxT("\n\n") + _("Ignore this error, retry or abort?"); + const wxString errorMessage = message + wxT("\n\n\n") + _("Ignore this error, retry or abort?"); ErrorDlg* errorDlg = new ErrorDlg(mainDialog, ErrorDlg::BUTTON_IGNORE | ErrorDlg::BUTTON_RETRY | ErrorDlg::BUTTON_ABORT, errorMessage, ignoreNextErrors); @@ -198,22 +130,22 @@ ErrorHandler::Response CompareStatusHandler::reportError(const Zstring& text) } -void CompareStatusHandler::reportFatalError(const Zstring& errorMessage) +void CompareStatusHandler::reportFatalError(const wxString& errorMessage) { mainDialog->compareStatus->updateStatusPanelNow(); bool dummy = false; ErrorDlg* errorDlg = new ErrorDlg(mainDialog, ErrorDlg::BUTTON_ABORT, - errorMessage.c_str(), dummy); + errorMessage, dummy); errorDlg->ShowModal(); abortThisProcess(); } -void CompareStatusHandler::reportWarning(const Zstring& warningMessage, bool& dontShowAgain) +void CompareStatusHandler::reportWarning(const wxString& warningMessage, bool& warningActive) { - if (ignoreErrors) //if errors are ignored, then warnings should also + if (!warningActive || ignoreErrors) //if errors are ignored, then warnings should also return; mainDialog->compareStatus->updateStatusPanelNow(); @@ -222,19 +154,18 @@ void CompareStatusHandler::reportWarning(const Zstring& warningMessage, bool& do bool dontWarnAgain = false; WarningDlg* warningDlg = new WarningDlg(mainDialog, WarningDlg::BUTTON_IGNORE | WarningDlg::BUTTON_ABORT, - warningMessage.c_str(), + warningMessage, dontWarnAgain); - switch (warningDlg->ShowModal()) + switch (static_cast(warningDlg->ShowModal())) { case WarningDlg::BUTTON_ABORT: abortThisProcess(); + break; case WarningDlg::BUTTON_IGNORE: - dontShowAgain = dontWarnAgain; - return; + warningActive = !dontWarnAgain; + break; } - - assert(false); } @@ -245,6 +176,12 @@ void CompareStatusHandler::forceUiRefresh() } +void CompareStatusHandler::OnAbortCompare(wxCommandEvent& event) +{ + requestAbortion(); +} + + void CompareStatusHandler::abortThisProcess() { requestAbortion(); @@ -265,23 +202,24 @@ SyncStatusHandler::SyncStatusHandler(wxWindow* dlg, bool ignoreAllErrors) : SyncStatusHandler::~SyncStatusHandler() { //print the results list - unsigned int failedItems = unhandledErrors.GetCount(); wxString result; - if (failedItems) + if (errorLog.messageCount() > 0) { - result = wxString(_("Warning: Synchronization failed for %x item(s):")) + wxT("\n\n"); - result.Replace(wxT("%x"), globalFunctions::numberToWxString(failedItems), false); - - for (unsigned int j = 0; j < failedItems; ++j) - { //remove linebreaks - wxString errorMessage = unhandledErrors[j]; - for (wxString::iterator i = errorMessage.begin(); i != errorMessage.end(); ++i) - if (*i == wxChar('\n')) - *i = wxChar(' '); + if (errorLog.errorsTotal() > 0) + { + wxString header(_("Warning: Synchronization failed for %x item(s):")); + header.Replace(wxT("%x"), globalFunctions::numberToWxString(errorLog.errorsTotal()), false); + result += header + wxT("\n\n"); + } - result += errorMessage + wxT("\n"); + const std::vector& messages = errorLog.getFormattedMessages(); + for (std::vector::const_iterator i = messages.begin(); i != messages.end(); ++i) + { + result += *i; + result += wxChar('\n'); } - result+= wxT("\n"); + + result += wxT("\n"); } //notify to syncStatusFrame that current process has ended @@ -291,7 +229,7 @@ SyncStatusHandler::~SyncStatusHandler() syncStatusFrame->setStatusText_NoUpdate(result.c_str()); syncStatusFrame->processHasFinished(SyncStatus::ABORTED); //enable okay and close events } - else if (failedItems) + 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)!"); syncStatusFrame->setStatusText_NoUpdate(result.c_str()); @@ -337,14 +275,11 @@ void SyncStatusHandler::updateProcessedData(int objectsProcessed, wxLongLong dat } -ErrorHandler::Response SyncStatusHandler::reportError(const Zstring& text) +ErrorHandler::Response SyncStatusHandler::reportError(const wxString& errorMessage) { - //add current time before error message - wxString errorWithTime = wxString(wxT("[")) + wxDateTime::Now().FormatTime() + wxT("] ") + text.c_str(); - if (ignoreErrors) { - unhandledErrors.Add(errorWithTime); + errorLog.logError(errorMessage); return ErrorHandler::IGNORE_ERROR; } @@ -353,66 +288,65 @@ ErrorHandler::Response SyncStatusHandler::reportError(const Zstring& text) bool ignoreNextErrors = false; ErrorDlg* errorDlg = new ErrorDlg(syncStatusFrame, ErrorDlg::BUTTON_IGNORE | ErrorDlg::BUTTON_RETRY | ErrorDlg::BUTTON_ABORT, - wxString(text) + wxT("\n\n") + _("Ignore this error, retry or abort synchronization?"), + errorMessage + wxT("\n\n\n") + _("Ignore this error, retry or abort synchronization?"), ignoreNextErrors); - int rv = errorDlg->ShowModal(); - switch (rv) + switch (static_cast(errorDlg->ShowModal())) { case ErrorDlg::BUTTON_IGNORE: ignoreErrors = ignoreNextErrors; - unhandledErrors.Add(errorWithTime); + errorLog.logError(errorMessage); return ErrorHandler::IGNORE_ERROR; case ErrorDlg::BUTTON_RETRY: return ErrorHandler::RETRY; case ErrorDlg::BUTTON_ABORT: - unhandledErrors.Add(errorWithTime); + errorLog.logError(errorMessage); abortThisProcess(); } assert (false); - unhandledErrors.Add(errorWithTime); + errorLog.logError(errorMessage); return ErrorHandler::IGNORE_ERROR; } -void SyncStatusHandler::reportFatalError(const Zstring& errorMessage) -{ //add current time before error message - wxString errorWithTime = wxString(wxT("[")) + wxDateTime::Now().FormatTime() + wxT("] ") + errorMessage.c_str(); - - unhandledErrors.Add(errorWithTime); +void SyncStatusHandler::reportFatalError(const wxString& errorMessage) +{ + errorLog.logError(errorMessage); abortThisProcess(); } -void SyncStatusHandler::reportWarning(const Zstring& warningMessage, bool& dontShowAgain) -{ //add current time before warning message - wxString warningWithTime = wxString(wxT("[")) + wxDateTime::Now().FormatTime() + wxT("] ") + warningMessage.c_str(); - - if (ignoreErrors) //if errors are ignored, then warnings should also - return; //no unhandled error situation! - - syncStatusFrame->updateStatusDialogNow(); +void SyncStatusHandler::reportWarning(const wxString& warningMessage, bool& warningActive) +{ + errorLog.logWarning(warningMessage); - //show popup and ask user how to handle warning - bool dontWarnAgain = false; - WarningDlg* warningDlg = new WarningDlg(syncStatusFrame, - WarningDlg::BUTTON_IGNORE | WarningDlg::BUTTON_ABORT, - warningMessage.c_str(), - dontWarnAgain); - switch (warningDlg->ShowModal()) - { - case WarningDlg::BUTTON_IGNORE: //no unhandled error situation! - dontShowAgain = dontWarnAgain; + if (ignoreErrors || !warningActive) //if errors are ignored, then warnings should also return; + else + { + syncStatusFrame->updateStatusDialogNow(); + + //show popup and ask user how to handle warning + bool dontWarnAgain = false; + WarningDlg* warningDlg = new WarningDlg(syncStatusFrame, + WarningDlg::BUTTON_IGNORE | WarningDlg::BUTTON_ABORT, + warningMessage, + dontWarnAgain); + switch (static_cast(warningDlg->ShowModal())) + { + case WarningDlg::BUTTON_IGNORE: //no unhandled error situation! + warningActive = !dontWarnAgain; + return; + + case WarningDlg::BUTTON_ABORT: + abortThisProcess(); + return; + } - case WarningDlg::BUTTON_ABORT: - unhandledErrors.Add(warningWithTime); - abortThisProcess(); + assert(false); } - - assert(false); } diff --git a/ui/guiStatusHandler.h b/ui/guiStatusHandler.h index 51a87c98..eb067102 100644 --- a/ui/guiStatusHandler.h +++ b/ui/guiStatusHandler.h @@ -2,14 +2,17 @@ #define GUISTATUSHANDLER_H_INCLUDED #include "../library/statusHandler.h" -#include +#include +#include "../library/errorLogging.h" class SyncStatus; class MainDialog; class wxWindow; +class wxCommandEvent; + //classes handling sync and compare error as well as status information -class CompareStatusHandler : public StatusHandler +class CompareStatusHandler : private wxEvtHandler, public StatusHandler { public: CompareStatusHandler(MainDialog* dlg); @@ -20,11 +23,12 @@ public: virtual void updateProcessedData(int objectsProcessed, wxLongLong dataProcessed); virtual void forceUiRefresh(); - virtual ErrorHandler::Response reportError(const Zstring& text); - virtual void reportFatalError(const Zstring& errorMessage); - virtual void reportWarning(const Zstring& warningMessage, bool& dontShowAgain); + virtual ErrorHandler::Response reportError(const wxString& text); + virtual void reportFatalError(const wxString& errorMessage); + virtual void reportWarning(const wxString& warningMessage, bool& warningActive); private: + void OnAbortCompare(wxCommandEvent& event); //handle abort button click virtual void abortThisProcess(); MainDialog* mainDialog; @@ -44,16 +48,16 @@ public: virtual void updateProcessedData(int objectsProcessed, wxLongLong dataProcessed); virtual void forceUiRefresh(); - virtual ErrorHandler::Response reportError(const Zstring& text); - virtual void reportFatalError(const Zstring& errorMessage); - virtual void reportWarning(const Zstring& warningMessage, bool& dontShowAgain); + virtual ErrorHandler::Response reportError(const wxString& text); + virtual void reportFatalError(const wxString& errorMessage); + virtual void reportWarning(const wxString& warningMessage, bool& warningActive); private: virtual void abortThisProcess(); SyncStatus* syncStatusFrame; bool ignoreErrors; - wxArrayString unhandledErrors; //list of non-resolved errors + FreeFileSync::ErrorLogging errorLog; }; diff --git a/ui/sorting.h b/ui/sorting.h index 2716eceb..c3cf8f97 100644 --- a/ui/sorting.h +++ b/ui/sorting.h @@ -2,8 +2,7 @@ #define SORTING_H_INCLUDED #include "../structures.h" -#include "../library/resources.h" -#include "../library/globalFunctions.h" +#include "../shared/globalFunctions.h" namespace FreeFileSync @@ -14,31 +13,15 @@ namespace FreeFileSync SORT_ON_RIGHT, }; - enum SortDirection - { - ASCENDING, - DESCENDING, - }; - - template inline - bool stringSmallerThan(const wxChar* stringA, const wxChar* stringB) + bool stringSmallerThan(const DefaultChar* stringA, const DefaultChar* stringB) { -#ifdef FFS_WIN //case-insensitive comparison! - return sortAscending == ASCENDING ? - FreeFileSync::compareStringsWin32(stringA, stringB) < 0 : //way faster than wxString::CmpNoCase() in windows build!!! - FreeFileSync::compareStringsWin32(stringA, stringB) > 0; +#ifdef FFS_WIN + //case-insensitive comparison! + return FreeFileSync::compareStringsWin32(stringA, stringB) < 0; //way faster than wxString::CmpNoCase() in windows build!!! #else - while (*stringA == *stringB) - { - if (*stringA == wxChar(0)) //strings are equal - return false; - - ++stringA; - ++stringB; - } - return sortAscending == ASCENDING ? *stringA < *stringB : *stringA > *stringB; //wxChar(0) is handled correctly + return defaultCompare(stringA, stringB) < 0; #endif } @@ -46,7 +29,8 @@ namespace FreeFileSync inline int compareString(const wxChar* stringA, const wxChar* stringB, const int lengthA, const int lengthB) { -#ifdef FFS_WIN //case-insensitive comparison! +#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) @@ -55,11 +39,15 @@ namespace FreeFileSync 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 } - template + template inline bool sortByFileName(const FileCompareLine& a, const FileCompareLine& b) { @@ -76,7 +64,7 @@ namespace FreeFileSync 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()); + return stringSmallerThan(descrLineA->relativeName.c_str(), descrLineB->relativeName.c_str()); else return false; } @@ -89,21 +77,21 @@ namespace FreeFileSync const wxChar* stringA = descrLineA->relativeName.c_str(); const wxChar* stringB = descrLineB->relativeName.c_str(); - size_t pos = descrLineA->relativeName.findFromEnd(FreeFileSync::FILE_NAME_SEPARATOR); //start search beginning from end + 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(FreeFileSync::FILE_NAME_SEPARATOR); //start search beginning from end + 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 stringSmallerThan(stringA, stringB); } } } - template + template bool sortByRelativeName(const FileCompareLine& a, const FileCompareLine& b) { const FileDescrLine* const descrLineA = side == SORT_ON_LEFT ? &a.fileDescrLeft : &a.fileDescrRight; @@ -119,7 +107,7 @@ namespace FreeFileSync relLengthA = descrLineA->relativeName.length(); else if (descrLineA->objType == FileDescrLine::TYPE_FILE) { - relLengthA = descrLineA->relativeName.findFromEnd(FreeFileSync::FILE_NAME_SEPARATOR); //start search beginning from end + relLengthA = descrLineA->relativeName.findFromEnd(globalFunctions::FILE_NAME_SEPARATOR); //start search beginning from end if (relLengthA == wxNOT_FOUND) { relLengthA = 0; @@ -144,7 +132,7 @@ namespace FreeFileSync relLengthB = descrLineB->relativeName.length(); else if (descrLineB->objType == FileDescrLine::TYPE_FILE) { - relLengthB = descrLineB->relativeName.findFromEnd(FreeFileSync::FILE_NAME_SEPARATOR); //start search beginning from end + relLengthB = descrLineB->relativeName.findFromEnd(globalFunctions::FILE_NAME_SEPARATOR); //start search beginning from end if (relLengthB == wxNOT_FOUND) { relLengthB = 0; @@ -162,7 +150,7 @@ namespace FreeFileSync //compare relative names without filenames first const int rv = compareString(relStringA, relStringB, relLengthA, relLengthB); if (rv != 0) - return sortAscending == ASCENDING ? rv < 0 : rv > 0; + return rv < 0; else //compare the filenames { if (descrLineB->objType == FileDescrLine::TYPE_DIRECTORY) //directories shall appear before files @@ -170,14 +158,12 @@ namespace FreeFileSync else if (descrLineA->objType == FileDescrLine::TYPE_DIRECTORY) return true; - return sortAscending == ASCENDING ? - compareString(fileStringA, fileStringB, fileLengthA, fileLengthB) < 0 : - compareString(fileStringA, fileStringB, fileLengthA, fileLengthB) > 0; + return compareString(fileStringA, fileStringB, fileLengthA, fileLengthB) < 0; } } - template + template inline bool sortByFullName(const FileCompareLine& a, const FileCompareLine& b) { @@ -191,18 +177,14 @@ namespace FreeFileSync return true; //empty rows always last else #ifdef FFS_WIN //case-insensitive comparison! - return sortAscending == ASCENDING ? - FreeFileSync::compareStringsWin32(descrLineA->fullName.c_str(), descrLineB->fullName.c_str()) < 0 : //way faster than wxString::CmpNoCase() in windows build!!! - FreeFileSync::compareStringsWin32(descrLineA->fullName.c_str(), descrLineB->fullName.c_str()) > 0; + return FreeFileSync::compareStringsWin32(descrLineA->fullName.c_str(), descrLineB->fullName.c_str()) < 0; //way faster than wxString::CmpNoCase() in windows build!!! #else - return sortAscending == ASCENDING ? - descrLineA->fullName.Cmp(descrLineB->fullName) < 0 : - descrLineA->fullName.Cmp(descrLineB->fullName) > 0; + return descrLineA->fullName.Cmp(descrLineB->fullName) < 0; #endif } - template + template inline bool sortByFileSize(const FileCompareLine& a, const FileCompareLine& b) { @@ -219,7 +201,7 @@ namespace FreeFileSync 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()); + return stringSmallerThan(descrLineA->relativeName.c_str(), descrLineB->relativeName.c_str()); else return false; } @@ -228,14 +210,12 @@ namespace FreeFileSync if (descrLineB->objType == FileDescrLine::TYPE_DIRECTORY) return true; else - return sortAscending == ASCENDING ? - descrLineA->fileSize > descrLineB->fileSize : //sortAscending shall result in list beginning with largest files first - descrLineA->fileSize < descrLineB->fileSize; + return descrLineA->fileSize > descrLineB->fileSize; //sortAscending shall result in list beginning with largest files first } } - template + template inline bool sortByDate(const FileCompareLine& a, const FileCompareLine& b) { @@ -251,7 +231,7 @@ namespace FreeFileSync 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()); + return stringSmallerThan(descrLineA->relativeName.c_str(), descrLineB->relativeName.c_str()); else return false; } @@ -260,14 +240,11 @@ namespace FreeFileSync if (descrLineB->objType == FileDescrLine::TYPE_DIRECTORY) return true; else - return sortAscending == ASCENDING ? - descrLineA->lastWriteTimeRaw > descrLineB->lastWriteTimeRaw : - descrLineA->lastWriteTimeRaw < descrLineB->lastWriteTimeRaw; + return descrLineA->lastWriteTimeRaw > descrLineB->lastWriteTimeRaw; } } - template inline bool sortByCmpResult(const FileCompareLine& a, const FileCompareLine& b) { @@ -277,37 +254,28 @@ namespace FreeFileSync if (b.cmpResult == FILE_EQUAL) return true; - return sortAscending == ASCENDING ? - a.cmpResult < b.cmpResult : - a.cmpResult > b.cmpResult; + return a.cmpResult < b.cmpResult; } - template inline bool sortBySyncDirection(const FileCompareLine& a, const FileCompareLine& b) { - return sortAscending == ASCENDING ? - a.direction < b.direction : - a.direction > b.direction; + return a.syncDir < b.syncDir; } - template + template inline bool sortByDirectory(const FolderCompareLine& a, const FolderCompareLine& b) { - const Zstring* const dirNameA = side == SORT_ON_LEFT ? &a.syncPair.leftDirectory : &a.syncPair.rightDirectory; - const Zstring* const dirNameB = side == SORT_ON_LEFT ? &b.syncPair.leftDirectory : &b.syncPair.rightDirectory; + 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 sortAscending == ASCENDING ? - FreeFileSync::compareStringsWin32(dirNameA->c_str(), dirNameB->c_str()) < 0 : //way faster than wxString::CmpNoCase() in windows build!!! - FreeFileSync::compareStringsWin32(dirNameA->c_str(), dirNameB->c_str()) > 0; + return FreeFileSync::compareStringsWin32(dirNameA.c_str(), dirNameB.c_str()) < 0; //way faster than wxString::CmpNoCase() in windows build!!! #elif defined FFS_LINUX - return sortAscending == ASCENDING ? - dirNameA->Cmp(*dirNameB) < 0 : - dirNameA->Cmp(*dirNameB) > 0; + return dirNameA.Cmp(dirNameB) < 0; #endif } } -- cgit