diff options
author | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 17:03:20 +0200 |
---|---|---|
committer | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 17:03:20 +0200 |
commit | 528635604eea1d8c679a3d038e2f00030ef72444 (patch) | |
tree | 9c3cbec29aa7d3e209939662e040b9342c9e7400 /ui | |
parent | 3.1 (diff) | |
download | FreeFileSync-528635604eea1d8c679a3d038e2f00030ef72444.tar.gz FreeFileSync-528635604eea1d8c679a3d038e2f00030ef72444.tar.bz2 FreeFileSync-528635604eea1d8c679a3d038e2f00030ef72444.zip |
3.2
Diffstat (limited to 'ui')
-rw-r--r-- | ui/MainDialog.cpp | 864 | ||||
-rw-r--r-- | ui/MainDialog.h | 30 | ||||
-rw-r--r-- | ui/SmallDialogs.cpp | 77 | ||||
-rw-r--r-- | ui/SmallDialogs.h | 9 | ||||
-rw-r--r-- | ui/folderPair.h | 174 | ||||
-rw-r--r-- | ui/guiGenerated.cpp | 252 | ||||
-rw-r--r-- | ui/guiGenerated.h | 88 | ||||
-rw-r--r-- | ui/settingsDialog.cpp | 248 | ||||
-rw-r--r-- | ui/settingsDialog.h | 13 | ||||
-rw-r--r-- | ui/sorting.h | 3 | ||||
-rw-r--r-- | ui/trayIcon.cpp | 4 | ||||
-rw-r--r-- | ui/trayIcon.h | 1 |
12 files changed, 1158 insertions, 605 deletions
diff --git a/ui/MainDialog.cpp b/ui/MainDialog.cpp index 7948da85..0d203453 100644 --- a/ui/MainDialog.cpp +++ b/ui/MainDialog.cpp @@ -7,6 +7,7 @@ #include <wx/ffile.h> #include "../library/customGrid.h" #include "../shared/customButton.h" +#include "../shared/customComboBox.h" #include <wx/msgdlg.h> #include "../comparison.h" #include "../synchronization.h" @@ -31,104 +32,159 @@ #include "../shared/toggleButton.h" #include "folderPair.h" #include "../shared/globalFunctions.h" +#include <wx/sound.h> using namespace FreeFileSync; using FreeFileSync::CustomLocale; -typedef FreeFileSync::FolderPairPanelBasic<FolderPairGenerated> FolderPairParent; +class MainFolderDragDrop : public DragDropOnMainDlg +{ +public: + MainFolderDragDrop(MainDialog& mainDlg, + wxWindow* dropWindow1, + wxWindow* dropWindow2, + wxDirPickerCtrl* dirPicker, + wxComboBox* dirName) : + + DragDropOnMainDlg(dropWindow1, dropWindow2, dirPicker, dirName), + mainDlg_(mainDlg) {} + + virtual bool AcceptDrop(const wxString& dropName) + { + const xmlAccess::XmlType fileType = xmlAccess::getXmlType(dropName); + + //test if ffs config file has been dropped + if (fileType == xmlAccess::XML_GUI_CONFIG) + { + mainDlg_.loadConfiguration(dropName); + return false; + } + //...or a ffs batch file + else if (fileType == xmlAccess::XML_BATCH_CONFIG) + { + BatchDialog* batchDlg = new BatchDialog(&mainDlg_, dropName); + if (batchDlg->ShowModal() == BatchDialog::BATCH_FILE_SAVED) + mainDlg_.pushStatusInformation(_("Batch file created successfully!")); + return false; + } + + //disable the sync button + mainDlg_.syncPreview.enableSynchronization(false); + + //clear grids + mainDlg_.gridDataView->clearAllRows(); + mainDlg_.updateGuiGrid(); + + return true; + } + +private: + MainFolderDragDrop(const MainFolderDragDrop&); + + MainDialog& mainDlg_; +}; + +//------------------------------------------------------------------ +/* class hierarchy: -class FolderPairPanel : public FolderPairParent + template<> + FolderPairPanelBasic + /|\ + | + template<> + FolderPairCallback FolderPairGenerated + /|\ /|\ + _________|________ ________| + | | | + FirstFolderPairCfg FolderPairPanel +*/ + +template <class GuiPanel> +class FolderPairCallback : public FolderPairPanelBasic<GuiPanel> //implements callback functionality to MainDialog as imposed by FolderPairPanelBasic { public: - FolderPairPanel(wxWindow* parent, MainDialog* mainDialog) : - FolderPairParent(parent), - mainDlg(mainDialog) - {} + FolderPairCallback(GuiPanel& basicPanel, MainDialog& mainDialog) : + FolderPairPanelBasic<GuiPanel>(basicPanel), //pass FolderPairGenerated part... + mainDlg(mainDialog) {} private: - virtual void OnAltFilterCfgRemoveConfirm(wxCommandEvent& event) + virtual void OnLocalFilterCfgRemoveConfirm(wxCommandEvent& event) { - FolderPairParent::OnAltFilterCfgRemoveConfirm(event); - mainDlg->updateFilterConfig(false); //update filter, leave activation status as it is + FolderPairPanelBasic<GuiPanel>::OnLocalFilterCfgRemoveConfirm(event); + mainDlg.updateFilterConfig(); //update filter } virtual void OnAltSyncCfgRemoveConfirm(wxCommandEvent& event) { - FolderPairParent::OnAltSyncCfgRemoveConfirm(event); - mainDlg->updateSyncConfig(); + FolderPairPanelBasic<GuiPanel>::OnAltSyncCfgRemoveConfirm(event); + mainDlg.updateSyncConfig(); } virtual wxWindow* getParentWindow() { - return mainDlg; + return &mainDlg; } virtual MainConfiguration getMainConfig() const { - return mainDlg->getCurrentConfiguration().mainCfg; + return mainDlg.getCurrentConfiguration().mainCfg; } virtual void OnAltSyncCfgChange() { - mainDlg->updateSyncConfig(); + mainDlg.updateSyncConfig(); } - virtual void OnAltFilterCfgChange(bool defaultValueSet) + virtual void OnLocalFilterCfgChange() { - if (defaultValueSet) //default - mainDlg->updateFilterConfig(false); //re-apply filter (without changing active-status) - else - mainDlg->updateFilterConfig(true); //activate(and apply) filter + mainDlg.updateFilterConfig(); //re-apply filter } - MainDialog* mainDlg; + MainDialog& mainDlg; }; -class MainFolderDragDrop : public DragDropOnMainDlg +class FolderPairPanel : + public FolderPairGenerated, //FolderPairPanel "owns" FolderPairGenerated! + public FolderPairCallback<FolderPairGenerated> { public: - MainFolderDragDrop(MainDialog* mainDlg, - wxWindow* dropWindow1, - wxWindow* dropWindow2, - wxDirPickerCtrl* dirPicker, - wxComboBox* dirName) : - - DragDropOnMainDlg(dropWindow1, dropWindow2, dirPicker, dirName), - mainDlg_(mainDlg) {} - - virtual bool AcceptDrop(const wxString& dropName) - { - const xmlAccess::XmlType fileType = xmlAccess::getXmlType(dropName); - - //test if ffs config file has been dropped - if (fileType == xmlAccess::XML_GUI_CONFIG) - { - mainDlg_->loadConfiguration(dropName); - return false; - } - //...or a ffs batch file - else if (fileType == xmlAccess::XML_BATCH_CONFIG) - { - BatchDialog* batchDlg = new BatchDialog(mainDlg_, dropName); - if (batchDlg->ShowModal() == BatchDialog::BATCH_FILE_SAVED) - mainDlg_->pushStatusInformation(_("Batch file created successfully!")); - return false; - } + FolderPairPanel(wxWindow* parent, MainDialog& mainDialog) : + FolderPairGenerated(parent), + FolderPairCallback<FolderPairGenerated>(static_cast<FolderPairGenerated&>(*this), mainDialog), //pass FolderPairGenerated part... + dragDropOnLeft( m_panelLeft, m_dirPickerLeft, m_directoryLeft), + dragDropOnRight(m_panelRight, m_dirPickerRight, m_directoryRight) {} - //disable the sync button - mainDlg_->syncPreview.enableSynchronization(false); +private: + //support for drag and drop + DragDropOnDlg dragDropOnLeft; + DragDropOnDlg dragDropOnRight; +}; - //clear grids - mainDlg_->gridDataView->clearAllRows(); - mainDlg_->updateGuiGrid(); - return true; - } +class FirstFolderPairCfg : public FolderPairCallback<MainDialogGenerated> +{ +public: + FirstFolderPairCfg(MainDialog& mainDialog) : + FolderPairCallback<MainDialogGenerated>(mainDialog, mainDialog), + + //prepare drag & drop + dragDropOnLeft(mainDialog, + mainDialog.m_panelLeft, + mainDialog.m_panelTopLeft, + mainDialog.m_dirPickerLeft, + mainDialog.m_directoryLeft), + dragDropOnRight(mainDialog, + mainDialog.m_panelRight, + mainDialog.m_panelTopRight, + mainDialog.m_dirPickerRight, + mainDialog.m_directoryRight) {} private: - MainDialog* mainDlg_; + //support for drag and drop + MainFolderDragDrop dragDropOnLeft; + MainFolderDragDrop dragDropOnRight; }; @@ -173,7 +229,10 @@ private: //################################################################################################################################## -MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, xmlAccess::XmlGlobalSettings& settings) : +MainDialog::MainDialog(wxFrame* frame, + const wxString& cfgFileName, + xmlAccess::XmlGlobalSettings& settings, + wxHelpController& helpController) : MainDialogGenerated(frame), globalSettings(settings), gridDataView(new FreeFileSync::GridView()), @@ -184,10 +243,14 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, xmlAccess::X #ifdef FFS_WIN updateFileIcons(new IconUpdater(m_gridLeft, m_gridRight)), #endif + helpController_(helpController), syncPreview(this) { wxWindowUpdateLocker dummy(this); //avoid display distortion + //init handling of first folder pair + firstFolderPair.reset(new FirstFolderPairCfg(*this)); + initViewFilterButtons(); //initialize and load configuration @@ -200,7 +263,6 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, xmlAccess::X //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_bpButtonCmpConfig->SetBitmapLabel(*GlobalResources::getInstance().bitmapCmpCfg); @@ -246,22 +308,6 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, xmlAccess::X m_menuLanguages->Append(newItem); } - - //prepare drag & drop - dragDropOnLeft.reset(new MainFolderDragDrop( - this, - m_panelLeft, - m_panelTopLeft, - m_dirPickerLeft, - m_directoryLeft)); - - dragDropOnRight.reset(new MainFolderDragDrop( - this, - m_panelRight, - m_panelTopRight, - m_dirPickerRight, - m_directoryRight)); - //support for CTRL + C and DEL m_gridLeft->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainDialog::onGridLeftButtonEvent), NULL, this); m_gridRight->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainDialog::onGridRightButtonEvent), NULL, this); @@ -297,7 +343,7 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, xmlAccess::X //correct width of swap button above middle grid const wxSize source = m_gridMiddle->GetSize(); - const wxSize target = bSizerMiddle->GetSize(); + const wxSize target = m_bpButtonSwapSides->GetSize(); const int spaceToAdd = source.GetX() - target.GetX(); bSizerMiddle->Insert(1, spaceToAdd / 2, 0, 0); bSizerMiddle->Insert(0, spaceToAdd - (spaceToAdd / 2), 0, 0); @@ -345,6 +391,8 @@ void MainDialog::readGlobalSettings() posXNotMaximized != wxDefaultCoord && posYNotMaximized != wxDefaultCoord) SetSize(posXNotMaximized, posYNotMaximized, widthNotMaximized, heightNotMaximized); + else + Centre(); Maximize(globalSettings.gui.isMaximized); @@ -421,7 +469,7 @@ void MainDialog::setSyncDirManually(const std::set<unsigned int>& rowsToSetOnUiT if (fsObj) { setSyncDirectionRec(dir, *fsObj); //set new direction (recursively) - FilterProcess::setActiveStatus(true, *fsObj); //works recursively for directories + FreeFileSync::setActiveStatus(true, *fsObj); //works recursively for directories } } @@ -449,7 +497,7 @@ void MainDialog::filterRangeManually(const std::set<unsigned int>& rowsToFilterO gridDataView->getAllFileRef(rowsToFilterOnUiTable, compRef); //everything in compRef is bound for (std::vector<FileSystemObject*>::iterator i = compRef.begin(); i != compRef.end(); ++i) - FilterProcess::setActiveStatus(newSelection, **i); //works recursively for directories + FreeFileSync::setActiveStatus(newSelection, **i); //works recursively for directories refreshGridAfterFilterChange(400); //call this instead of updateGuiGrid() to add some delay if hideFiltered == true and to handle some graphical artifacts } @@ -462,12 +510,16 @@ void MainDialog::OnIdleEvent(wxEvent& event) if (stackObjects.size() > 0 ) //check if there is some work to do { wxLongLong currentTime = wxGetLocalTimeMillis(); - if (currentTime - lastStatusChange > 2000) //restore stackObject after two seconds + if (currentTime - lastStatusChange > 2500) //restore stackObject after two seconds { lastStatusChange = currentTime; m_staticTextStatusMiddle->SetLabel(stackObjects.top()); stackObjects.pop(); + + if (stackObjects.empty()) + m_staticTextStatusMiddle->SetForegroundColour(*wxBLACK); //reset color + m_panel7->Layout(); } } @@ -746,8 +798,8 @@ void MainDialog::openExternalApplication(unsigned int rowNumber, bool leftSide, else { //fallback - dir = zToWx(FreeFileSync::getFormattedDirectoryName(wxToZ(m_directoryLeft->GetValue()))); - dirCo = zToWx(FreeFileSync::getFormattedDirectoryName(wxToZ(m_directoryRight->GetValue()))); + dir = zToWx(FreeFileSync::getFormattedDirectoryName(firstFolderPair->getLeftDir())); + dirCo = zToWx(FreeFileSync::getFormattedDirectoryName(firstFolderPair->getRightDir())); if (!leftSide) std::swap(dir, dirCo); @@ -772,6 +824,7 @@ void MainDialog::pushStatusInformation(const wxString& text) lastStatusChange = wxGetLocalTimeMillis(); stackObjects.push(m_staticTextStatusMiddle->GetLabel()); m_staticTextStatusMiddle->SetLabel(text); + m_staticTextStatusMiddle->SetForegroundColour(wxColour(31, 57, 226)); //highlight color: blue m_panel7->Layout(); } @@ -781,6 +834,7 @@ void MainDialog::clearStatusBar() while (stackObjects.size() > 0) stackObjects.pop(); + m_staticTextStatusMiddle->SetForegroundColour(*wxBLACK); //reset color m_staticTextStatusLeft->SetLabel(wxEmptyString); m_staticTextStatusMiddle->SetLabel(wxEmptyString); m_staticTextStatusRight->SetLabel(wxEmptyString); @@ -910,14 +964,48 @@ void MainDialog::onGridLeftButtonEvent(wxKeyEvent& event) const int keyCode = event.GetKeyCode(); if (event.ControlDown()) - { - if (keyCode == 67 || keyCode == WXK_INSERT) //CTRL + C || CTRL + INS + switch (keyCode) + { + case 67: + case WXK_INSERT: //CTRL + C || CTRL + INS copySelectionToClipboard(m_gridLeft); - else if (keyCode == 65) //CTRL + A + break; + + case 65: //CTRL + A m_gridLeft->SelectAll(); - else if (keyCode == WXK_NUMPAD_ADD) //CTRL + '+' + break; + + case WXK_NUMPAD_ADD: //CTRL + '+' m_gridLeft->autoSizeColumns(); - } + break; + } + + else if (event.AltDown()) + switch (keyCode) + { + case WXK_LEFT: //ALT + <- + { + wxCommandEvent dummy; + OnContextSyncDirLeft(dummy); + } + break; + + case WXK_RIGHT: //ALT + -> + { + wxCommandEvent dummy; + OnContextSyncDirRight(dummy); + } + break; + + case WXK_UP: /* ALT + /|\ */ + case WXK_DOWN: /* ALT + \|/ */ + { + wxCommandEvent dummy; + OnContextSyncDirNone(dummy); + } + break; + } + else switch (keyCode) { @@ -965,14 +1053,48 @@ void MainDialog::onGridRightButtonEvent(wxKeyEvent& event) const int keyCode = event.GetKeyCode(); if (event.ControlDown()) - { - if (keyCode == 67 || keyCode == WXK_INSERT) //CTRL + C || CTRL + INS + switch (keyCode) + { + case 67: + case WXK_INSERT: //CTRL + C || CTRL + INS copySelectionToClipboard(m_gridRight); - else if (keyCode == 65) //CTRL + A + break; + + case 65: //CTRL + A m_gridRight->SelectAll(); - else if (keyCode == WXK_NUMPAD_ADD) //CTRL + '+' + break; + + case WXK_NUMPAD_ADD: //CTRL + '+' m_gridRight->autoSizeColumns(); - } + break; + } + + else if (event.AltDown()) + switch (keyCode) + { + case WXK_LEFT: //ALT + <- + { + wxCommandEvent dummy; + OnContextSyncDirLeft(dummy); + } + break; + + case WXK_RIGHT: //ALT + -> + { + wxCommandEvent dummy; + OnContextSyncDirRight(dummy); + } + break; + + case WXK_UP: /* ALT + /|\ */ + case WXK_DOWN: /* ALT + \|/ */ + { + wxCommandEvent dummy; + OnContextSyncDirNone(dummy); + } + break; + } + else switch (keyCode) { @@ -1073,17 +1195,17 @@ void MainDialog::OnContextRim(wxGridEvent& event) if (fsObj && (selectionLeft.size() + selectionRight.size() > 0)) { //CONTEXT_SYNC_DIR_LEFT - wxMenuItem* menuItemSyncDirLeft = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_LEFT, _("Change direction")); + wxMenuItem* menuItemSyncDirLeft = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_LEFT, wxString(_("Change direction")) + wxT("\tALT + LEFT")); menuItemSyncDirLeft->SetBitmap(getSyncOpImage(fsObj->testSyncOperation(true, SYNC_DIR_LEFT))); contextMenu->Append(menuItemSyncDirLeft); //CONTEXT_SYNC_DIR_NONE - wxMenuItem* menuItemSyncDirNone = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_NONE, _("Change direction")); + wxMenuItem* menuItemSyncDirNone = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_NONE, wxString(_("Change direction")) + wxT("\tALT + UP")); menuItemSyncDirNone->SetBitmap(getSyncOpImage(fsObj->testSyncOperation(true, SYNC_DIR_NONE))); contextMenu->Append(menuItemSyncDirNone); //CONTEXT_SYNC_DIR_RIGHT - wxMenuItem* menuItemSyncDirRight = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_RIGHT, _("Change direction")); + wxMenuItem* menuItemSyncDirRight = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_RIGHT, wxString(_("Change direction")) + wxT("\tALT + RIGHT")); menuItemSyncDirRight->SetBitmap(getSyncOpImage(fsObj->testSyncOperation(true, SYNC_DIR_RIGHT))); contextMenu->Append(menuItemSyncDirRight); @@ -1259,8 +1381,8 @@ void MainDialog::OnContextExcludeExtension(wxCommandEvent& event) currentCfg.mainCfg.excludeFilter += Zstring(DefaultStr("*.")) + selExtension->extension + DefaultStr(";"); //';' is appended to 'mark' that next exclude extension entry won't write to new line - currentCfg.mainCfg.filterIsActive = true; - updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive); + m_checkBoxActivateFilter->SetValue(true); + updateFilterButtons(); applyFiltering(getCurrentConfiguration().mainCfg, gridDataView->getDataTentative()); updateGuiGrid(); @@ -1293,8 +1415,8 @@ void MainDialog::OnContextExcludeObject(wxCommandEvent& event) currentCfg.mainCfg.excludeFilter += Zstring() + globalFunctions::FILE_NAME_SEPARATOR + i->relativeName + globalFunctions::FILE_NAME_SEPARATOR + DefaultStr("*"); } - currentCfg.mainCfg.filterIsActive = true; - updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive); + m_checkBoxActivateFilter->SetValue(true); + updateFilterButtons(); applyFiltering(getCurrentConfiguration().mainCfg, gridDataView->getDataTentative()); updateGuiGrid(); @@ -1457,8 +1579,8 @@ void MainDialog::OnContextMiddle(wxGridEvent& event) { contextMenu.reset(new wxMenu); //re-create context menu - contextMenu->Append(CONTEXT_CHECK_ALL, _("Check all")); - contextMenu->Append(CONTEXT_UNCHECK_ALL, _("Uncheck all")); + contextMenu->Append(CONTEXT_CHECK_ALL, _("Include all rows")); + contextMenu->Append(CONTEXT_UNCHECK_ALL, _("Exclude all rows")); if (gridDataView->rowsTotal() == 0) { @@ -1497,14 +1619,14 @@ void MainDialog::OnContextMiddleLabel(wxGridEvent& event) void MainDialog::OnContextIncludeAll(wxCommandEvent& event) { - FilterProcess::setActiveStatus(true, gridDataView->getDataTentative()); + FreeFileSync::setActiveStatus(true, gridDataView->getDataTentative()); refreshGridAfterFilterChange(0); //call this instead of updateGuiGrid() to add some delay if hideFiltered == true and to handle some graphical artifacts break; } void MainDialog::OnContextExcludeAll(wxCommandEvent& event) { - FilterProcess::setActiveStatus(false, gridDataView->getDataTentative()); + FreeFileSync::setActiveStatus(false, gridDataView->getDataTentative()); refreshGridAfterFilterChange(400); //call this instead of updateGuiGrid() to add some delay if hideFiltered == true and to handle some graphical artifacts } @@ -1621,48 +1743,15 @@ void MainDialog::addFileToCfgHistory(const wxString& filename) } -int findTextPos(const wxArrayString& array, const wxString& text) -{ - for (unsigned int i = 0; i < array.GetCount(); ++i) -#ifdef FFS_WIN //don't respect case in windows build - if (array[i].CmpNoCase(text) == 0) -#elif defined FFS_LINUX - if (array[i] == text) -#endif - return i; - - return -1; -} - - -void addPairToFolderHistory(wxComboBox* comboBox, const wxString& newFolder, unsigned int maxHistSize) -{ - const wxString oldVal = comboBox->GetValue(); - - const int pos = findTextPos(comboBox->GetStrings(), newFolder); - if (pos >= 0) - comboBox->Delete(pos); - - comboBox->Insert(newFolder, 0); - - //keep maximal size of history list - if (comboBox->GetCount() > maxHistSize) - comboBox->Delete(maxHistSize); - - comboBox->SetSelection(wxNOT_FOUND); //don't select anything - comboBox->SetValue(oldVal); //but preserve main text! -} - - void MainDialog::addLeftFolderToHistory(const wxString& leftFolder) { - addPairToFolderHistory(m_directoryLeft, leftFolder, globalSettings.gui.folderHistLeftMax); + m_directoryLeft->addPairToFolderHistory(leftFolder, globalSettings.gui.folderHistLeftMax); } void MainDialog::addRightFolderToHistory(const wxString& rightFolder) { - addPairToFolderHistory(m_directoryRight, rightFolder, globalSettings.gui.folderHistRightMax); + m_directoryRight->addPairToFolderHistory(rightFolder, globalSettings.gui.folderHistRightMax); } @@ -1800,44 +1889,6 @@ void MainDialog::OnCfgHistoryKeyEvent(wxKeyEvent& event) } -void removeSelectedElement(wxComboBox* control, wxEvent& event) -{ - const int selectedItem = control->GetCurrentSelection(); - if (0 <= selectedItem && selectedItem < int(control->GetCount())) - { - const wxString oldVal = control->GetValue(); - control->Delete(selectedItem); - control->SetSelection(wxNOT_FOUND); - control->SetValue(oldVal); - } - else - event.Skip(); -} - - -void MainDialog::OnFolderHistoryKeyEvent(wxKeyEvent& event) -{ - - /* - const int keyCode = event.GetKeyCode(); - if (keyCode == WXK_DELETE || keyCode == WXK_NUMPAD_DELETE) - { - wxObject* eventObj = event.GetEventObject(); - if (eventObj == (wxObject*)m_comboBoxDirLeft) - { - removeSelectedElement(m_comboBoxDirLeft, event); - return; //no event.Skip() here! - } - else if (eventObj == (wxObject*)m_comboBoxDirRight) - { - removeSelectedElement(m_comboBoxDirRight, event); - return; - } - }*/ - event.Skip(); -} - - void MainDialog::OnClose(wxCloseEvent &event) { if (!saveOldConfig()) //notify user about changed settings @@ -1886,7 +1937,7 @@ void MainDialog::OnSetSyncDirection(FFSSyncDirectionEvent& event) if (fsObj) { setSyncDirectionRec(event.direction, *fsObj); //set new direction (recursively) - FilterProcess::setActiveStatus(true, *fsObj); //works recursively for directories + FreeFileSync::setActiveStatus(true, *fsObj); //works recursively for directories } } @@ -1997,17 +2048,17 @@ void MainDialog::setCurrentConfiguration(const xmlAccess::XmlGuiConfig& newGuiCf //(re-)set view filter buttons initViewFilterButtons(); - updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive); - + m_checkBoxActivateFilter->SetValue(currentCfg.mainCfg.filterIsActive); + updateFilterButtons(); - //read main folder pair - const wxString mainFolderLeft = zToWx(currentCfg.mainCfg.mainFolderPair.leftDirectory); - const wxString mainFolderRight = zToWx(currentCfg.mainCfg.mainFolderPair.rightDirectory); - FreeFileSync::setDirectoryName(mainFolderLeft, m_directoryLeft, m_dirPickerLeft); - FreeFileSync::setDirectoryName(mainFolderRight, m_directoryRight, m_dirPickerRight); + //set first folder pair + firstFolderPair->setValues(currentCfg.mainCfg.firstPair.leftDirectory, + currentCfg.mainCfg.firstPair.rightDirectory, + currentCfg.mainCfg.firstPair.altSyncConfig, + currentCfg.mainCfg.firstPair.localFilter); - addLeftFolderToHistory( mainFolderLeft); //another hack: wxCombobox::Insert() asynchronously sends message - addRightFolderToHistory(mainFolderRight); //overwriting a later wxCombobox::SetValue()!!! :( + addLeftFolderToHistory( zToWx(currentCfg.mainCfg.firstPair.leftDirectory)); //another hack: wxCombobox::Insert() asynchronously sends message + addRightFolderToHistory(zToWx(currentCfg.mainCfg.firstPair.rightDirectory)); //overwriting a later wxCombobox::SetValue()!!! :( //clear existing additional folder pairs clearAddFolderPairs(); @@ -2034,8 +2085,8 @@ void MainDialog::setCurrentConfiguration(const xmlAccess::XmlGuiConfig& newGuiCf inline FolderPairEnh getEnahncedPair(const FolderPairPanel* panel) { - return FolderPairEnh(wxToZ(panel->m_directoryLeft->GetValue()), - wxToZ(panel->m_directoryRight->GetValue()), + return FolderPairEnh(panel->getLeftDir(), + panel->getRightDir(), panel->getAltSyncConfig(), panel->getAltFilterConfig()); } @@ -2047,15 +2098,19 @@ xmlAccess::XmlGuiConfig MainDialog::getCurrentConfiguration() const //load settings whose ownership lies not in currentCfg: - //main folder pair - guiCfg.mainCfg.mainFolderPair.leftDirectory = wxToZ(m_directoryLeft->GetValue()); - guiCfg.mainCfg.mainFolderPair.rightDirectory = wxToZ(m_directoryRight->GetValue()); + //first folder pair + guiCfg.mainCfg.firstPair = FolderPairEnh(firstFolderPair->getLeftDir(), + firstFolderPair->getRightDir(), + firstFolderPair->getAltSyncConfig(), + firstFolderPair->getAltFilterConfig()); //add additional pairs guiCfg.mainCfg.additionalPairs.clear(); std::transform(additionalFolderPairs.begin(), additionalFolderPairs.end(), std::back_inserter(guiCfg.mainCfg.additionalPairs), getEnahncedPair); + //filter active status + guiCfg.mainCfg.filterIsActive = m_checkBoxActivateFilter->GetValue(); //sync preview guiCfg.syncPreviewEnabled = syncPreview.previewIsEnabled(); @@ -2096,12 +2151,10 @@ void MainDialog::refreshGridAfterFilterChange(const int delay) void MainDialog::OnFilterButton(wxCommandEvent &event) { - //toggle filter on/off - currentCfg.mainCfg.filterIsActive = !currentCfg.mainCfg.filterIsActive; - //make sure, button-appearance and "filterIsActive" are in sync. - updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive); + //make sure, button-appearance and "m_checkBoxActivateFilter" are in sync. + updateFilterButtons(); - updateFilterConfig(false); //refresh filtering (without changing active-status) + updateFilterConfig(); //refresh filtering } @@ -2120,19 +2173,20 @@ void MainDialog::OnHideFilteredButton(wxCommandEvent &event) } -void MainDialog::OnConfigureFilter(wxHyperlinkEvent &event) +void MainDialog::OnConfigureFilter(wxCommandEvent &event) { - FilterDlg* filterDlg = new FilterDlg(this, currentCfg.mainCfg.includeFilter, currentCfg.mainCfg.excludeFilter); + FilterDlg* filterDlg = new FilterDlg(this, + true, //is main filter dialog + currentCfg.mainCfg.includeFilter, + currentCfg.mainCfg.excludeFilter, + m_checkBoxActivateFilter->GetValue()); if (filterDlg->ShowModal() == FilterDlg::BUTTON_APPLY) { - if (currentCfg.mainCfg.includeFilter == defaultIncludeFilter() && - currentCfg.mainCfg.excludeFilter == defaultExcludeFilter()) //default - updateFilterConfig(false); //re-apply filter (without changing active-status) - else - updateFilterConfig(true); //activate(and apply) filter + updateFilterButtons(); //refresh global filter icon + updateFilterConfig(); //re-apply filter } - //no event.Skip() here, to not start browser + //event.Skip() } @@ -2328,30 +2382,56 @@ void MainDialog::initViewFilterButtons() } -void MainDialog::updateFilterButton(wxBitmapButton* filterButton, bool isActive) +void MainDialog::updateFilterButtons() { - if (isActive) + //prepare filter icon + if (m_notebookBottomLeft->GetImageList() == NULL) { - filterButton->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterOn); - filterButton->SetToolTip(_("Filter active: Press again to deactivate")); + wxImageList* panelIcons = new wxImageList(16, 16); + panelIcons->Add(wxBitmap(*GlobalResources::getInstance().bitmapFilterSmall)); + panelIcons->Add(wxBitmap(*GlobalResources::getInstance().bitmapFilterSmallGrey)); + m_notebookBottomLeft->AssignImageList(panelIcons); //pass ownership + } - //show filter icon - if (m_notebookBottomLeft->GetImageList() == NULL) + //global filter + if (m_checkBoxActivateFilter->GetValue()) //filter active? + { + //test for Null-filter + const bool isNullFilter = NameFilter(currentCfg.mainCfg.includeFilter, currentCfg.mainCfg.excludeFilter).isNull(); + if (isNullFilter) { - wxImageList* panelIcons = new wxImageList(16, 16); - panelIcons->Add(wxBitmap(*GlobalResources::getInstance().bitmapFilterSmall)); - m_notebookBottomLeft->AssignImageList(panelIcons); //pass ownership + m_bpButtonFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterOff); + m_bpButtonFilter->SetToolTip(_("No filter selected")); + + //additional filter icon + m_notebookBottomLeft->SetPageImage(1, 1); } - m_notebookBottomLeft->SetPageImage(1, 0); + else + { + m_bpButtonFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterOn); + m_bpButtonFilter->SetToolTip(_("Filter has been selected")); + //show filter icon + m_notebookBottomLeft->SetPageImage(1, 0); + } } else { - filterButton->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterOff); - filterButton->SetToolTip(_("Press button to activate filter")); + m_bpButtonFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterOff); + m_bpButtonFilter->SetToolTip(_("Filtering is deactivated")); - //hide filter icon - m_notebookBottomLeft->SetPageImage(1, -1); + //additional filter icon + m_notebookBottomLeft->SetPageImage(1, 1); + } + + //update main local filter + firstFolderPair->refreshButtons(); + + //update folder pairs + for (std::vector<FolderPairPanel*>::const_iterator i = additionalFolderPairs.begin(); i != additionalFolderPairs.end(); ++i) + { + FolderPairPanel* dirPair = *i; + dirPair->refreshButtons(); } } @@ -2400,6 +2480,7 @@ void MainDialog::OnCompare(wxCommandEvent &event) //disable the sync button syncPreview.enableSynchronization(false); m_buttonCompare->SetFocus(); + updateGuiGrid(); //refresh grid in ANY case! (also on abort) } else { @@ -2421,12 +2502,15 @@ void MainDialog::OnCompare(wxCommandEvent &event) m_gridRight-> ClearSelection(); //add to folder history after successful comparison only - addLeftFolderToHistory(m_directoryLeft->GetValue()); + addLeftFolderToHistory( m_directoryLeft->GetValue()); addRightFolderToHistory(m_directoryRight->GetValue()); - } - //refresh grid in ANY case! (also on abort) - updateGuiGrid(); + //refresh grid in ANY case! (also on abort) + updateGuiGrid(); + + if (allElementsEqual(gridDataView->getDataTentative())) + pushStatusInformation(_("All directories in sync!")); + } } @@ -2545,73 +2629,82 @@ void MainDialog::OnCmpSettings(wxCommandEvent& event) void MainDialog::OnStartSync(wxCommandEvent& event) { - if (syncPreview.synchronizationIsEnabled()) + if (!syncPreview.synchronizationIsEnabled()) { - //show sync preview screen - if (globalSettings.optDialogs.showSummaryBeforeSync) - { - bool dontShowAgain = false; + pushStatusInformation(_("Please run a Compare first before synchronizing!")); + return; + } - SyncPreviewDlg* preview = new SyncPreviewDlg( - this, - getCurrentConfiguration().mainCfg.getSyncVariantName(), - FreeFileSync::SyncStatistics(gridDataView->getDataTentative()), - dontShowAgain); + //show sync preview screen + if (globalSettings.optDialogs.showSummaryBeforeSync) + { + bool dontShowAgain = false; - if (preview->ShowModal() != SyncPreviewDlg::BUTTON_START) - return; + SyncPreviewDlg* preview = new SyncPreviewDlg( + this, + getCurrentConfiguration().mainCfg.getSyncVariantName(), + FreeFileSync::SyncStatistics(gridDataView->getDataTentative()), + dontShowAgain); - globalSettings.optDialogs.showSummaryBeforeSync = !dontShowAgain; - } - - //check if there are files/folders to be sync'ed at all - if (!synchronizationNeeded(gridDataView->getDataTentative())) - { - wxMessageBox(_("Nothing to synchronize according to configuration!"), _("Information"), wxICON_WARNING); + if (preview->ShowModal() != SyncPreviewDlg::BUTTON_START) return; - } - wxBusyCursor dummy; //show hourglass cursor + globalSettings.optDialogs.showSummaryBeforeSync = !dontShowAgain; + } - clearStatusBar(); - try - { - //PERF_START; + //check if there are files/folders to be sync'ed at all + if (!synchronizationNeeded(gridDataView->getDataTentative())) + { + wxMessageBox(_("Nothing to synchronize according to configuration!"), _("Information"), wxICON_WARNING); + return; + } - //class handling status updates and error messages - SyncStatusHandler statusHandler(this, currentCfg.ignoreErrors); + wxBusyCursor dummy; //show hourglass cursor - //start synchronization and mark all elements processed - FreeFileSync::SyncProcess synchronization( - currentCfg.mainCfg.hidden.copyFileSymlinks, - currentCfg.mainCfg.hidden.traverseDirectorySymlinks, - globalSettings.optDialogs, - currentCfg.mainCfg.hidden.verifyFileCopy, - statusHandler); + clearStatusBar(); + try + { + //PERF_START; - const std::vector<FreeFileSync::FolderPairSyncCfg> syncProcessCfg = FreeFileSync::extractSyncCfg(getCurrentConfiguration().mainCfg); - FolderComparison& dataToSync = gridDataView->getDataTentative(); + //class handling status updates and error messages + SyncStatusHandler statusHandler(this, currentCfg.ignoreErrors); - //make sure syncProcessCfg and dataToSync have same size and correspond! - if (syncProcessCfg.size() != dataToSync.size()) - throw std::logic_error("Programming Error: Contract violation!"); //should never happen: sync button is deactivated if they are not in sync + //start synchronization and mark all elements processed + FreeFileSync::SyncProcess synchronization( + currentCfg.mainCfg.hidden.copyFileSymlinks, + currentCfg.mainCfg.hidden.traverseDirectorySymlinks, + globalSettings.optDialogs, + currentCfg.mainCfg.hidden.verifyFileCopy, + globalSettings.copyLockedFiles, + statusHandler); - synchronization.startSynchronizationProcess(syncProcessCfg, dataToSync); - } - catch (AbortThisProcess&) - { - //do NOT disable the sync button: user might want to try to sync the REMAINING rows - } //enableSynchronization(false); + const std::vector<FreeFileSync::FolderPairSyncCfg> syncProcessCfg = FreeFileSync::extractSyncCfg(getCurrentConfiguration().mainCfg); + FolderComparison& dataToSync = gridDataView->getDataTentative(); - //remove rows that empty: just a beautification, invalid rows shouldn't cause issues - gridDataView->removeInvalidRows(); + //make sure syncProcessCfg and dataToSync have same size and correspond! + if (syncProcessCfg.size() != dataToSync.size()) + throw std::logic_error("Programming Error: Contract violation!"); //should never happen: sync button is deactivated if they are not in sync - updateGuiGrid(); + synchronization.startSynchronizationProcess(syncProcessCfg, dataToSync); - m_gridLeft-> ClearSelection(); - m_gridMiddle->ClearSelection(); - m_gridRight-> ClearSelection(); + //play (optional) sound notification after sync has completed (GUI and batch mode) + const wxString soundFile = FreeFileSync::getInstallationDir() + wxT("Sync_Complete.wav"); + if (fileExists(wxToZ(soundFile))) + wxSound::Play(soundFile, wxSOUND_ASYNC); } + catch (AbortThisProcess&) + { + //do NOT disable the sync button: user might want to try to sync the REMAINING rows + } //enableSynchronization(false); + + //remove rows that empty: just a beautification, invalid rows shouldn't cause issues + gridDataView->removeInvalidRows(); + + updateGuiGrid(); + + m_gridLeft-> ClearSelection(); + m_gridMiddle->ClearSelection(); + m_gridRight-> ClearSelection(); } @@ -2651,7 +2744,7 @@ void MainDialog::OnSortLeftGrid(wxGridEvent& event) switch (columnType) { case xmlAccess::FULL_PATH: - gridDataView->sortView(GridView::SORT_BY_DIRECTORY, true, sortAscending); + gridDataView->sortView(GridView::SORT_BY_REL_NAME, true, sortAscending); break; case xmlAccess::FILENAME: gridDataView->sortView(GridView::SORT_BY_FILENAME, true, sortAscending); @@ -2726,7 +2819,7 @@ void MainDialog::OnSortRightGrid(wxGridEvent& event) switch (columnType) { case xmlAccess::FULL_PATH: - gridDataView->sortView(GridView::SORT_BY_DIRECTORY, false, sortAscending); + gridDataView->sortView(GridView::SORT_BY_REL_NAME, false, sortAscending); break; case xmlAccess::FILENAME: gridDataView->sortView(GridView::SORT_BY_FILENAME, false, sortAscending); @@ -2757,22 +2850,20 @@ void MainDialog::OnSortRightGrid(wxGridEvent& event) void MainDialog::OnSwapSides(wxCommandEvent& event) { - //swap directory names: main pair - const wxString leftDir = m_directoryLeft->GetValue(); - const wxString rightDir = m_directoryRight->GetValue(); - m_directoryLeft->SetSelection(wxNOT_FOUND); - m_directoryRight->SetSelection(wxNOT_FOUND); - - m_directoryLeft->SetValue(rightDir); - m_directoryRight->SetValue(leftDir); + //swap directory names: first pair + firstFolderPair->setValues(firstFolderPair->getRightDir(), // swap directories + firstFolderPair->getLeftDir(), // + firstFolderPair->getAltSyncConfig(), + firstFolderPair->getAltFilterConfig()); //additional pairs for (std::vector<FolderPairPanel*>::const_iterator i = additionalFolderPairs.begin(); i != additionalFolderPairs.end(); ++i) { FolderPairPanel* dirPair = *i; - wxString tmp = dirPair->m_directoryLeft->GetValue(); - dirPair->m_directoryLeft->SetValue(dirPair->m_directoryRight->GetValue()); - dirPair->m_directoryRight->SetValue(tmp); + dirPair->setValues(dirPair->getRightDir(), // swap directories + dirPair->getLeftDir(), // + dirPair->getAltSyncConfig(), + dirPair->getAltFilterConfig()); } //swap view filter @@ -2800,7 +2891,6 @@ void MainDialog::OnSwapSides(wxCommandEvent& event) //swap grid information FreeFileSync::swapGrids(getCurrentConfiguration().mainCfg, gridDataView->getDataTentative()); updateGuiGrid(); - event.Skip(); } @@ -2923,10 +3013,9 @@ void MainDialog::updateGridViewData() bSizer3->Layout(); - //update status information - while (stackObjects.size() > 0) - stackObjects.pop(); + clearStatusBar(); + wxString statusLeftNew; wxString statusMiddleNew; @@ -2969,7 +3058,8 @@ void MainDialog::updateGridViewData() statusLeftNew += FreeFileSync::formatFilesizeToShortString(filesizeLeftView); } - const wxString objectsView = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(gridDataView->rowsOnView())); + const wxString objectsView = FreeFileSync::includeNumberSeparator( + globalFunctions::numberToWxString(static_cast<unsigned int>(gridDataView->rowsOnView()))); if (gridDataView->rowsTotal() == 1) { wxString outputString = _("%x of 1 row in view"); @@ -2978,7 +3068,8 @@ void MainDialog::updateGridViewData() } else { - const wxString objectsTotal = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(gridDataView->rowsTotal())); + const wxString objectsTotal = FreeFileSync::includeNumberSeparator( + globalFunctions::numberToWxString(static_cast<unsigned int>(gridDataView->rowsTotal()))); wxString outputString = _("%x of %y rows in view"); outputString.Replace(wxT("%x"), objectsView, false); @@ -3038,45 +3129,36 @@ void MainDialog::OnAddFolderPair(wxCommandEvent& event) wxWindowUpdateLocker dummy(this); //avoid display distortion std::vector<FolderPairEnh> newPairs; - newPairs.push_back( - FolderPairEnh(Zstring(), - Zstring(), - boost::shared_ptr<AlternateSyncConfig>(), - boost::shared_ptr<AlternateFilter>())); + newPairs.push_back(getCurrentConfiguration().mainCfg.firstPair); - addFolderPair(newPairs, false); //add pair at the end of additional pairs + addFolderPair(newPairs, true); //add pair in front of additonal pairs - FreeFileSync::scrollToBottom(m_scrolledWindowFolderPairs); + //clear first pair + const FolderPairEnh cfgEmpty; + firstFolderPair->setValues(cfgEmpty.leftDirectory, + cfgEmpty.rightDirectory, + cfgEmpty.altSyncConfig, + cfgEmpty.localFilter); //disable the sync button syncPreview.enableSynchronization(false); //clear grids gridDataView->clearAllRows(); - updateGuiGrid(); + updateSyncConfig(); //mainly to update sync dir description text } -void MainDialog::updateFilterConfig(bool activateFilter) //true: activate filter false: stay as it is +void MainDialog::updateFilterConfig() { - if (activateFilter) - { - //activate filter (if not yet active) - if (!currentCfg.mainCfg.filterIsActive) - { - currentCfg.mainCfg.filterIsActive = true; - updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive); - } - } - - if (currentCfg.mainCfg.filterIsActive) + if (m_checkBoxActivateFilter->GetValue()) { applyFiltering(getCurrentConfiguration().mainCfg, gridDataView->getDataTentative()); refreshGridAfterFilterChange(400); } else { - FilterProcess::setActiveStatus(true, gridDataView->getDataTentative()); + FreeFileSync::setActiveStatus(true, gridDataView->getDataTentative()); refreshGridAfterFilterChange(0); } } @@ -3119,21 +3201,47 @@ void MainDialog::updateSyncConfig() } +void MainDialog::OnRemoveTopFolderPair(wxCommandEvent& event) +{ + if (additionalFolderPairs.size() > 0) + { + //get settings from second folder pair + const FolderPairEnh cfgSecond = getEnahncedPair(additionalFolderPairs[0]); + + //reset first pair + firstFolderPair->setValues(cfgSecond.leftDirectory, + cfgSecond.rightDirectory, + cfgSecond.altSyncConfig, + cfgSecond.localFilter); + + removeAddFolderPair(0); //remove second folder pair (first of additional folder pairs) + +//------------------------------------------------------------------ + //disable the sync button + syncPreview.enableSynchronization(false); + + //clear grids + gridDataView->clearAllRows(); + updateSyncConfig(); //mainly to update sync dir description text + } +} + + void MainDialog::OnRemoveFolderPair(wxCommandEvent& event) { const wxObject* const eventObj = event.GetEventObject(); //find folder pair originating the event for (std::vector<FolderPairPanel*>::const_iterator i = additionalFolderPairs.begin(); i != additionalFolderPairs.end(); ++i) - if (eventObj == static_cast<wxObject*>((*i)->m_bpButtonRemovePair)) + if (eventObj == (*i)->m_bpButtonRemovePair) { removeAddFolderPair(i - additionalFolderPairs.begin()); +//------------------------------------------------------------------ //disable the sync button syncPreview.enableSynchronization(false); //clear grids gridDataView->clearAllRows(); - - updateSyncConfig(); + updateSyncConfig(); //mainly to update sync dir description text return; } } @@ -3142,63 +3250,94 @@ void MainDialog::OnRemoveFolderPair(wxCommandEvent& event) const size_t MAX_ADD_FOLDER_PAIRS = 5; -void MainDialog::addFolderPair(const std::vector<FolderPairEnh>& newPairs, bool addFront) +void MainDialog::updateGuiForFolderPair() { - if (newPairs.size() == 0) - return; + //adapt delete top folder pair button + if (additionalFolderPairs.size() == 0) + m_bpButtonRemovePair->Hide(); + else + m_bpButtonRemovePair->Show(); - wxWindowUpdateLocker dummy(this); //avoid display distortion + m_panelTopRight->Layout(); - int pairHeight = 0; - for (std::vector<FolderPairEnh>::const_iterator i = newPairs.begin(); i != newPairs.end(); ++i) + //adapt local filter and sync cfg for first folder pair + if ( additionalFolderPairs.size() == 0 && + firstFolderPair->getAltSyncConfig().get() == NULL && + NameFilter(firstFolderPair->getAltFilterConfig().includeFilter, + firstFolderPair->getAltFilterConfig().excludeFilter).isNull()) { - //add new folder pair - FolderPairPanel* newPair = new FolderPairPanel(m_scrolledWindowFolderPairs, this); + m_bpButtonLocalFilter->Hide(); + m_bpButtonAltSyncCfg->Hide(); - //correct width of middle block - newPair->m_panel21->SetMinSize(wxSize(m_gridMiddle->GetSize().GetWidth(), -1)); + m_bpButtonSwapSides->SetBitmapLabel(*GlobalResources::getInstance().bitmapSwap); + } + else + { + m_bpButtonLocalFilter->Show(); + m_bpButtonAltSyncCfg->Show(); - //set width of left folder panel - const int width = m_panelTopLeft->GetSize().GetWidth(); - newPair->m_panelLeft->SetMinSize(wxSize(width, -1)); + m_bpButtonSwapSides->SetBitmapLabel(*GlobalResources::getInstance().bitmapSwapSlim); + } + m_panelTopMiddle->Layout(); +} - if (addFront) - { - bSizerAddFolderPairs->Insert(0, newPair, 0, wxEXPAND, 5); - additionalFolderPairs.insert(additionalFolderPairs.begin(), newPair); - } - else + +void MainDialog::addFolderPair(const std::vector<FolderPairEnh>& newPairs, bool addFront) +{ + wxWindowUpdateLocker dummy(this); //avoid display distortion + + if (!newPairs.empty()) + { + int pairHeight = 0; + for (std::vector<FolderPairEnh>::const_iterator i = newPairs.begin(); i != newPairs.end(); ++i) { - bSizerAddFolderPairs->Add(newPair, 0, wxEXPAND, 5); - additionalFolderPairs.push_back(newPair); - } + //add new folder pair + FolderPairPanel* newPair = new FolderPairPanel(m_scrolledWindowFolderPairs, *this); - //get size of scrolled window - pairHeight = newPair->GetSize().GetHeight(); + //correct width of middle block + newPair->m_panel21->SetMinSize(wxSize(m_gridMiddle->GetSize().GetWidth(), -1)); - //register events - newPair->m_bpButtonRemovePair->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainDialog::OnRemoveFolderPair), NULL, this); + //set width of left folder panel + const int width = m_panelTopLeft->GetSize().GetWidth(); + newPair->m_panelLeft->SetMinSize(wxSize(width, -1)); - //insert directory names - FreeFileSync::setDirectoryName(zToWx(i->leftDirectory), newPair->m_directoryLeft, newPair->m_dirPickerLeft); - FreeFileSync::setDirectoryName(zToWx(i->rightDirectory), newPair->m_directoryRight, newPair->m_dirPickerRight); - //set alternate configuration - newPair->setValues(i->altSyncConfig, i->altFilter); - } + 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); + } - //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)); + //get size of scrolled window + pairHeight = newPair->GetSize().GetHeight(); - //update controls - m_scrolledWindowFolderPairs->Fit(); //adjust scrolled window size - m_scrolledWindowFolderPairs->Layout(); //adjust stuff inside scrolled window - bSizer1->Layout(); + //register events + newPair->m_bpButtonRemovePair->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainDialog::OnRemoveFolderPair), NULL, this); + + //set alternate configuration + newPair->setValues(i->leftDirectory, + i->rightDirectory, + i->altSyncConfig, + i->localFilter); + } - //scroll to the bottom of wxScrolledWindow - //scrollToBottom(m_scrolledWindowFolderPairs); + //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)); + + //update controls + m_scrolledWindowFolderPairs->Fit(); //adjust scrolled window size + m_scrolledWindowFolderPairs->Layout(); //adjust stuff inside scrolled window + bSizer1->Layout(); + } + + updateGuiForFolderPair(); } @@ -3226,6 +3365,8 @@ void MainDialog::removeAddFolderPair(const unsigned int pos) m_scrolledWindowFolderPairs->Layout(); //adjust stuff inside scrolled window bSizer1->Layout(); } + + updateGuiForFolderPair(); } @@ -3416,6 +3557,13 @@ void MainDialog::OnMenuAbout(wxCommandEvent& event) } + +void MainDialog::OnShowHelp(wxCommandEvent& event) +{ + helpController_.DisplayContents(); +} + + void MainDialog::OnMenuQuit(wxCommandEvent& event) { if (!saveOldConfig()) //notify user about changed settings @@ -3435,7 +3583,7 @@ void MainDialog::switchProgramLanguage(const int langID) cleanUp(); //destructor's code: includes writing settings to HD //create new dialog with respect to new language - MainDialog* frame = new MainDialog(NULL, wxEmptyString, globalSettings); + MainDialog* frame = new MainDialog(NULL, wxEmptyString, globalSettings, helpController_); frame->SetIcon(*GlobalResources::getInstance().programIcon); //set application icon frame->Show(); @@ -3511,3 +3659,7 @@ bool MainDialog::SyncPreview::synchronizationIsEnabled() const { return synchronizationEnabled; } + + + + diff --git a/ui/MainDialog.h b/ui/MainDialog.h index 30f018ad..61f1537f 100644 --- a/ui/MainDialog.h +++ b/ui/MainDialog.h @@ -14,6 +14,7 @@ #include <memory> #include <map> #include <set> +#include <wx/help.h> class CompareStatusHandler; class CompareStatus; @@ -24,6 +25,7 @@ class FFSSyncDirectionEvent; class IconUpdater; class ManualDeletionHandler; class FolderPairPanel; +class FirstFolderPairCfg; namespace FreeFileSync @@ -38,7 +40,8 @@ class MainDialog : public MainDialogGenerated friend class CompareStatusHandler; friend class ManualDeletionHandler; friend class MainFolderDragDrop; - friend class FolderPairPanel; + template <class GuiPanel> + friend class FolderPairCallback; //IDs for context menu items enum ContextIDRim //context menu for left and right grids @@ -78,7 +81,8 @@ class MainDialog : public MainDialogGenerated public: MainDialog(wxFrame* frame, const wxString& cfgFileName, - xmlAccess::XmlGlobalSettings& settings); + xmlAccess::XmlGlobalSettings& settings, + wxHelpController& helpController); ~MainDialog(); @@ -102,7 +106,7 @@ private: void writeGlobalSettings(); void initViewFilterButtons(); - void updateFilterButton(wxBitmapButton* filterButton, bool isActive); + void updateFilterButtons(); void addFileToCfgHistory(const wxString& filename); void addLeftFolderToHistory(const wxString& leftFolder); @@ -112,6 +116,8 @@ private: void removeAddFolderPair(const unsigned int pos); void clearAddFolderPairs(); +void updateGuiForFolderPair(); //helper method: add usability by showing/hiding buttons related to folder pairs + //main method for putting gridDataView on UI: updates data respecting current view settings void updateGuiGrid(); void updateGridViewData(); @@ -203,7 +209,6 @@ private: void loadConfiguration(const wxString& filename); void OnCfgHistoryKeyEvent( wxKeyEvent& event); - void OnFolderHistoryKeyEvent(wxKeyEvent& event); void OnRegularUpdateCheck( wxIdleEvent& event); void OnLayoutWindowAsync( wxIdleEvent& event); @@ -213,7 +218,7 @@ private: void OnResizeFolderPairs( wxSizeEvent& event); void OnFilterButton( wxCommandEvent& event); void OnHideFilteredButton( wxCommandEvent& event); - void OnConfigureFilter( wxHyperlinkEvent& event); + void OnConfigureFilter( wxCommandEvent& event); void OnSwapSides( wxCommandEvent& event); void OnCompare( wxCommandEvent& event); void OnSwitchView( wxCommandEvent& event); @@ -227,8 +232,9 @@ private: void OnAddFolderPair( wxCommandEvent& event); void OnRemoveFolderPair( wxCommandEvent& event); + void OnRemoveTopFolderPair( wxCommandEvent& event); - void updateFilterConfig(bool activateFilter); + void updateFilterConfig(); void updateSyncConfig(); //menu events @@ -237,6 +243,7 @@ private: void OnMenuBatchJob( wxCommandEvent& event); void OnMenuCheckVersion( wxCommandEvent& event); void OnMenuAbout( wxCommandEvent& event); + void OnShowHelp( wxCommandEvent& event); void OnMenuQuit( wxCommandEvent& event); void OnMenuLanguageSwitch( wxCommandEvent& event); @@ -260,8 +267,8 @@ private: xmlAccess::XmlGuiConfig currentCfg; //folder pairs: - //m_directoryLeft, m_directoryRight - std::vector<FolderPairPanel*> additionalFolderPairs; //additional pairs to the standard pair + std::auto_ptr<FirstFolderPairCfg> firstFolderPair; //always bound!!! + std::vector<FolderPairPanel*> additionalFolderPairs; //additional pairs to the first pair //gui settings int widthNotMaximized; @@ -291,15 +298,14 @@ private: int lastSortColumn; const wxGrid* lastSortGrid; - //support for drag and drop - std::auto_ptr<MainFolderDragDrop> dragDropOnLeft; - std::auto_ptr<MainFolderDragDrop> dragDropOnRight; - #ifdef FFS_WIN //update icons periodically: one updater instance for both left and right grids std::auto_ptr<IconUpdater> updateFileIcons; #endif + //global help controller + wxHelpController& helpController_; + //encapsulation of handling of sync preview class SyncPreview //encapsulates MainDialog functionality for synchronization preview (friend class) { diff --git a/ui/SmallDialogs.cpp b/ui/SmallDialogs.cpp index 4999a0e7..74678244 100644 --- a/ui/SmallDialogs.cpp +++ b/ui/SmallDialogs.cpp @@ -114,9 +114,6 @@ HelpDlg::HelpDlg(wxWindow* window) : HelpDlgGenerated(window) } -HelpDlg::~HelpDlg() {} - - void HelpDlg::OnClose(wxCloseEvent& event) { Destroy(); @@ -127,17 +124,22 @@ void HelpDlg::OnOK(wxCommandEvent& event) { Destroy(); } -//######################################################################################## -FilterDlg::FilterDlg(wxWindow* window, Zstring& filterIncl, Zstring& filterExcl) : +//######################################################################################## +FilterDlg::FilterDlg(wxWindow* window, + bool isGlobalFilter, //global or local filter dialog? + Zstring& filterIncl, + Zstring& filterExcl, + bool filterActive) : FilterDlgGenerated(window), + isGlobalFilter_(isGlobalFilter), includeFilter(filterIncl), excludeFilter(filterExcl) { m_bitmap8->SetBitmap(*GlobalResources::getInstance().bitmapInclude); m_bitmap9->SetBitmap(*GlobalResources::getInstance().bitmapExclude); - m_bitmap26->SetBitmap(*GlobalResources::getInstance().bitmapFilter); + m_bitmap26->SetBitmap(*GlobalResources::getInstance().bitmapFilterOn); m_bpButtonHelp->SetBitmapLabel(*GlobalResources::getInstance().bitmapHelp); m_textCtrlInclude->SetValue(zToWx(includeFilter)); @@ -146,6 +148,15 @@ FilterDlg::FilterDlg(wxWindow* window, Zstring& filterIncl, Zstring& filterExcl) m_panel13->Hide(); m_button10->SetFocus(); + if (filterActive) + m_staticTextFilteringInactive->Hide(); + + //adapt header for global/local dialog + if (isGlobalFilter_) + m_staticTexHeader->SetLabel(_("Global filter")); + else + m_staticTexHeader->SetLabel(_("Local filter")); + Fit(); } @@ -163,8 +174,19 @@ void FilterDlg::OnHelp(wxCommandEvent& event) void FilterDlg::OnDefault(wxCommandEvent& event) { - m_textCtrlInclude->SetValue(zToWx(defaultIncludeFilter())); - m_textCtrlExclude->SetValue(zToWx(defaultExcludeFilter())); + const FilterConfig nullFilter; + + if (isGlobalFilter_) + { + m_textCtrlInclude->SetValue(zToWx(nullFilter.includeFilter)); + //exclude various recycle bin directories with global filter + m_textCtrlExclude->SetValue(zToWx(standardExcludeFilter())); + } + else + { + m_textCtrlInclude->SetValue(zToWx(nullFilter.includeFilter)); + m_textCtrlExclude->SetValue(zToWx(nullFilter.excludeFilter)); + } //changes to mainDialog are only committed when the OK button is pressed Fit(); @@ -636,6 +658,8 @@ CompareCfgDialog::CompareCfgDialog(wxWindow* parentWindow, const wxPoint& positi Move(wxPoint(position.x, std::max(0, position.y - (m_buttonTimeSize->GetScreenPosition() - GetScreenPosition()).y))); m_bpButtonHelp->SetBitmapLabel(*GlobalResources::getInstance().bitmapHelp); + m_bitmapByTime->SetBitmap(*GlobalResources::getInstance().bitmapCmpByTime); + m_bitmapByContent->SetBitmap(*GlobalResources::getInstance().bitmapCmpByContent); switch (cmpVar) { @@ -648,6 +672,7 @@ CompareCfgDialog::CompareCfgDialog(wxWindow* parentWindow, const wxPoint& positi m_buttonTimeSize->SetFocus(); //set focus on the other button break; } + Fit(); } @@ -695,12 +720,18 @@ GlobalSettingsDlg::GlobalSettingsDlg(wxWindow* window, xmlAccess::XmlGlobalSetti m_bpButtonRemoveRow->SetBitmapLabel(*GlobalResources::getInstance().bitmapRemoveFolderPair); m_checkBoxIgnoreOneHour->SetValue(globalSettings.ignoreOneHourDiff); + m_checkBoxCopyLocked->SetValue(globalSettings.copyLockedFiles); + +#ifndef FFS_WIN +m_staticTextCopyLocked->Hide(); +m_checkBoxCopyLocked->Hide(); +#endif set(globalSettings.gui.externelApplications); const wxString toolTip = wxString(_("Integrate external applications into context menu. The following macros are available:")) + wxT("\n\n") + wxT("%name \t") + _("- full file or directory name") + wxT("\n") + - wxT("%dir \t") + _("- directory part only") + wxT("\n") + + wxT("%dir \t") + _("- directory part only") + wxT("\n") + wxT("%nameCo \t") + _("- Other side's counterpart to %name") + wxT("\n") + wxT("%dirCo \t") + _("- Other side's counterpart to %dir"); @@ -717,6 +748,7 @@ void GlobalSettingsDlg::OnOkay(wxCommandEvent& event) { //write global settings only when okay-button is pressed! settings.ignoreOneHourDiff = m_checkBoxIgnoreOneHour->GetValue(); + settings.copyLockedFiles = m_checkBoxCopyLocked->GetValue(); settings.gui.externelApplications = getExtApp(); @@ -740,6 +772,7 @@ void GlobalSettingsDlg::OnDefault(wxCommandEvent& event) xmlAccess::XmlGlobalSettings defaultCfg; m_checkBoxIgnoreOneHour->SetValue(defaultCfg.ignoreOneHourDiff); + m_checkBoxCopyLocked->SetValue(defaultCfg.copyLockedFiles); set(defaultCfg.gui.externelApplications); } @@ -762,7 +795,7 @@ void GlobalSettingsDlg::set(const xmlAccess::ExternalApps& extApp) if (rowCount > 0) m_gridCustomCommand->DeleteRows(0, rowCount); - m_gridCustomCommand->AppendRows(extApp.size()); + m_gridCustomCommand->AppendRows(static_cast<int>(extApp.size())); for (xmlAccess::ExternalApps::const_iterator i = extApp.begin(); i != extApp.end(); ++i) { const int row = i - extApp.begin(); @@ -919,10 +952,10 @@ void CompareStatus::updateStatusPanelNow() if (*i == wxChar('\n')) *i = wxChar(' '); - //status texts + //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 @@ -942,7 +975,7 @@ void CompareStatus::updateStatusPanelNow() m_staticTextDataRemaining->SetLabel(remainingBytesTmp); if (statistics.get()) - { + { if (timeElapsed.Time() - lastStatCallSpeed >= 500) //call method every 500 ms { lastStatCallSpeed = timeElapsed.Time(); @@ -1014,8 +1047,14 @@ SyncStatus::SyncStatus(StatusHandler* updater, wxWindow* parentWindow) : if (mainDialog) //disable (main) window while this status dialog is shown mainDialog->Disable(); - SetIcon(*GlobalResources::getInstance().programIcon); //set application icon timeElapsed.Start(); //measure total time + + + SetIcon(*GlobalResources::getInstance().programIcon); //set application icon + + //register key event + Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(SyncStatus::OnKeyPressed), NULL, this); + } @@ -1033,6 +1072,16 @@ SyncStatus::~SyncStatus() } +void SyncStatus::OnKeyPressed(wxKeyEvent& event) +{ + const int keyCode = event.GetKeyCode(); + if (keyCode == WXK_ESCAPE) + Close(); //generate close event: do NOT destroy window unconditionally! + + event.Skip(); +} + + void SyncStatus::resetGauge(int totalObjectsToProcess, wxLongLong totalDataToProcess) { currentData = 0; diff --git a/ui/SmallDialogs.h b/ui/SmallDialogs.h index ca22afa9..22a271c9 100644 --- a/ui/SmallDialogs.h +++ b/ui/SmallDialogs.h @@ -33,7 +33,6 @@ class HelpDlg : public HelpDlgGenerated { public: HelpDlg(wxWindow* window); - ~HelpDlg(); private: void OnClose(wxCloseEvent& event); @@ -44,7 +43,11 @@ private: class FilterDlg : public FilterDlgGenerated { public: - FilterDlg(wxWindow* window, Zstring& filterIncl, Zstring& filterExcl); + FilterDlg(wxWindow* window, + bool isGlobalFilter, + Zstring& filterIncl, + Zstring& filterExcl, + bool filterActive); ~FilterDlg() {} enum @@ -59,6 +62,7 @@ private: void OnCancel(wxCommandEvent& event); void OnClose(wxCloseEvent& event); + const bool isGlobalFilter_; Zstring& includeFilter; Zstring& excludeFilter; }; @@ -324,6 +328,7 @@ public: void minimizeToTray(); private: + void OnKeyPressed(wxKeyEvent& event); virtual void OnOkay(wxCommandEvent& event); virtual void OnPause(wxCommandEvent& event); virtual void OnAbort(wxCommandEvent& event); diff --git a/ui/folderPair.h b/ui/folderPair.h index e495995e..557f3cc6 100644 --- a/ui/folderPair.h +++ b/ui/folderPair.h @@ -6,99 +6,127 @@ #include "../library/resources.h" #include "smallDialogs.h" #include "settingsDialog.h" +#include <wx/event.h> namespace FreeFileSync { -//basic functionality for changing alternate folder pair configuration: adaptable to generated gui class +//basic functionality for handling alternate folder pair configuration: change sync-cfg/filter cfg, right-click context menu, button icons... template <class GuiPanel> -class FolderPairPanelBasic : public GuiPanel +class FolderPairPanelBasic : private wxEvtHandler { - using GuiPanel::m_bpButtonAltSyncCfg; - using GuiPanel::m_bpButtonAltFilter; - public: - FolderPairPanelBasic(wxWindow* parent) : - GuiPanel(parent), - dragDropOnLeft(new DragDropOnDlg( GuiPanel::m_panelLeft, GuiPanel::m_dirPickerLeft, GuiPanel::m_directoryLeft)), - dragDropOnRight(new DragDropOnDlg(GuiPanel::m_panelRight, GuiPanel::m_dirPickerRight, GuiPanel::m_directoryRight)) - { - //register events for removal of alternate configuration - m_bpButtonAltFilter->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(FolderPairPanelBasic::OnAltFilterCfgRemove), NULL, this); - m_bpButtonAltSyncCfg->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(FolderPairPanelBasic::OnAltSyncCfgRemove), NULL, this); + typedef boost::shared_ptr<const FreeFileSync::AlternateSyncConfig> AltSyncCfgPtr; - m_bpButtonAltSyncCfg->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FolderPairPanelBasic::OnAltSyncCfg), NULL, this); - m_bpButtonAltFilter-> Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FolderPairPanelBasic::OnAltFilterCfg), NULL, this); - GuiPanel::m_bpButtonRemovePair->SetBitmapLabel(*GlobalResources::getInstance().bitmapRemoveFolderPair); + Zstring getLeftDir() const + { + return wxToZ(basicPanel_.m_directoryLeft->GetValue()); } - typedef boost::shared_ptr<const FreeFileSync::AlternateSyncConfig> AltSyncCfgPtr; - typedef boost::shared_ptr<const FreeFileSync::AlternateFilter> AltFilterPtr; + Zstring getRightDir() const + { + return wxToZ(basicPanel_.m_directoryRight->GetValue()); + } AltSyncCfgPtr getAltSyncConfig() const { return altSyncConfig; } - AltFilterPtr getAltFilterConfig() const + FilterConfig getAltFilterConfig() const { - return altFilter; + return localFilter; } - void setValues(AltSyncCfgPtr syncCfg, AltFilterPtr filter) + void setValues(const Zstring& leftDir, + const Zstring& rightDir, + AltSyncCfgPtr syncCfg, + const FilterConfig& filter) { altSyncConfig = syncCfg; - altFilter = filter; + localFilter = filter; + + //insert directory names + FreeFileSync::setDirectoryName(zToWx(leftDir), basicPanel_.m_directoryLeft, basicPanel_.m_dirPickerLeft); + FreeFileSync::setDirectoryName(zToWx(rightDir), basicPanel_.m_directoryRight, basicPanel_.m_dirPickerRight); - updateAltButtonColor(); + refreshButtons(); } + void refreshButtons() + { + if (altSyncConfig.get()) + { + basicPanel_.m_bpButtonAltSyncCfg->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncCfgSmall); + basicPanel_.m_bpButtonAltSyncCfg->SetToolTip(wxString(_("Select alternate synchronization settings")) + wxT(" ") + globalFunctions::LINE_BREAK + + wxT("(") + altSyncConfig->syncConfiguration.getVariantName() + wxT(")")); + } + else + { + basicPanel_.m_bpButtonAltSyncCfg->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncCfgSmallGrey); + basicPanel_.m_bpButtonAltSyncCfg->SetToolTip(_("Select alternate synchronization settings")); + } + + + if (getMainConfig().filterIsActive) + { + //test for Null-filter + const bool isNullFilter = NameFilter(localFilter.includeFilter, localFilter.excludeFilter).isNull(); + if (isNullFilter) + { + basicPanel_.m_bpButtonLocalFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterSmallGrey); + basicPanel_.m_bpButtonLocalFilter->SetToolTip(_("No filter selected")); + } + else + { + basicPanel_.m_bpButtonLocalFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterSmall); + basicPanel_.m_bpButtonLocalFilter->SetToolTip(_("Filter has been selected")); + } + } + else + { + basicPanel_.m_bpButtonLocalFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterSmallGrey); + basicPanel_.m_bpButtonLocalFilter->SetToolTip(_("Filtering is deactivated")); + } + } + protected: - virtual void OnAltFilterCfgRemoveConfirm(wxCommandEvent& event) + FolderPairPanelBasic(GuiPanel& basicPanel) : //takes reference on basic panel to be enhanced + basicPanel_(basicPanel) + { + //register events for removal of alternate configuration + basicPanel_.m_bpButtonAltSyncCfg->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(FolderPairPanelBasic::OnAltSyncCfgRemove), NULL, this); + basicPanel_.m_bpButtonLocalFilter->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(FolderPairPanelBasic::OnLocalFilterCfgRemove), NULL, this); + + basicPanel_.m_bpButtonAltSyncCfg-> Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FolderPairPanelBasic::OnAltSyncCfg), NULL, this); + basicPanel_.m_bpButtonLocalFilter->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FolderPairPanelBasic::OnLocalFilterCfg), NULL, this); + + basicPanel_.m_bpButtonRemovePair->SetBitmapLabel(*GlobalResources::getInstance().bitmapRemoveFolderPair); + } + + virtual void OnLocalFilterCfgRemoveConfirm(wxCommandEvent& event) { - altFilter.reset(); - updateAltButtonColor(); + localFilter = FilterConfig(); + refreshButtons(); } virtual void OnAltSyncCfgRemoveConfirm(wxCommandEvent& event) { altSyncConfig.reset(); - updateAltButtonColor(); + refreshButtons(); } private: - void updateAltButtonColor() - { - if (altSyncConfig.get()) - m_bpButtonAltSyncCfg->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncCfgSmall); - else - m_bpButtonAltSyncCfg->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncCfgSmallGrey); - - if (altFilter.get()) - m_bpButtonAltFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterSmall); - else - m_bpButtonAltFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterSmallGrey); - - //set tooltips - if (altSyncConfig.get()) - m_bpButtonAltSyncCfg->SetToolTip(wxString(_("Select alternate synchronization settings")) + wxT(" \n") + - wxT("(") + altSyncConfig->syncConfiguration.getVariantName() + wxT(")")); - else - m_bpButtonAltSyncCfg->SetToolTip(_("Select alternate synchronization settings")); - - m_bpButtonAltFilter->SetToolTip(_("Select alternate filter settings")); - } - - void OnAltFilterCfgRemove(wxCommandEvent& event) + void OnLocalFilterCfgRemove(wxCommandEvent& event) { contextMenu.reset(new wxMenu); //re-create context menu - contextMenu->Append(wxID_ANY, _("Remove alternate settings")); - contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(FolderPairPanelBasic::OnAltFilterCfgRemoveConfirm), NULL, this); - GuiPanel::PopupMenu(contextMenu.get()); //show context menu + contextMenu->Append(wxID_ANY, _("Remove local filter settings")); + contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(FolderPairPanelBasic::OnLocalFilterCfgRemoveConfirm), NULL, this); + basicPanel_.PopupMenu(contextMenu.get()); //show context menu } void OnAltSyncCfgRemove(wxCommandEvent& event) @@ -106,7 +134,7 @@ private: contextMenu.reset(new wxMenu); //re-create context menu contextMenu->Append(wxID_ANY, _("Remove alternate settings")); contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(FolderPairPanelBasic::OnAltSyncCfgRemoveConfirm), NULL, this); - GuiPanel::PopupMenu(contextMenu.get()); //show context menu + basicPanel_.PopupMenu(contextMenu.get()); //show context menu } virtual MainConfiguration getMainConfig() const = 0; @@ -131,46 +159,42 @@ private: if (syncDlg->ShowModal() == SyncCfgDialog::BUTTON_APPLY) { altSyncConfig.reset(new AlternateSyncConfig(altSyncCfg)); - updateAltButtonColor(); + refreshButtons(); OnAltSyncCfgChange(); } } - virtual void OnAltFilterCfgChange(bool defaultValueSet) {}; + virtual void OnLocalFilterCfgChange() {}; - void OnAltFilterCfg(wxCommandEvent& event) + void OnLocalFilterCfg(wxCommandEvent& event) { - const MainConfiguration mainCfg = getMainConfig(); - const AlternateFilter filterMain(mainCfg.includeFilter, mainCfg.excludeFilter); - - AlternateFilter altFilt = altFilter.get() ? *altFilter : filterMain; - FilterDlg* filterDlg = new FilterDlg(getParentWindow(), altFilt.includeFilter, altFilt.excludeFilter); + FilterConfig localFiltTmp = localFilter; + FilterDlg* filterDlg = new FilterDlg(getParentWindow(), + false, //is local filter dialog + localFiltTmp.includeFilter, + localFiltTmp.excludeFilter, + getMainConfig().filterIsActive); if (filterDlg->ShowModal() == FilterDlg::BUTTON_APPLY) { - altFilter.reset(new AlternateFilter(altFilt)); - updateAltButtonColor(); + localFilter = localFiltTmp; + refreshButtons(); - if ( altFilt.includeFilter == defaultIncludeFilter() && - altFilt.excludeFilter == defaultExcludeFilter()) //default - OnAltFilterCfgChange(true); - else - OnAltFilterCfgChange(false); + OnLocalFilterCfgChange(); } } + GuiPanel& basicPanel_; //panel to be enhanced by this template + //alternate configuration attached to it - AltSyncCfgPtr altSyncConfig; //optional - AltFilterPtr altFilter; //optional + AltSyncCfgPtr altSyncConfig; //optional: present if non-NULL + FilterConfig localFilter; std::auto_ptr<wxMenu> contextMenu; - - //support for drag and drop - std::auto_ptr<DragDropOnDlg> dragDropOnLeft; - std::auto_ptr<DragDropOnDlg> dragDropOnRight; }; } #endif // FOLDERPAIR_H_INCLUDED + diff --git a/ui/guiGenerated.cpp b/ui/guiGenerated.cpp index fdc4f72d..9670c775 100644 --- a/ui/guiGenerated.cpp +++ b/ui/guiGenerated.cpp @@ -7,6 +7,7 @@ #include "../library/customGrid.h" #include "../shared/customButton.h" +#include "../shared/customComboBox.h" #include "../shared/toggleButton.h" #include "guiGenerated.h" @@ -68,13 +69,17 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_menubar1->Append( m_menuAdvanced, _("&Advanced") ); m_menuHelp = new wxMenu(); + wxMenuItem* m_menuItemReadme; + m_menuItemReadme = new wxMenuItem( m_menuHelp, wxID_ANY, wxString( _("&Content") ) + wxT('\t') + wxT("F1"), wxEmptyString, wxITEM_NORMAL ); + m_menuHelp->Append( m_menuItemReadme ); + wxMenuItem* m_menuItemCheckVer; m_menuItemCheckVer = new wxMenuItem( m_menuHelp, wxID_ANY, wxString( _("&Check for new version") ) , wxEmptyString, wxITEM_NORMAL ); m_menuHelp->Append( m_menuItemCheckVer ); m_menuHelp->AppendSeparator(); - m_menuItemAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( _("&About...") ) + wxT('\t') + wxT("F1"), wxEmptyString, wxITEM_NORMAL ); + m_menuItemAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( _("&About...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuHelp->Append( m_menuItemAbout ); m_menubar1->Append( m_menuHelp, _("&Help") ); @@ -182,7 +187,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const sbSizer2 = new wxStaticBoxSizer( new wxStaticBox( m_panelTopLeft, wxID_ANY, _("Drag && drop") ), wxHORIZONTAL ); - m_directoryLeft = new wxComboBox( m_panelTopLeft, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); + m_directoryLeft = new CustomComboBox( 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, 0 ); @@ -195,7 +200,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_panelTopLeft->SetSizer( bSizer92 ); m_panelTopLeft->Layout(); bSizer92->Fit( m_panelTopLeft ); - bSizer91->Add( m_panelTopLeft, 1, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer91->Add( m_panelTopLeft, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_panelTopMiddle = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bSizer93; @@ -206,7 +211,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizerMiddle = new wxBoxSizer( wxHORIZONTAL ); - m_bpButtonSwapSides = new wxBitmapButton( m_panelTopMiddle, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); + m_bpButtonSwapSides = new wxBitmapButton( m_panelTopMiddle, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW ); m_bpButtonSwapSides->SetToolTip( _("Swap sides") ); m_bpButtonSwapSides->SetToolTip( _("Swap sides") ); @@ -215,6 +220,26 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer93->Add( bSizerMiddle, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + wxBoxSizer* bSizer160; + bSizer160 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer160->Add( 0, 0, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_bpButtonLocalFilter = new wxBitmapButton( m_panelTopMiddle, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); + bSizer160->Add( m_bpButtonLocalFilter, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer160->Add( 5, 0, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + m_bpButtonAltSyncCfg = new wxBitmapButton( m_panelTopMiddle, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); + bSizer160->Add( m_bpButtonAltSyncCfg, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer160->Add( 0, 0, 1, wxEXPAND, 5 ); + + bSizer93->Add( bSizer160, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + m_panelTopMiddle->SetSizer( bSizer93 ); m_panelTopMiddle->Layout(); bSizer93->Fit( m_panelTopMiddle ); @@ -237,7 +262,14 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const sbSizer3->Add( m_bpButtonAddPair, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 3 ); - m_directoryRight = new wxComboBox( m_panelTopRight, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); + m_bpButtonRemovePair = new wxBitmapButton( m_panelTopRight, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 19,21 ), wxBU_AUTODRAW ); + m_bpButtonRemovePair->SetToolTip( _("Remove folder pair") ); + + m_bpButtonRemovePair->SetToolTip( _("Remove folder pair") ); + + sbSizer3->Add( m_bpButtonRemovePair, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + m_directoryRight = new CustomComboBox( 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, 0 ); @@ -252,7 +284,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_panelTopRight->SetSizer( bSizer94 ); m_panelTopRight->Layout(); bSizer94->Fit( m_panelTopRight ); - bSizer91->Add( m_panelTopRight, 1, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer91->Add( m_panelTopRight, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer1->Add( bSizer91, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 ); @@ -333,7 +365,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const // Label Appearance // Cell Defaults - m_gridMiddle->SetDefaultCellFont( wxFont( 12, 74, 90, 92, false, wxT("Arial") ) ); + m_gridMiddle->SetDefaultCellFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxT("Arial") ) ); m_gridMiddle->SetDefaultCellAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); bSizer18->Add( m_gridMiddle, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP|wxBOTTOM, 5 ); @@ -426,19 +458,19 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const wxBoxSizer* bSizer23; bSizer23 = new wxBoxSizer( wxVERTICAL ); - m_hyperlinkCfgFilter = new wxHyperlinkCtrl( m_panelFilter, wxID_ANY, _("Configure filter..."), wxEmptyString, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_checkBoxActivateFilter = new wxCheckBox( m_panelFilter, wxID_ANY, _("Activate filter"), wxDefaultPosition, wxDefaultSize, 0 ); - m_hyperlinkCfgFilter->SetNormalColour( wxColour( 0, 0, 255 ) ); - m_hyperlinkCfgFilter->SetVisitedColour( wxColour( 0, 0, 255 ) ); - bSizer23->Add( m_hyperlinkCfgFilter, 0, wxALL, 5 ); + m_checkBoxActivateFilter->SetToolTip( _("Enable filter to exclude files from synchronization") ); - m_checkBoxHideFilt = new wxCheckBox( m_panelFilter, wxID_ANY, _("Hide filtered items"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer23->Add( m_checkBoxActivateFilter, 0, wxBOTTOM, 5 ); - m_checkBoxHideFilt->SetToolTip( _("Choose to hide filtered files/directories from list") ); + m_checkBoxHideFilt = new wxCheckBox( m_panelFilter, wxID_ANY, _("Hide excluded items"), wxDefaultPosition, wxDefaultSize, 0 ); + + m_checkBoxHideFilt->SetToolTip( _("Hide filtered or temporarily excluded files") ); bSizer23->Add( m_checkBoxHideFilt, 0, 0, 5 ); - bSizer140->Add( bSizer23, 0, 0, 5 ); + bSizer140->Add( bSizer23, 0, wxALIGN_CENTER_VERTICAL, 5 ); m_panelFilter->SetSizer( bSizer140 ); m_panelFilter->Layout(); @@ -594,8 +626,10 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizerBottomRight->Add( m_panelSyncPreview, 0, wxALIGN_CENTER_VERTICAL, 5 ); m_bpButton10 = new wxBitmapButton( m_panelBottom, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 50,50 ), wxBU_AUTODRAW ); + m_bpButton10->Hide(); m_bpButton10->SetToolTip( _("Quit") ); + m_bpButton10->Hide(); m_bpButton10->SetToolTip( _("Quit") ); bSizerBottomRight->Add( m_bpButton10, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT, 5 ); @@ -692,17 +726,17 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const this->Connect( m_menuItemGlobSett->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuGlobalSettings ) ); this->Connect( m_menuItem7->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuBatchJob ) ); this->Connect( m_menuItem5->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuExportFileList ) ); + this->Connect( m_menuItemReadme->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnShowHelp ) ); 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_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 ); m_dirPickerLeft->Connect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( MainDialogGenerated::OnDirSelected ), NULL, this ); m_bpButtonSwapSides->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSwapSides ), NULL, this ); m_bpButtonAddPair->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnAddFolderPair ), NULL, this ); - m_directoryRight->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( MainDialogGenerated::OnFolderHistoryKeyEvent ), NULL, this ); + m_bpButtonRemovePair->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnRemoveTopFolderPair ), NULL, this ); m_dirPickerRight->Connect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( MainDialogGenerated::OnDirSelected ), NULL, this ); m_gridLeft->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( MainDialogGenerated::OnLeftGridDoubleClick ), NULL, this ); m_gridLeft->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( MainDialogGenerated::OnContextRim ), NULL, this ); @@ -719,8 +753,8 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_bpButtonLoad->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnLoadConfig ), NULL, this ); m_choiceHistory->Connect( wxEVT_CHAR, wxKeyEventHandler( MainDialogGenerated::OnCfgHistoryKeyEvent ), NULL, this ); m_choiceHistory->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnLoadFromHistory ), NULL, this ); - m_bpButtonFilter->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnFilterButton ), NULL, this ); - m_hyperlinkCfgFilter->Connect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( MainDialogGenerated::OnConfigureFilter ), NULL, this ); + m_bpButtonFilter->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnConfigureFilter ), NULL, this ); + m_checkBoxActivateFilter->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnFilterButton ), NULL, this ); m_checkBoxHideFilt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnHideFilteredButton ), NULL, this ); m_bpButtonLeftOnly->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnLeftOnlyFiles ), NULL, this ); m_bpButtonLeftNewer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnLeftNewerFiles ), NULL, this ); @@ -753,17 +787,17 @@ MainDialogGenerated::~MainDialogGenerated() this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuGlobalSettings ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuBatchJob ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuExportFileList ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnShowHelp ) ); 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_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 ); m_dirPickerLeft->Disconnect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( MainDialogGenerated::OnDirSelected ), NULL, this ); m_bpButtonSwapSides->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSwapSides ), NULL, this ); m_bpButtonAddPair->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnAddFolderPair ), NULL, this ); - m_directoryRight->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( MainDialogGenerated::OnFolderHistoryKeyEvent ), NULL, this ); + m_bpButtonRemovePair->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnRemoveTopFolderPair ), NULL, this ); m_dirPickerRight->Disconnect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( MainDialogGenerated::OnDirSelected ), NULL, this ); m_gridLeft->Disconnect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( MainDialogGenerated::OnLeftGridDoubleClick ), NULL, this ); m_gridLeft->Disconnect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( MainDialogGenerated::OnContextRim ), NULL, this ); @@ -780,8 +814,8 @@ MainDialogGenerated::~MainDialogGenerated() m_bpButtonLoad->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnLoadConfig ), NULL, this ); m_choiceHistory->Disconnect( wxEVT_CHAR, wxKeyEventHandler( MainDialogGenerated::OnCfgHistoryKeyEvent ), NULL, this ); m_choiceHistory->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnLoadFromHistory ), NULL, this ); - m_bpButtonFilter->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnFilterButton ), NULL, this ); - m_hyperlinkCfgFilter->Disconnect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( MainDialogGenerated::OnConfigureFilter ), NULL, this ); + m_bpButtonFilter->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnConfigureFilter ), NULL, this ); + m_checkBoxActivateFilter->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnFilterButton ), NULL, this ); m_checkBoxHideFilt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnHideFilteredButton ), NULL, this ); m_bpButtonLeftOnly->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnLeftOnlyFiles ), NULL, this ); m_bpButtonLeftNewer->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnLeftNewerFiles ), NULL, this ); @@ -829,7 +863,7 @@ 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_MENU ) ); + m_panel21->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) ); wxBoxSizer* bSizer96; bSizer96 = new wxBoxSizer( wxHORIZONTAL ); @@ -837,8 +871,11 @@ FolderPairGenerated::FolderPairGenerated( wxWindow* parent, wxWindowID id, const bSizer96->Add( 0, 0, 1, wxEXPAND, 5 ); - m_bpButtonAltFilter = new wxBitmapButton( m_panel21, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); - bSizer96->Add( m_bpButtonAltFilter, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 ); + m_bpButtonLocalFilter = new wxBitmapButton( m_panel21, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); + bSizer96->Add( m_bpButtonLocalFilter, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer96->Add( 5, 0, 0, wxALIGN_CENTER_VERTICAL, 5 ); m_bpButtonAltSyncCfg = new wxBitmapButton( m_panel21, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); bSizer96->Add( m_bpButtonAltSyncCfg, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -960,8 +997,8 @@ BatchFolderPairGenerated::BatchFolderPairGenerated( wxWindow* parent, wxWindowID bSizer114->Add( m_dirPickerLeft, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_bpButtonAltFilter = new wxBitmapButton( m_panelLeft, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); - bSizer114->Add( m_bpButtonAltFilter, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_bpButtonLocalFilter = new wxBitmapButton( m_panelLeft, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); + bSizer114->Add( m_bpButtonLocalFilter, 0, wxALIGN_CENTER_VERTICAL, 5 ); m_panelLeft->SetSizer( bSizer114 ); m_panelLeft->Layout(); @@ -1085,7 +1122,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer147 = new wxBoxSizer( wxHORIZONTAL ); wxBoxSizer* bSizer1361; - bSizer1361 = new wxBoxSizer( wxVERTICAL ); + bSizer1361 = new wxBoxSizer( wxHORIZONTAL ); m_bpButtonAddPair = new wxBitmapButton( m_panelMainPair, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 19,21 ), wxBU_AUTODRAW ); m_bpButtonAddPair->SetToolTip( _("Add folder pair") ); @@ -1094,6 +1131,13 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer1361->Add( m_bpButtonAddPair, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 3 ); + m_bpButtonRemovePair = new wxBitmapButton( m_panelMainPair, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 19,21 ), wxBU_AUTODRAW ); + m_bpButtonRemovePair->SetToolTip( _("Remove folder pair") ); + + m_bpButtonRemovePair->SetToolTip( _("Remove folder pair") ); + + bSizer1361->Add( m_bpButtonRemovePair, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer147->Add( bSizer1361, 0, wxALIGN_CENTER_VERTICAL, 5 ); wxBoxSizer* bSizer143; @@ -1143,6 +1187,9 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer1141->Add( m_dirPickerLeft, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_bpButtonLocalFilter = new wxBitmapButton( m_panelLeft, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); + bSizer1141->Add( m_bpButtonLocalFilter, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_panelLeft->SetSizer( bSizer1141 ); m_panelLeft->Layout(); bSizer1141->Fit( m_panelLeft ); @@ -1160,6 +1207,9 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer115->Add( m_dirPickerRight, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_bpButtonAltSyncCfg = new wxBitmapButton( m_panelRight, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); + bSizer115->Add( m_bpButtonAltSyncCfg, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_panelRight->SetSizer( bSizer115 ); m_panelRight->Layout(); bSizer115->Fit( m_panelRight ); @@ -1220,7 +1270,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS sbSizer24->Add( m_checkBoxAutomatic, 0, wxALL, 5 ); - m_checkBoxFilter = new wxCheckBox( m_panelOverview, wxID_ANY, _("Filter files"), wxDefaultPosition, wxDefaultSize, 0 ); + m_checkBoxFilter = new wxCheckBox( m_panelOverview, wxID_ANY, _("Activate filter"), wxDefaultPosition, wxDefaultSize, 0 ); m_checkBoxFilter->SetToolTip( _("Enable filter to exclude files from synchronization") ); @@ -1228,7 +1278,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS m_checkBoxSilent = new wxCheckBox( m_panelOverview, wxID_ANY, _("Silent mode"), wxDefaultPosition, wxDefaultSize, 0 ); - m_checkBoxSilent->SetToolTip( _("Do not display visual status information but write to a logfile instead") ); + m_checkBoxSilent->SetToolTip( _("Run minimized and write status information to a logfile") ); sbSizer24->Add( m_checkBoxSilent, 0, wxALL, 5 ); @@ -1542,6 +1592,7 @@ 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_bpButtonRemovePair->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_checkBoxAutomatic->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnCheckAutomatic ), NULL, this ); @@ -1565,6 +1616,7 @@ 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_bpButtonRemovePair->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_checkBoxAutomatic->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnCheckAutomatic ), NULL, this ); @@ -1767,7 +1819,7 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const fgSizer1->Add( m_buttonAutomatic, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - m_staticText81 = new wxStaticText( this, wxID_ANY, _("Synchronize both sides using a database. Deletions are detected automatically."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText81 = new wxStaticText( this, wxID_ANY, _("Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText81->Wrap( 300 ); fgSizer1->Add( m_staticText81, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); @@ -1801,16 +1853,20 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const m_radioBtnTwoWay = new wxRadioButton( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_radioBtnTwoWay->SetFont( wxFont( 11, 74, 90, 92, false, wxT("Tahoma") ) ); + m_radioBtnTwoWay->Hide(); fgSizer1->Add( m_radioBtnTwoWay, 0, wxALIGN_CENTER_VERTICAL, 5 ); m_buttonTwoWay = new wxButton( this, wxID_ANY, _("Two way <->"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); m_buttonTwoWay->SetFont( wxFont( 11, 74, 90, 92, false, wxT("Tahoma") ) ); + m_buttonTwoWay->Hide(); fgSizer1->Add( m_buttonTwoWay, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); m_staticText10 = new wxStaticText( this, wxID_ANY, _("Synchronize both sides simultaneously: Copy new or updated files in both directions."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText10->Wrap( 300 ); + m_staticText10->Hide(); + fgSizer1->Add( m_staticText10, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); m_radioBtnCustom = new wxRadioButton( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); @@ -2107,7 +2163,7 @@ CmpCfgDlgGenerated::CmpCfgDlgGenerated( wxWindow* parent, wxWindowID id, const w sbSizer6 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Compare by...") ), wxHORIZONTAL ); wxFlexGridSizer* fgSizer16; - fgSizer16 = new wxFlexGridSizer( 2, 2, 0, 0 ); + fgSizer16 = new wxFlexGridSizer( 2, 3, 0, 0 ); fgSizer16->SetFlexibleDirection( wxBOTH ); fgSizer16->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); @@ -2117,22 +2173,32 @@ CmpCfgDlgGenerated::CmpCfgDlgGenerated( wxWindow* parent, wxWindowID id, const w 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_bitmapByTime = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); + m_bitmapByTime->SetToolTip( _("Files are found equal if\n - filesize\n - last write time and date\nare the same.") ); + + fgSizer16->Add( m_bitmapByTime, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_buttonTimeSize = new wxButton( this, wxID_ANY, _("File size and date"), wxDefaultPosition, wxSize( -1,42 ), 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 ); + fgSizer16->Add( m_buttonTimeSize, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, 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_bitmapByContent = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); + m_bitmapByContent->SetToolTip( _("Files are found equal if\n - file content\nis the same.") ); + + fgSizer16->Add( m_bitmapByContent, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_buttonContent = new wxButton( this, wxID_ANY, _("File content"), wxDefaultPosition, wxSize( -1,42 ), 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 ); + fgSizer16->Add( m_buttonContent, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); sbSizer6->Add( fgSizer16, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); @@ -2186,8 +2252,8 @@ CmpCfgDlgGenerated::~CmpCfgDlgGenerated() SyncStatusDlgGenerated::SyncStatusDlgGenerated( 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( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); + this->SetSizeHints( wxSize( 470,300 ), wxDefaultSize ); + this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) ); wxBoxSizer* bSizer27; bSizer27 = new wxBoxSizer( wxVERTICAL ); @@ -2575,6 +2641,79 @@ HelpDlgGenerated::~HelpDlgGenerated() m_button8->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( HelpDlgGenerated::OnOK ), NULL, this ); } +ReadmeDlgGenerated::ReadmeDlgGenerated( 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* bSizer20; + bSizer20 = new wxBoxSizer( wxVERTICAL ); + + + bSizer20->Add( 0, 10, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer85; + bSizer85 = new wxBoxSizer( wxHORIZONTAL ); + + m_bitmap25 = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), 0 ); + bSizer85->Add( m_bitmap25, 1, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_panel8 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER|wxTAB_TRAVERSAL ); + m_panel8->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT ) ); + + wxBoxSizer* bSizer72; + bSizer72 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer72->Add( 20, 0, 0, 0, 5 ); + + m_staticText56 = new wxStaticText( m_panel8, wxID_ANY, _("&Readme.txt"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText56->Wrap( -1 ); + m_staticText56->SetFont( wxFont( 16, 74, 90, 92, false, wxT("Tahoma") ) ); + + bSizer72->Add( m_staticText56, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer72->Add( 20, 0, 0, 0, 5 ); + + m_panel8->SetSizer( bSizer72 ); + m_panel8->Layout(); + bSizer72->Fit( m_panel8 ); + bSizer85->Add( m_panel8, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + + bSizer85->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer20->Add( bSizer85, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_textCtrlMain = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_RICH ); + m_textCtrlMain->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Courier") ) ); + m_textCtrlMain->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_INACTIVEBORDER ) ); + + bSizer20->Add( m_textCtrlMain, 1, wxALL|wxEXPAND, 5 ); + + 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") ) ); + + bSizer20->Add( m_buttonOkay, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + this->SetSizer( bSizer20 ); + this->Layout(); + + this->Centre( wxBOTH ); + + // Connect Events + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( ReadmeDlgGenerated::OnClose ) ); + m_buttonOkay->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ReadmeDlgGenerated::OnOK ), NULL, this ); +} + +ReadmeDlgGenerated::~ReadmeDlgGenerated() +{ + // Disconnect Events + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( ReadmeDlgGenerated::OnClose ) ); + m_buttonOkay->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ReadmeDlgGenerated::OnOK ), NULL, this ); +} + AboutDlgGenerated::AboutDlgGenerated( 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 ); @@ -3112,11 +3251,11 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w wxBoxSizer* bSizer72; bSizer72 = new wxBoxSizer( wxVERTICAL ); - m_staticText56 = new wxStaticText( m_panel8, wxID_ANY, _("Filter files"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText56->Wrap( -1 ); - m_staticText56->SetFont( wxFont( 16, 74, 90, 92, false, wxT("Tahoma") ) ); + m_staticTexHeader = new wxStaticText( m_panel8, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTexHeader->Wrap( -1 ); + m_staticTexHeader->SetFont( wxFont( 16, 74, 90, 92, false, wxT("Tahoma") ) ); - bSizer72->Add( m_staticText56, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); + bSizer72->Add( m_staticTexHeader, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); m_panel8->SetSizer( bSizer72 ); m_panel8->Layout(); @@ -3202,6 +3341,13 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w bSizer69->Fit( m_panel13 ); bSizer21->Add( m_panel13, 0, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxEXPAND, 5 ); + m_staticTextFilteringInactive = new wxStaticText( this, wxID_ANY, _("Filtering is deactivated"), wxDefaultPosition, wxDefaultSize, 0|wxRAISED_BORDER ); + m_staticTextFilteringInactive->Wrap( -1 ); + m_staticTextFilteringInactive->SetFont( wxFont( 12, 74, 90, 92, false, wxT("Arial Black") ) ); + m_staticTextFilteringInactive->SetForegroundColour( wxColour( 255, 0, 0 ) ); + + bSizer21->Add( m_staticTextFilteringInactive, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); + wxStaticBoxSizer* sbSizer8; sbSizer8 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxEmptyString ), wxVERTICAL ); @@ -3447,7 +3593,27 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind bSizer120->Add( m_checkBoxIgnoreOneHour, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - sbSizer23->Add( bSizer120, 1, wxEXPAND, 5 ); + sbSizer23->Add( bSizer120, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer1201; + bSizer1201 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticTextCopyLocked = new wxStaticText( this, wxID_ANY, _("Copy locked files"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextCopyLocked->Wrap( -1 ); + m_staticTextCopyLocked->SetToolTip( _("Use Volume Shadow Copy Service to copy locked or shared files.") ); + + bSizer1201->Add( m_staticTextCopyLocked, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer1201->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_checkBoxCopyLocked = new wxCheckBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + + m_checkBoxCopyLocked->SetToolTip( _("Use Volume Shadow Copy Service to copy locked or shared files.") ); + + bSizer1201->Add( m_checkBoxCopyLocked, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + sbSizer23->Add( bSizer1201, 0, wxEXPAND, 5 ); m_staticline10 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); sbSizer23->Add( m_staticline10, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxTOP|wxBOTTOM, 5 ); diff --git a/ui/guiGenerated.h b/ui/guiGenerated.h index f51a5f41..70cce976 100644 --- a/ui/guiGenerated.h +++ b/ui/guiGenerated.h @@ -10,6 +10,7 @@ #include <wx/intl.h> +class CustomComboBox; class CustomGridLeft; class CustomGridMiddle; class CustomGridRight; @@ -36,7 +37,6 @@ class wxButtonWithImage; #include <wx/scrolwin.h> #include <wx/grid.h> #include <wx/choice.h> -#include <wx/hyperlink.h> #include <wx/checkbox.h> #include <wx/notebook.h> #include <wx/statbmp.h> @@ -48,6 +48,7 @@ class wxButtonWithImage; #include <wx/gauge.h> #include <wx/animate.h> #include <wx/treectrl.h> +#include <wx/hyperlink.h> #include <wx/checklst.h> /////////////////////////////////////////////////////////////////////////// @@ -90,25 +91,20 @@ class MainDialogGenerated : public wxFrame wxBitmapButton* m_bpButtonSyncConfig; wxButtonWithImage* m_buttonStartSync; - wxPanel* m_panelTopLeft; wxStaticBoxSizer* sbSizer2; - wxComboBox* m_directoryLeft; - wxDirPickerCtrl* m_dirPickerLeft; wxPanel* m_panelTopMiddle; wxBoxSizer* bSizerMiddle; wxBitmapButton* m_bpButtonSwapSides; - wxPanel* m_panelTopRight; + + + wxBitmapButton* m_bpButtonAddPair; - wxComboBox* m_directoryRight; - wxDirPickerCtrl* m_dirPickerRight; wxScrolledWindow* m_scrolledWindowFolderPairs; wxBoxSizer* bSizerAddFolderPairs; - wxPanel* m_panelLeft; CustomGridLeft* m_gridLeft; wxPanel* m_panelMiddle; CustomGridMiddle* m_gridMiddle; - wxPanel* m_panelRight; CustomGridRight* m_gridRight; wxBoxSizer* bSizer3; wxNotebook* m_notebookBottomLeft; @@ -118,7 +114,7 @@ class MainDialogGenerated : public wxFrame wxChoice* m_choiceHistory; wxPanel* m_panelFilter; wxBitmapButton* m_bpButtonFilter; - wxHyperlinkCtrl* m_hyperlinkCfgFilter; + wxCheckBox* m_checkBoxActivateFilter; wxCheckBox* m_checkBoxHideFilt; wxPanel* m_panel112; @@ -175,14 +171,15 @@ class MainDialogGenerated : public wxFrame virtual void OnMenuGlobalSettings( wxCommandEvent& event ){ event.Skip(); } virtual void OnMenuBatchJob( wxCommandEvent& event ){ event.Skip(); } virtual void OnMenuExportFileList( wxCommandEvent& event ){ event.Skip(); } + virtual void OnShowHelp( wxCommandEvent& event ){ event.Skip(); } virtual void OnMenuCheckVersion( wxCommandEvent& event ){ event.Skip(); } virtual void OnMenuAbout( 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(); } virtual void OnSwapSides( wxCommandEvent& event ){ event.Skip(); } virtual void OnAddFolderPair( wxCommandEvent& event ){ event.Skip(); } + virtual void OnRemoveTopFolderPair( wxCommandEvent& event ){ event.Skip(); } virtual void OnLeftGridDoubleClick( wxGridEvent& event ){ event.Skip(); } virtual void OnContextRim( wxGridEvent& event ){ event.Skip(); } virtual void OnSortLeftGrid( wxGridEvent& event ){ event.Skip(); } @@ -195,8 +192,8 @@ class MainDialogGenerated : public wxFrame virtual void OnContextRimLabelRight( wxGridEvent& event ){ event.Skip(); } virtual void OnCfgHistoryKeyEvent( wxKeyEvent& event ){ event.Skip(); } virtual void OnLoadFromHistory( wxCommandEvent& event ){ event.Skip(); } + virtual void OnConfigureFilter( wxCommandEvent& event ){ event.Skip(); } virtual void OnFilterButton( wxCommandEvent& event ){ event.Skip(); } - virtual void OnConfigureFilter( wxHyperlinkEvent& event ){ event.Skip(); } virtual void OnHideFilteredButton( wxCommandEvent& event ){ event.Skip(); } virtual void OnLeftOnlyFiles( wxCommandEvent& event ){ event.Skip(); } virtual void OnLeftNewerFiles( wxCommandEvent& event ){ event.Skip(); } @@ -216,6 +213,17 @@ class MainDialogGenerated : public wxFrame public: + wxPanel* m_panelTopLeft; + CustomComboBox* m_directoryLeft; + wxDirPickerCtrl* m_dirPickerLeft; + wxBitmapButton* m_bpButtonLocalFilter; + wxBitmapButton* m_bpButtonAltSyncCfg; + wxPanel* m_panelTopRight; + wxBitmapButton* m_bpButtonRemovePair; + CustomComboBox* m_directoryRight; + wxDirPickerCtrl* m_dirPickerRight; + wxPanel* m_panelLeft; + wxPanel* m_panelRight; MainDialogGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("FreeFileSync - Folder Comparison and Synchronization"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 933,612 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL ); ~MainDialogGenerated(); @@ -231,8 +239,7 @@ class FolderPairGenerated : public wxPanel protected: wxPanel* m_panel20; - wxBitmapButton* m_bpButtonAltFilter; - wxBitmapButton* m_bpButtonAltSyncCfg; + public: @@ -240,6 +247,8 @@ class FolderPairGenerated : public wxPanel wxTextCtrl* m_directoryLeft; wxDirPickerCtrl* m_dirPickerLeft; wxPanel* m_panel21; + wxBitmapButton* m_bpButtonLocalFilter; + wxBitmapButton* m_bpButtonAltSyncCfg; wxPanel* m_panelRight; wxBitmapButton* m_bpButtonRemovePair; wxTextCtrl* m_directoryRight; @@ -261,17 +270,17 @@ class BatchFolderPairGenerated : public wxPanel wxStaticText* m_staticText53; wxStaticText* m_staticText541; wxPanel* m_panelLeft; - wxBitmapButton* m_bpButtonAltFilter; wxPanel* m_panelRight; - wxBitmapButton* m_bpButtonAltSyncCfg; public: wxBitmapButton* m_bpButtonRemovePair; wxTextCtrl* m_directoryLeft; wxDirPickerCtrl* m_dirPickerLeft; + wxBitmapButton* m_bpButtonLocalFilter; wxTextCtrl* m_directoryRight; wxDirPickerCtrl* m_dirPickerRight; + wxBitmapButton* m_bpButtonAltSyncCfg; BatchFolderPairGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); ~BatchFolderPairGenerated(); @@ -297,13 +306,10 @@ class BatchDlgGenerated : public wxDialog wxStaticText* m_staticText531; wxNotebook* m_notebookSettings; wxPanel* m_panelOverview; - wxScrolledWindow* m_scrolledWindow6; wxBoxSizer* sbSizerMainPair; wxPanel* m_panelMainPair; wxStaticText* m_staticText532; wxStaticText* m_staticText5411; - wxPanel* m_panelLeft; - wxPanel* m_panelRight; wxBoxSizer* bSizerAddFolderPairs; @@ -363,6 +369,7 @@ 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 OnCheckAutomatic( wxCommandEvent& event ){ event.Skip(); } virtual void OnCheckFilter( wxCommandEvent& event ){ event.Skip(); } @@ -381,11 +388,17 @@ class BatchDlgGenerated : public wxDialog public: + wxScrolledWindow* m_scrolledWindow6; wxBitmapButton* m_bpButtonAddPair; + wxBitmapButton* m_bpButtonRemovePair; + wxPanel* m_panelLeft; wxTextCtrl* m_directoryLeft; wxDirPickerCtrl* m_dirPickerLeft; + wxBitmapButton* m_bpButtonLocalFilter; + wxPanel* m_panelRight; wxTextCtrl* m_directoryRight; wxDirPickerCtrl* m_dirPickerRight; + wxBitmapButton* m_bpButtonAltSyncCfg; 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(); @@ -520,8 +533,10 @@ class CmpCfgDlgGenerated : public wxDialog protected: wxRadioButton* m_radioBtnSizeDate; + wxStaticBitmap* m_bitmapByTime; wxButton* m_buttonTimeSize; wxRadioButton* m_radioBtnContent; + wxStaticBitmap* m_bitmapByContent; wxButton* m_buttonContent; wxStaticLine* m_staticline14; wxBitmapButton* m_bpButtonHelp; @@ -648,6 +663,35 @@ class HelpDlgGenerated : public wxDialog }; /////////////////////////////////////////////////////////////////////////////// +/// Class ReadmeDlgGenerated +/////////////////////////////////////////////////////////////////////////////// +class ReadmeDlgGenerated : public wxDialog +{ + private: + + protected: + + wxStaticBitmap* m_bitmap25; + wxPanel* m_panel8; + + wxStaticText* m_staticText56; + + + wxTextCtrl* m_textCtrlMain; + wxButton* m_buttonOkay; + + // Virtual event handlers, overide them in your derived class + virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } + virtual void OnOK( wxCommandEvent& event ){ event.Skip(); } + + + public: + ReadmeDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 706,475 ), long style = wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER ); + ~ReadmeDlgGenerated(); + +}; + +/////////////////////////////////////////////////////////////////////////////// /// Class AboutDlgGenerated /////////////////////////////////////////////////////////////////////////////// class AboutDlgGenerated : public wxDialog @@ -836,7 +880,7 @@ class FilterDlgGenerated : public wxDialog protected: wxStaticBitmap* m_bitmap26; wxPanel* m_panel8; - wxStaticText* m_staticText56; + wxStaticText* m_staticTexHeader; wxStaticText* m_staticText44; wxBitmapButton* m_bpButtonHelp; @@ -849,6 +893,7 @@ class FilterDlgGenerated : public wxDialog wxStaticText* m_staticText85; wxStaticText* m_staticText181; wxStaticText* m_staticText1811; + wxStaticText* m_staticTextFilteringInactive; wxStaticText* m_staticText15; wxStaticBitmap* m_bitmap8; @@ -924,6 +969,9 @@ class GlobalSettingsDlgGenerated : public wxDialog wxStaticText* m_staticText114; wxCheckBox* m_checkBoxIgnoreOneHour; + wxStaticText* m_staticTextCopyLocked; + + wxCheckBox* m_checkBoxCopyLocked; wxStaticLine* m_staticline10; wxStaticText* m_staticText100; diff --git a/ui/settingsDialog.cpp b/ui/settingsDialog.cpp index 90437453..230d187d 100644 --- a/ui/settingsDialog.cpp +++ b/ui/settingsDialog.cpp @@ -489,48 +489,14 @@ void SyncCfgDialog::OnConflict(wxCommandEvent& event) toggleSyncDirection(localSyncConfiguration.conflict); updateConfigIcons(cmpVariant, localSyncConfiguration); } -//################################################################################################################################### - - -typedef FreeFileSync::FolderPairPanelBasic<BatchFolderPairGenerated> FolderPairParent; - -class BatchFolderPairPanel : public FolderPairParent -{ -public: - BatchFolderPairPanel(wxWindow* parent, BatchDialog* batchDialog) : - FolderPairParent(parent), - batchDlg(batchDialog) {} - -private: - virtual wxWindow* getParentWindow() - { - return batchDlg; - } - virtual MainConfiguration getMainConfig() const - { - return batchDlg->getCurrentConfiguration().mainCfg; - } - - virtual void OnAltFilterCfgChange(bool defaultValueSet) - { - if (!defaultValueSet) - { - //activate filter - batchDlg->m_checkBoxFilter->SetValue(true); - batchDlg->updateVisibleTabs(); - } - } - BatchDialog* batchDlg; -}; //################################################################################################################################### - class BatchFileDropEvent : public wxFileDropTarget { public: - BatchFileDropEvent(BatchDialog* dlg) : + BatchFileDropEvent(BatchDialog& dlg) : batchDlg(dlg) {} virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames) @@ -543,7 +509,7 @@ public: //test if ffs batch file has been dropped if (fileType == xmlAccess::XML_BATCH_CONFIG) - batchDlg->loadBatchFile(droppedFileName); + batchDlg.loadBatchFile(droppedFileName); else { wxString errorMessage = _("%x is not a valid FreeFileSync batch file!"); @@ -555,10 +521,89 @@ public: } private: - BatchDialog* batchDlg; + BatchDialog& batchDlg; +}; + +//################################################################################################################################### + +//------------------------------------------------------------------ +/* class hierarchy: + + template<> + FolderPairPanelBasic + /|\ + | + template<> + FolderPairCallback BatchFolderPairGenerated + /|\ /|\ + _________|______________ ________| + | | | + FirstBatchFolderPairCfg BatchFolderPairPanel +*/ + +template <class GuiPanel> +class FolderPairCallback : public FolderPairPanelBasic<GuiPanel> //implements callback functionality to BatchDialog as imposed by FolderPairPanelBasic +{ +public: + FolderPairCallback(GuiPanel& basicPanel, BatchDialog& batchDialog) : + FolderPairPanelBasic<GuiPanel>(basicPanel), //pass FolderPairGenerated part... + batchDlg(batchDialog) {} + +private: + virtual wxWindow* getParentWindow() + { + return &batchDlg; + } + + virtual MainConfiguration getMainConfig() const + { + return batchDlg.getCurrentConfiguration().mainCfg; + } + + BatchDialog& batchDlg; +}; + + +class BatchFolderPairPanel : + public BatchFolderPairGenerated, //BatchFolderPairPanel "owns" BatchFolderPairGenerated! + public FolderPairCallback<BatchFolderPairGenerated> +{ +public: + BatchFolderPairPanel(wxWindow* parent, BatchDialog& batchDialog) : + BatchFolderPairGenerated(parent), + FolderPairCallback<BatchFolderPairGenerated>(static_cast<BatchFolderPairGenerated&>(*this), batchDialog), //pass BatchFolderPairGenerated part... + dragDropOnLeft( m_panelLeft, m_dirPickerLeft, m_directoryLeft), + dragDropOnRight(m_panelRight, m_dirPickerRight, m_directoryRight) {} + +private: + //support for drag and drop + DragDropOnDlg dragDropOnLeft; + DragDropOnDlg dragDropOnRight; }; +class FirstBatchFolderPairCfg : public FolderPairCallback<BatchDlgGenerated> +{ +public: + FirstBatchFolderPairCfg(BatchDialog& batchDialog) : + FolderPairCallback<BatchDlgGenerated>(batchDialog, batchDialog), + + //prepare drag & drop + dragDropOnLeft(batchDialog.m_panelLeft, + batchDialog.m_dirPickerLeft, + batchDialog.m_directoryLeft), + dragDropOnRight(batchDialog.m_panelRight, + batchDialog.m_dirPickerRight, + batchDialog.m_directoryRight) {} + +private: + //support for drag and drop + DragDropOnDlg dragDropOnLeft; + DragDropOnDlg dragDropOnRight; +}; + + +//################################################################################################################################### BatchDialog::BatchDialog(wxWindow* window, const xmlAccess::XmlBatchConfig& batchCfg) : BatchDlgGenerated(window) { @@ -577,14 +622,17 @@ BatchDialog::BatchDialog(wxWindow* window, const wxString& filename) : void BatchDialog::init() { + wxWindowUpdateLocker dummy(this); //avoid display distortion + + //init handling of first folder pair + firstFolderPair.reset(new FirstBatchFolderPairCfg(*this)); + + //prepare drag & drop for loading of *.ffs_batch files - SetDropTarget(new BatchFileDropEvent(this)); + 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)); - + //support for drag and drop: user-defined deletion directory dragDropCustomDelFolder.reset(new DragDropOnDlg(m_panelCustomDeletionDir, m_dirPickerCustomDelFolder, m_textCtrlCustomDelFolder)); @@ -769,6 +817,16 @@ void BatchDialog::OnConflict(wxCommandEvent& event) void BatchDialog::OnCheckFilter(wxCommandEvent& event) { updateVisibleTabs(); + + //update main local filter + firstFolderPair->refreshButtons(); + + //update folder pairs + for (std::vector<BatchFolderPairPanel*>::const_iterator i = additionalFolderPairs.begin(); i != additionalFolderPairs.end(); ++i) + { + BatchFolderPairPanel* dirPair = *i; + dirPair->refreshButtons(); + } } @@ -798,7 +856,7 @@ void BatchDialog::OnCheckSilent(wxCommandEvent& event) void BatchDialog::updateVisibleTabs() { - showNotebookpage(m_panelFilter, _("Filter"), m_checkBoxFilter->GetValue()); + showNotebookpage(m_panelFilter, _("Filter"), m_checkBoxFilter->GetValue()); showNotebookpage(m_panelLogging, _("Logging"), m_checkBoxSilent->GetValue()); } @@ -936,8 +994,8 @@ void BatchDialog::OnLoadBatchJob(wxCommandEvent& event) inline FolderPairEnh getEnahncedPair(const BatchFolderPairPanel* panel) { - return FolderPairEnh(wxToZ(panel->m_directoryLeft->GetValue()), - wxToZ(panel->m_directoryRight->GetValue()), + return FolderPairEnh(panel->getLeftDir(), + panel->getRightDir(), panel->getAltSyncConfig(), panel->getAltFilterConfig()); } @@ -956,9 +1014,11 @@ xmlAccess::XmlBatchConfig BatchDialog::getCurrentConfiguration() const batchCfg.mainCfg.handleDeletion = getDeletionHandling(); batchCfg.mainCfg.customDeletionDirectory = m_textCtrlCustomDelFolder->GetValue(); - //main pair - batchCfg.mainCfg.mainFolderPair.leftDirectory = wxToZ(m_directoryLeft->GetValue()); - batchCfg.mainCfg.mainFolderPair.rightDirectory = wxToZ(m_directoryRight->GetValue()); + //first folder pair + batchCfg.mainCfg.firstPair = FolderPairEnh(firstFolderPair->getLeftDir(), + firstFolderPair->getRightDir(), + firstFolderPair->getAltSyncConfig(), + firstFolderPair->getAltFilterConfig()); //add additional pairs batchCfg.mainCfg.additionalPairs.clear(); @@ -1053,10 +1113,11 @@ void BatchDialog::loadBatchCfg(const xmlAccess::XmlBatchConfig& batchCfg) //error handling is dependent from m_checkBoxSilent! /|\ \|/ setSelectionHandleError(batchCfg.handleError); - - //set main folder pair - FreeFileSync::setDirectoryName(zToWx(batchCfg.mainCfg.mainFolderPair.leftDirectory), m_directoryLeft, m_dirPickerLeft); - FreeFileSync::setDirectoryName(zToWx(batchCfg.mainCfg.mainFolderPair.rightDirectory), m_directoryRight, m_dirPickerRight); + //set first folder pair + firstFolderPair->setValues(batchCfg.mainCfg.firstPair.leftDirectory, + batchCfg.mainCfg.firstPair.rightDirectory, + batchCfg.mainCfg.firstPair.altSyncConfig, + batchCfg.mainCfg.firstPair.localFilter); //remove existing additional folder pairs clearAddFolderPairs(); @@ -1074,14 +1135,19 @@ void BatchDialog::loadBatchCfg(const xmlAccess::XmlBatchConfig& batchCfg) void BatchDialog::OnAddFolderPair(wxCommandEvent& event) { + wxWindowUpdateLocker dummy(this); //avoid display distortion + std::vector<FolderPairEnh> newPairs; - newPairs.push_back( - FolderPairEnh(Zstring(), - Zstring(), - boost::shared_ptr<AlternateSyncConfig>(), - boost::shared_ptr<AlternateFilter>())); + newPairs.push_back(getCurrentConfiguration().mainCfg.firstPair); + + addFolderPair(newPairs, true); //add pair in front of additonal pairs - addFolderPair(newPairs, false); //add pair at the end of additional pairs + //clear first pair + const FolderPairEnh cfgEmpty; + firstFolderPair->setValues(cfgEmpty.leftDirectory, + cfgEmpty.rightDirectory, + cfgEmpty.altSyncConfig, + cfgEmpty.localFilter); } @@ -1104,13 +1170,16 @@ 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(); + //get settings from second folder pair + const FolderPairEnh cfgSecond = getEnahncedPair(additionalFolderPairs[0]); - FreeFileSync::setDirectoryName(leftDir, m_directoryLeft, m_dirPickerLeft); - FreeFileSync::setDirectoryName(rightDir, m_directoryRight, m_dirPickerRight); + //reset first pair + firstFolderPair->setValues(cfgSecond.leftDirectory, + cfgSecond.rightDirectory, + cfgSecond.altSyncConfig, + cfgSecond.localFilter); - removeAddFolderPair(0); //remove first of additional folder pairs + removeAddFolderPair(0); //remove second folder pair (first of additional folder pairs) } } @@ -1118,18 +1187,45 @@ void BatchDialog::OnRemoveTopFolderPair(wxCommandEvent& event) const size_t MAX_FOLDER_PAIRS = 3; -void BatchDialog::addFolderPair(const std::vector<FreeFileSync::FolderPairEnh>& newPairs, bool addFront) +void BatchDialog::updateGuiForFolderPair() { - if (newPairs.size() == 0) - return; + //adapt delete top folder pair button + if (additionalFolderPairs.size() == 0) + m_bpButtonRemovePair->Hide(); + else + m_bpButtonRemovePair->Show(); + + //adapt local filter and sync cfg for first folder pair + if ( additionalFolderPairs.size() == 0 && + firstFolderPair->getAltSyncConfig().get() == NULL && + NameFilter(firstFolderPair->getAltFilterConfig().includeFilter, + firstFolderPair->getAltFilterConfig().excludeFilter).isNull()) + { + m_bpButtonLocalFilter->Hide(); + m_bpButtonAltSyncCfg->Hide(); + } + else + { + m_bpButtonLocalFilter->Show(); + m_bpButtonAltSyncCfg->Show(); + } + + m_scrolledWindow6->Fit(); //adjust scrolled window size + m_panelOverview->Layout(); //adjust stuff inside scrolled window +} + +void BatchDialog::addFolderPair(const std::vector<FreeFileSync::FolderPairEnh>& newPairs, bool addFront) +{ wxWindowUpdateLocker dummy(m_panelOverview); //avoid display distortion + if (!newPairs.empty()) +{ //add folder pairs int pairHeight = 0; for (std::vector<FreeFileSync::FolderPairEnh>::const_iterator i = newPairs.begin(); i != newPairs.end(); ++i) { - BatchFolderPairPanel* newPair = new BatchFolderPairPanel(m_scrolledWindow6, this); + BatchFolderPairPanel* newPair = new BatchFolderPairPanel(m_scrolledWindow6, *this); if (addFront) { @@ -1148,12 +1244,11 @@ void BatchDialog::addFolderPair(const std::vector<FreeFileSync::FolderPairEnh>& //register events newPair->m_bpButtonRemovePair->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BatchDialog::OnRemoveFolderPair), NULL, this ); - //insert directory names - FreeFileSync::setDirectoryName(zToWx(i->leftDirectory), newPair->m_directoryLeft, newPair->m_dirPickerLeft); - FreeFileSync::setDirectoryName(zToWx(i->rightDirectory), newPair->m_directoryRight, newPair->m_dirPickerRight); - //set alternate configuration - newPair->setValues(i->altSyncConfig, i->altFilter); + newPair->setValues(i->leftDirectory, + i->rightDirectory, + i->altSyncConfig, + i->localFilter); } //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 @@ -1168,13 +1263,16 @@ void BatchDialog::addFolderPair(const std::vector<FreeFileSync::FolderPairEnh>& m_bpButtonLeftOnly->SetFocus(); } + updateGuiForFolderPair(); +} + void BatchDialog::removeAddFolderPair(const int pos) { - if (0 <= pos && pos < static_cast<int>(additionalFolderPairs.size())) - { wxWindowUpdateLocker dummy(m_panelOverview); //avoid display distortion + if (0 <= pos && pos < static_cast<int>(additionalFolderPairs.size())) + { //remove folder pairs from window BatchFolderPairPanel* pairToDelete = additionalFolderPairs[pos]; const int pairHeight = pairToDelete->GetSize().GetHeight(); @@ -1197,6 +1295,8 @@ void BatchDialog::removeAddFolderPair(const int pos) //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(); } + + updateGuiForFolderPair(); } diff --git a/ui/settingsDialog.h b/ui/settingsDialog.h index feb763a9..0864cf92 100644 --- a/ui/settingsDialog.h +++ b/ui/settingsDialog.h @@ -7,6 +7,7 @@ class BatchFileDropEvent; class BatchFolderPairPanel; +class FirstBatchFolderPairCfg; namespace FreeFileSync { @@ -97,7 +98,8 @@ private: class BatchDialog: public BatchDlgGenerated { friend class BatchFileDropEvent; - friend class BatchFolderPairPanel; + template <class GuiPanel> + friend class FolderPairCallback; public: BatchDialog(wxWindow* window, const xmlAccess::XmlBatchConfig& batchCfg); @@ -135,6 +137,8 @@ private: void removeAddFolderPair(const int pos); void clearAddFolderPairs(); +void updateGuiForFolderPair(); + FreeFileSync::CompareVariant getCurrentCompareVar() const; void updateConfigIcons(const FreeFileSync::CompareVariant cmpVar, const FreeFileSync::SyncConfiguration& syncConfig); @@ -163,6 +167,8 @@ private: xmlAccess::XmlBatchConfig getCurrentConfiguration() const; FreeFileSync::SyncConfiguration localSyncConfiguration; + + boost::shared_ptr<FirstBatchFolderPairCfg> firstFolderPair; //always bound!!! std::vector<BatchFolderPairPanel*> additionalFolderPairs; //used when saving batch file @@ -170,11 +176,6 @@ private: //add drag & drop support when selecting logfile directory std::auto_ptr<FreeFileSync::DragDropOnDlg> dragDropOnLogfileDir; - - //support for drag and drop on main pair - std::auto_ptr<FreeFileSync::DragDropOnDlg> dragDropOnLeft; - std::auto_ptr<FreeFileSync::DragDropOnDlg> dragDropOnRight; - std::auto_ptr<FreeFileSync::DragDropOnDlg> dragDropCustomDelFolder; }; diff --git a/ui/sorting.h b/ui/sorting.h index e65344e6..04ecc171 100644 --- a/ui/sorting.h +++ b/ui/sorting.h @@ -72,7 +72,8 @@ bool sortByFileName(const FileSystemObject& a, const FileSystemObject& b) if (dynamic_cast<const DirMapping*>(&b)) return true; else - return Compare<ascending>().isSmallerThan(a.getShortName<side>(), b.getShortName<side>()); + return Compare<ascending>().isSmallerThan( + compareString(a.getShortName<side>(), b.getShortName<side>()), 0); } } diff --git a/ui/trayIcon.cpp b/ui/trayIcon.cpp index 42847eb0..478d135a 100644 --- a/ui/trayIcon.cpp +++ b/ui/trayIcon.cpp @@ -1,7 +1,7 @@ #include "trayIcon.h" #include "../library/resources.h" #include "smallDialogs.h" -#include "../library/statusHandler.h" +//#include "../library/statusHandler.h" #include <wx/taskbar.h> @@ -79,7 +79,7 @@ void MinimizeToTray::resumeFromTray() //remove trayIcon and restore windows: Mi trayIcon->RemoveIcon(); //hide icon until final deletion takes place trayIcon->Disconnect(wxEVT_TASKBAR_LEFT_DCLICK, wxCommandEventHandler(MinimizeToTray::OnDoubleClick), NULL, this); - //delayed destruction: delete during next idle loop iteration (handle late window messages, e.g. when double-clicking) + //use wxWidgets delayed destruction: delete during next idle loop iteration (handle late window messages, e.g. when double-clicking) if (!wxPendingDelete.Member(trayIcon)) wxPendingDelete.Append(trayIcon); diff --git a/ui/trayIcon.h b/ui/trayIcon.h index 370e85f3..94e75518 100644 --- a/ui/trayIcon.h +++ b/ui/trayIcon.h @@ -13,6 +13,7 @@ public: void setToolTip(const wxString& toolTipText); void keepHidden(); //do not show windows again: avoid window flashing shortly before it is destroyed + private: void OnContextMenuSelection(wxCommandEvent& event); void OnDoubleClick(wxCommandEvent& event); |