diff options
Diffstat (limited to 'ui')
-rw-r--r-- | ui/MainDialog.cpp | 213 | ||||
-rw-r--r-- | ui/MainDialog.h | 29 | ||||
-rw-r--r-- | ui/SmallDialogs.cpp | 1009 | ||||
-rw-r--r-- | ui/SmallDialogs.h | 368 | ||||
-rw-r--r-- | ui/appMain.h | 20 | ||||
-rw-r--r-- | ui/batchStatusHandler.cpp | 87 | ||||
-rw-r--r-- | ui/batchStatusHandler.h | 10 | ||||
-rw-r--r-- | ui/checkVersion.cpp | 17 | ||||
-rw-r--r-- | ui/checkVersion.h | 6 | ||||
-rw-r--r-- | ui/folderPair.h | 35 | ||||
-rw-r--r-- | ui/gridView.cpp | 50 | ||||
-rw-r--r-- | ui/gridView.h | 10 | ||||
-rw-r--r-- | ui/guiGenerated.cpp | 391 | ||||
-rw-r--r-- | ui/guiGenerated.h | 93 | ||||
-rw-r--r-- | ui/guiStatusHandler.cpp | 125 | ||||
-rw-r--r-- | ui/guiStatusHandler.h | 9 | ||||
-rw-r--r-- | ui/messagePopup.cpp | 180 | ||||
-rw-r--r-- | ui/messagePopup.h | 80 | ||||
-rw-r--r-- | ui/mouseMoveWindow.cpp | 26 | ||||
-rw-r--r-- | ui/mouseMoveWindow.h | 36 | ||||
-rw-r--r-- | ui/progressIndicator.cpp | 773 | ||||
-rw-r--r-- | ui/progressIndicator.h | 76 | ||||
-rw-r--r-- | ui/search.cpp | 264 | ||||
-rw-r--r-- | ui/search.h | 20 | ||||
-rw-r--r-- | ui/settingsDialog.cpp | 105 | ||||
-rw-r--r-- | ui/settingsDialog.h | 13 | ||||
-rw-r--r-- | ui/sorting.h | 37 | ||||
-rw-r--r-- | ui/trayIcon.cpp | 179 | ||||
-rw-r--r-- | ui/trayIcon.h | 6 | ||||
-rw-r--r-- | ui/util.cpp | 12 | ||||
-rw-r--r-- | ui/util.h | 8 |
31 files changed, 2615 insertions, 1672 deletions
diff --git a/ui/MainDialog.cpp b/ui/MainDialog.cpp index 4d255950..932d0b4a 100644 --- a/ui/MainDialog.cpp +++ b/ui/MainDialog.cpp @@ -1,3 +1,9 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// #include "mainDialog.h" #include <wx/filename.h> #include <stdexcept> @@ -19,6 +25,7 @@ #include "../shared/localization.h" #include "../shared/stringConv.h" #include "smallDialogs.h" +#include "messagePopup.h" #include "../shared/dragAndDrop.h" #include "../library/filter.h" #include "../structures.h" @@ -27,12 +34,15 @@ #include "gridView.h" #include "../library/resources.h" #include "../shared/fileHandling.h" +#include "../shared/recycler.h" #include "../shared/xmlBase.h" #include "../shared/standardPaths.h" #include "../shared/toggleButton.h" #include "folderPair.h" #include "../shared/globalFunctions.h" #include <wx/sound.h> +#include "search.h" +#include "../shared/helpProvider.h" using namespace FreeFileSync; using FreeFileSync::CustomLocale; @@ -241,23 +251,28 @@ struct DirNotFound //################################################################################################################################## MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, - xmlAccess::XmlGlobalSettings& settings, - wxHelpController& helpController) : + xmlAccess::XmlGlobalSettings& settings) : MainDialogGenerated(frame), globalSettings(settings), gridDataView(new FreeFileSync::GridView()), contextMenu(new wxMenu), //initialize right-click context menu; will be dynamically re-created on each R-mouse-click + compareStatus(*this), cleanedUp(false), lastSortColumn(-1), lastSortGrid(NULL), #ifdef FFS_WIN updateFileIcons(new IconUpdater(m_gridLeft, m_gridRight)), + moveWholeWindow(this), #endif - helpController_(helpController), syncPreview(this) { wxWindowUpdateLocker dummy(this); //avoid display distortion +//avoid mirroring this dialog in RTL languages like Hebrew or Arabic +SetLayoutDirection(wxLayout_LeftToRight); +m_panelStatusBar->SetLayoutDirection(wxLayout_LeftToRight); + + //init handling of first folder pair firstFolderPair.reset(new FirstFolderPairCfg(*this)); @@ -304,6 +319,17 @@ MainDialog::MainDialog(wxFrame* frame, MenuItemUpdater updateMenuHelp(m_menuHelp); updateMenuHelp.addForUpdate(m_menuItemAbout, GlobalResources::getInstance().getImageByName(wxT("aboutSmall"))); +#ifdef FFS_WIN + //allow moving main dialog by clicking (nearly) anywhere... + moveWholeWindow.connectSourceWindow(m_panel71); + moveWholeWindow.connectSourceWindow(m_panelBottom); + moveWholeWindow.connectSourceWindow(m_panelStatusBar); +#endif + +#ifdef FFS_LINUX + if (!FreeFileSync::isPortableVersion()) //disable update check for Linux installer-based version -> handled by .deb + m_menuItemCheckVer->Enable(false); +#endif //create language selection menu for (std::vector<LocInfoLine>::const_iterator i = LocalizationInfo::getMapping().begin(); i != LocalizationInfo::getMapping().end(); ++i) @@ -319,7 +345,7 @@ MainDialog::MainDialog(wxFrame* frame, m_menuLanguages->Append(newItem); } - //support for CTRL + C and DEL + //support for CTRL + C and DEL on grids m_gridLeft->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainDialog::onGridLeftButtonEvent), NULL, this); m_gridRight->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainDialog::onGridRightButtonEvent), NULL, this); m_gridMiddle->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainDialog::onGridMiddleButtonEvent), NULL, this); @@ -346,11 +372,10 @@ MainDialog::MainDialog(wxFrame* frame, //mainly to update row label sizes... updateGuiGrid(); - //create the compare status panel in hidden state - compareStatus = new CompareStatus(this); - bSizer1->Insert(1, compareStatus, 0, wxEXPAND | wxBOTTOM, 5 ); + //integrate the compare status panel (in hidden state) + bSizer1->Insert(1, compareStatus.getAsWindow(), 0, wxEXPAND | wxBOTTOM, 5 ); Layout(); //avoid screen flicker when panel is shown later - compareStatus->Hide(); + compareStatus.getAsWindow()->Hide(); //correct width of swap button above middle grid const wxSize source = m_gridMiddle->GetSize(); @@ -385,6 +410,8 @@ MainDialog::MainDialog(wxFrame* frame, MainDialog::~MainDialog() { + //keep non-inline destructor for std::auto_ptr to work with forward declaration + cleanUp(); //do NOT include any other code here! cleanUp() is re-used when switching languages } @@ -398,7 +425,7 @@ void MainDialog::cleanUp() //no need for wxEventHandler::Disconnect() here; done automatically when window is destoyed! //save configuration - writeConfigurationToXml(lastConfigFileName()); //don't trow exceptions in destructors + writeConfigurationToXml(lastConfigFileName()); //don't throw exceptions in destructors writeGlobalSettings(); } } @@ -547,7 +574,7 @@ void MainDialog::OnIdleEvent(wxEvent& event) if (stackObjects.empty()) m_staticTextStatusMiddle->SetForegroundColour(*wxBLACK); //reset color - m_panel7->Layout(); + m_panelStatusBar->Layout(); } } @@ -672,7 +699,7 @@ public: statusMessage.Replace(wxT("%y"), globalFunctions::numberToWxString(totalObjToDelete), false); mainDlg->m_staticTextStatusMiddle->SetLabel(statusMessage); - mainDlg->m_panel7->Layout(); + mainDlg->m_panelStatusBar->Layout(); updateUiNow(); } @@ -714,17 +741,15 @@ void MainDialog::deleteSelectedFiles() int totalDeleteCount = 0; - DeleteDialog* confirmDeletion = new DeleteDialog(this, //no destruction needed; attached to main window - compRefLeft, - compRefRight, - globalSettings.gui.deleteOnBothSides, - globalSettings.gui.useRecyclerForManualDeletion, - totalDeleteCount); - if (confirmDeletion->ShowModal() == DeleteDialog::BUTTON_OKAY) + if (FreeFileSync::showDeleteDialog(compRefLeft, + compRefRight, + globalSettings.gui.deleteOnBothSides, + globalSettings.gui.useRecyclerForManualDeletion, + totalDeleteCount) == DefaultReturnCode::BUTTON_OKAY) { if (globalSettings.gui.useRecyclerForManualDeletion && !FreeFileSync::recycleBinExists()) { - wxMessageBox(_("Unable to initialize Recycle Bin!")); + wxMessageBox(_("Recycle Bin not yet supported for this system!")); return; } @@ -847,7 +872,7 @@ void MainDialog::pushStatusInformation(const wxString& text) stackObjects.push(m_staticTextStatusMiddle->GetLabel()); m_staticTextStatusMiddle->SetLabel(text); m_staticTextStatusMiddle->SetForegroundColour(wxColour(31, 57, 226)); //highlight color: blue - m_panel7->Layout(); + m_panelStatusBar->Layout(); } @@ -988,15 +1013,19 @@ void MainDialog::onGridLeftButtonEvent(wxKeyEvent& event) if (event.ControlDown()) switch (keyCode) { - case 67: + case 'C': case WXK_INSERT: //CTRL + C || CTRL + INS copySelectionToClipboard(m_gridLeft); break; - case 65: //CTRL + A + case 'A': //CTRL + A m_gridLeft->SelectAll(); break; + case 'F': //CTRL + F + FreeFileSync::startFind(*this, *m_gridLeft, *m_gridRight, globalSettings.gui.textSearchRespectCase); + break; + case WXK_NUMPAD_ADD: //CTRL + '+' m_gridLeft->autoSizeColumns(); break; @@ -1050,6 +1079,11 @@ void MainDialog::onGridLeftButtonEvent(wxKeyEvent& event) OnContextOpenWith(dummy); } break; + + case WXK_F3: //F3 + case WXK_NUMPAD_F3: // + FreeFileSync::findNext(*this, *m_gridLeft, *m_gridRight, globalSettings.gui.textSearchRespectCase); + break; } //event.Skip(); -> swallow event! don't allow default grid commands! @@ -1077,15 +1111,19 @@ void MainDialog::onGridRightButtonEvent(wxKeyEvent& event) if (event.ControlDown()) switch (keyCode) { - case 67: + case 'C': case WXK_INSERT: //CTRL + C || CTRL + INS copySelectionToClipboard(m_gridRight); break; - case 65: //CTRL + A + case 'A': //CTRL + A m_gridRight->SelectAll(); break; + case 'F': //CTRL + F + FreeFileSync::startFind(*this, *m_gridLeft, *m_gridRight, globalSettings.gui.textSearchRespectCase); + break; + case WXK_NUMPAD_ADD: //CTRL + '+' m_gridRight->autoSizeColumns(); break; @@ -1139,7 +1177,13 @@ void MainDialog::onGridRightButtonEvent(wxKeyEvent& event) OnContextOpenWith(dummy); } break; + + case WXK_F3: //F3 + case WXK_NUMPAD_F3: // + FreeFileSync::findNext(*this, *m_gridLeft, *m_gridRight, globalSettings.gui.textSearchRespectCase); + break; } + //event.Skip(); -> swallow event! don't allow default grid commands! } @@ -1218,17 +1262,23 @@ void MainDialog::OnContextRim(wxGridEvent& event) if (selectionLeft.size() + selectionRight.size() > 0) { //CONTEXT_SYNC_DIR_LEFT - wxMenuItem* menuItemSyncDirLeft = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_LEFT, wxString(_("Change direction")) + wxT("\tALT + LEFT")); + wxMenuItem* menuItemSyncDirLeft = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_LEFT, wxString(_("Set direction:")) + + wxT(" ") + getSymbol(fsObj->testSyncOperation(true, SYNC_DIR_LEFT)) + + wxT("\tALT + LEFT")); //Linux needs a direction, "<-", because it has no context menu icons! 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, wxString(_("Change direction")) + wxT("\tALT + UP")); + wxMenuItem* menuItemSyncDirNone = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_NONE, wxString(_("Set direction:")) + + wxT(" ") + getSymbol(fsObj->testSyncOperation(true, SYNC_DIR_NONE)) + + 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, wxString(_("Change direction")) + wxT("\tALT + RIGHT")); + wxMenuItem* menuItemSyncDirRight = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_RIGHT, wxString(_("Set direction:")) + + wxT(" ") + getSymbol(fsObj->testSyncOperation(true, SYNC_DIR_RIGHT)) + + wxT("\tALT + RIGHT")); menuItemSyncDirRight->SetBitmap(getSyncOpImage(fsObj->testSyncOperation(true, SYNC_DIR_RIGHT))); contextMenu->Append(menuItemSyncDirRight); @@ -1336,10 +1386,15 @@ void MainDialog::OnContextRim(wxGridEvent& event) i != globalSettings.gui.externelApplications.end(); ++i, ++newID) { + //some trick to translate default external apps on the fly: 1. "open in explorer" 2. "start directly" + wxString description = wxGetTranslation(i->first); + if (description.empty()) + description = wxT(" "); //wxWidgets doesn't like empty items + if (i == globalSettings.gui.externelApplications.begin()) - contextMenu->Append(newID, i->first + wxT("\t") + wxString(_("D-Click")) + wxT("; ENTER")); + contextMenu->Append(newID, description + wxT("\t") + wxString(_("D-Click")) + wxT("; ENTER")); else - contextMenu->Append(newID, i->first.empty() ? wxT(" ") : i->first); //wxWidgets doesn't like empty items + contextMenu->Append(newID, description); contextMenu->Enable(newID, externalAppEnabled); @@ -1433,7 +1488,7 @@ void MainDialog::OnContextExcludeObject(wxCommandEvent& event) if (!i->isDir) currentCfg.mainCfg.excludeFilter += Zstring() + globalFunctions::FILE_NAME_SEPARATOR + i->relativeName; else - currentCfg.mainCfg.excludeFilter += Zstring() + globalFunctions::FILE_NAME_SEPARATOR + i->relativeName + globalFunctions::FILE_NAME_SEPARATOR + DefaultStr("*"); + currentCfg.mainCfg.excludeFilter += Zstring() + globalFunctions::FILE_NAME_SEPARATOR + i->relativeName + globalFunctions::FILE_NAME_SEPARATOR; } m_checkBoxActivateFilter->SetValue(true); @@ -1549,13 +1604,10 @@ void MainDialog::OnContextRimLabelRight(wxGridEvent& event) void MainDialog::OnContextCustColumnLeft(wxCommandEvent& event) { xmlAccess::ColumnAttributes colAttr = m_gridLeft->getColumnAttributes(); - CustomizeColsDlg* customizeDlg = new CustomizeColsDlg(this, colAttr, globalSettings.gui.showFileIconsLeft); - if (customizeDlg->ShowModal() == CustomizeColsDlg::BUTTON_OKAY) + + if (FreeFileSync::showCustomizeColsDlg(colAttr) == DefaultReturnCode::BUTTON_OKAY) { m_gridLeft->setColumnAttributes(colAttr); -#ifdef FFS_WIN - m_gridLeft->enableFileIcons(globalSettings.gui.showFileIconsLeft); -#endif m_gridLeft->setSortMarker(CustomGrid::SortMarker(-1, CustomGrid::ASCENDING)); //hide sort direction indicator on GUI grids m_gridMiddle->setSortMarker(CustomGrid::SortMarker(-1, CustomGrid::ASCENDING)); @@ -1567,13 +1619,10 @@ void MainDialog::OnContextCustColumnLeft(wxCommandEvent& event) void MainDialog::OnContextCustColumnRight(wxCommandEvent& event) { xmlAccess::ColumnAttributes colAttr = m_gridRight->getColumnAttributes(); - CustomizeColsDlg* customizeDlg = new CustomizeColsDlg(this, colAttr, globalSettings.gui.showFileIconsRight); - if (customizeDlg->ShowModal() == CustomizeColsDlg::BUTTON_OKAY) + + if (FreeFileSync::showCustomizeColsDlg(colAttr) == DefaultReturnCode::BUTTON_OKAY) { m_gridRight->setColumnAttributes(colAttr); -#ifdef FFS_WIN - m_gridRight->enableFileIcons(globalSettings.gui.showFileIconsRight); -#endif m_gridLeft->setSortMarker(CustomGrid::SortMarker(-1, CustomGrid::ASCENDING)); //hide sort direction indicator on GUI grids m_gridMiddle->setSortMarker(CustomGrid::SortMarker(-1, CustomGrid::ASCENDING)); @@ -2121,9 +2170,7 @@ xmlAccess::XmlGuiConfig MainDialog::getCurrentConfiguration() const const wxString& MainDialog::lastConfigFileName() { - static wxString instance = FreeFileSync::getConfigDir().EndsWith(zToWx(globalFunctions::FILE_NAME_SEPARATOR)) ? - FreeFileSync::getConfigDir() + wxT("LastRun.ffs_gui") : - FreeFileSync::getConfigDir() + zToWx(globalFunctions::FILE_NAME_SEPARATOR) + wxT("LastRun.ffs_gui"); + static wxString instance = FreeFileSync::getConfigDir() + wxT("LastRun.ffs_gui"); return instance; } @@ -2175,12 +2222,10 @@ void MainDialog::OnHideFilteredButton(wxCommandEvent &event) void MainDialog::OnConfigureFilter(wxCommandEvent &event) { - 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 (showFilterDialog(true, //is main filter dialog + currentCfg.mainCfg.includeFilter, + currentCfg.mainCfg.excludeFilter, + m_checkBoxActivateFilter->GetValue()) == DefaultReturnCode::BUTTON_OKAY) { updateFilterButtons(); //refresh global filter icon updateFilterConfig(); //re-apply filter @@ -2194,98 +2239,98 @@ void MainDialog::OnLeftOnlyFiles(wxCommandEvent& event) { m_bpButtonLeftOnly->toggle(); updateGuiGrid(); -}; +} void MainDialog::OnLeftNewerFiles(wxCommandEvent& event) { m_bpButtonLeftNewer->toggle(); updateGuiGrid(); -}; +} void MainDialog::OnDifferentFiles(wxCommandEvent& event) { m_bpButtonDifferent->toggle(); updateGuiGrid(); -}; +} void MainDialog::OnRightNewerFiles(wxCommandEvent& event) { m_bpButtonRightNewer->toggle(); updateGuiGrid(); -}; +} void MainDialog::OnRightOnlyFiles(wxCommandEvent& event) { m_bpButtonRightOnly->toggle(); updateGuiGrid(); -}; +} void MainDialog::OnEqualFiles(wxCommandEvent& event) { m_bpButtonEqual->toggle(); updateGuiGrid(); -}; +} void MainDialog::OnConflictFiles(wxCommandEvent& event) { m_bpButtonConflict->toggle(); updateGuiGrid(); -}; +} void MainDialog::OnSyncCreateLeft(wxCommandEvent& event) { m_bpButtonSyncCreateLeft->toggle(); updateGuiGrid(); -}; +} void MainDialog::OnSyncCreateRight(wxCommandEvent& event) { m_bpButtonSyncCreateRight->toggle(); updateGuiGrid(); -}; +} void MainDialog::OnSyncDeleteLeft(wxCommandEvent& event) { m_bpButtonSyncDeleteLeft->toggle(); updateGuiGrid(); -}; +} void MainDialog::OnSyncDeleteRight(wxCommandEvent& event) { m_bpButtonSyncDeleteRight->toggle(); updateGuiGrid(); -}; +} void MainDialog::OnSyncDirLeft(wxCommandEvent& event) { m_bpButtonSyncDirOverwLeft->toggle(); updateGuiGrid(); -}; +} void MainDialog::OnSyncDirRight(wxCommandEvent& event) { m_bpButtonSyncDirOverwRight->toggle(); updateGuiGrid(); -}; +} void MainDialog::OnSyncDirNone(wxCommandEvent& event) { m_bpButtonSyncDirNone->toggle(); updateGuiGrid(); -}; +} void MainDialog::initViewFilterButtons() @@ -2457,7 +2502,6 @@ void MainDialog::OnCompare(wxCommandEvent &event) FreeFileSync::CompareProcess comparison(currentCfg.mainCfg.hidden.traverseDirectorySymlinks, currentCfg.mainCfg.hidden.fileTimeTolerance, globalSettings.ignoreOneHourDiff, - globalSettings.detectRenameThreshold, globalSettings.optDialogs, &statusHandler); @@ -2472,7 +2516,7 @@ void MainDialog::OnCompare(wxCommandEvent &event) gridDataView->setData(newCompareData); //newCompareData is invalidated after this call //play (optional) sound notification after sync has completed (GUI and batch mode) - const wxString soundFile = FreeFileSync::getInstallationDir() + wxT("Compare_Complete.wav"); + const wxString soundFile = FreeFileSync::getResourceDir() + wxT("Compare_Complete.wav"); if (fileExists(wxToZ(soundFile))) wxSound::Play(soundFile, wxSOUND_ASYNC); } @@ -2609,8 +2653,7 @@ void MainDialog::OnCmpSettings(wxCommandEvent& event) wxPoint windowPos = m_bpButtonCmpConfig->GetScreenPosition(); windowPos.x += m_bpButtonCmpConfig->GetSize().GetWidth() + 5; - CompareCfgDialog* syncDlg = new CompareCfgDialog(this, windowPos, newCmpVariant); - if (syncDlg->ShowModal() == CompareCfgDialog::BUTTON_OKAY) + if (FreeFileSync::showCompareCfgDialog(windowPos, newCmpVariant) == DefaultReturnCode::BUTTON_OKAY) { if (currentCfg.mainCfg.compareVar != newCmpVariant) { @@ -2646,13 +2689,10 @@ void MainDialog::OnStartSync(wxCommandEvent& event) { bool dontShowAgain = false; - SyncPreviewDlg* preview = new SyncPreviewDlg( - this, - getCurrentConfiguration().mainCfg.getSyncVariantName(), - FreeFileSync::SyncStatistics(gridDataView->getDataTentative()), - dontShowAgain); - - if (preview->ShowModal() != SyncPreviewDlg::BUTTON_START) + if (FreeFileSync::showSyncPreviewDlg( + getCurrentConfiguration().mainCfg.getSyncVariantName(), + FreeFileSync::SyncStatistics(gridDataView->getDataTentative()), + dontShowAgain) != DefaultReturnCode::BUTTON_OKAY) return; globalSettings.optDialogs.showSummaryBeforeSync = !dontShowAgain; @@ -2694,7 +2734,7 @@ void MainDialog::OnStartSync(wxCommandEvent& event) synchronization.startSynchronizationProcess(syncProcessCfg, dataToSync); //play (optional) sound notification after sync has completed (GUI and batch mode) - const wxString soundFile = FreeFileSync::getInstallationDir() + wxT("Sync_Complete.wav"); + const wxString soundFile = FreeFileSync::getResourceDir() + wxT("Sync_Complete.wav"); if (fileExists(wxToZ(soundFile))) wxSound::Play(soundFile, wxSOUND_ASYNC); } @@ -2767,6 +2807,9 @@ void MainDialog::OnSortLeftGrid(wxGridEvent& event) case xmlAccess::DATE: gridDataView->sortView(GridView::SORT_BY_DATE, true, sortAscending); break; + case xmlAccess::EXTENSION: + gridDataView->sortView(GridView::SORT_BY_EXTENSION, true, sortAscending); + break; } updateGuiGrid(); //refresh gridDataView @@ -2842,6 +2885,9 @@ void MainDialog::OnSortRightGrid(wxGridEvent& event) case xmlAccess::DATE: gridDataView->sortView(GridView::SORT_BY_DATE, false, sortAscending); break; + case xmlAccess::EXTENSION: + gridDataView->sortView(GridView::SORT_BY_EXTENSION, false, sortAscending); + break; } updateGuiGrid(); //refresh gridDataView @@ -3129,7 +3175,7 @@ void MainDialog::updateGridViewData() if (m_staticTextStatusRight->GetLabel() != statusRightNew) m_staticTextStatusRight->SetLabel(statusRightNew); - m_panel7->Layout(); + m_panelStatusBar->Layout(); } @@ -3395,8 +3441,7 @@ void MainDialog::clearAddFolderPairs() //menu events void MainDialog::OnMenuGlobalSettings(wxCommandEvent& event) { - wxDialog* settingsDlg = new GlobalSettingsDlg(this, globalSettings); - settingsDlg->ShowModal(); + FreeFileSync::showGlobalSettingsDlg(globalSettings); //event.Skip(); } @@ -3436,7 +3481,7 @@ void MainDialog::OnMenuExportFileList(wxCommandEvent& event) exportString += wxString(wxT("\"")) + getDescription(SO_OVERWRITE_LEFT) + wxT("\";") + getSymbol(SO_OVERWRITE_LEFT) + wxT('\n'); exportString += wxString(wxT("\"")) + getDescription(SO_OVERWRITE_RIGHT) + wxT("\";") + getSymbol(SO_OVERWRITE_RIGHT) + wxT('\n'); exportString += wxString(wxT("\"")) + getDescription(SO_DO_NOTHING) + wxT("\";") + getSymbol(SO_DO_NOTHING) + wxT('\n'); - exportString += wxString(wxT("\"")) + getDescription(SO_DO_NOTHING) + wxT("\";") + getSymbol(SO_EQUAL) + wxT('\n'); + exportString += wxString(wxT("\"")) + getDescription(SO_EQUAL) + wxT("\";") + getSymbol(SO_EQUAL) + wxT('\n'); exportString += wxString(wxT("\"")) + getDescription(SO_UNRESOLVED_CONFLICT) + wxT("\";") + getSymbol(SO_UNRESOLVED_CONFLICT) + wxT('\n'); } else @@ -3562,15 +3607,13 @@ void MainDialog::OnLayoutWindowAsync(wxIdleEvent& event) void MainDialog::OnMenuAbout(wxCommandEvent& event) { - AboutDlg* aboutDlg = new AboutDlg(this); - aboutDlg->ShowModal(); + FreeFileSync::showAboutDialog(); } - void MainDialog::OnShowHelp(wxCommandEvent& event) { - helpController_.DisplayContents(); +FreeFileSync::displayHelpEntry(); } @@ -3593,7 +3636,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, helpController_); + MainDialog* frame = new MainDialog(NULL, wxEmptyString, globalSettings); frame->SetIcon(*GlobalResources::getInstance().programIcon); //set application icon frame->Show(); @@ -3674,3 +3717,5 @@ bool MainDialog::SyncPreview::synchronizationIsEnabled() const + + diff --git a/ui/MainDialog.h b/ui/MainDialog.h index ff9fee09..7c30f8a3 100644 --- a/ui/MainDialog.h +++ b/ui/MainDialog.h @@ -1,10 +1,9 @@ -/*************************************************************** - * Name: mainDialog.h - * Purpose: Main Application Dialog - * Author: ZenJu (zhnmju123@gmx.de) - * Created: 2008-07-16 - **************************************************************/ - +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// #ifndef MAINDIALOG_H #define MAINDIALOG_H @@ -14,10 +13,10 @@ #include <memory> #include <map> #include <set> -#include <wx/help.h> +#include "mouseMoveWindow.h" +#include "progressIndicator.h" class CompareStatusHandler; -class CompareStatus; class MainFolderDragDrop; class CustomGrid; class FFSCheckRowsEvent; @@ -81,8 +80,7 @@ class MainDialog : public MainDialogGenerated public: MainDialog(wxFrame* frame, const wxString& cfgFileName, - xmlAccess::XmlGlobalSettings& settings, - wxHelpController& helpController); + xmlAccess::XmlGlobalSettings& settings); ~MainDialog(); @@ -206,7 +204,6 @@ private: bool trySaveConfig(); //return true if saved successfully bool saveOldConfig(); //return false on user abort - void loadConfiguration(const wxString& filename); void OnCfgHistoryKeyEvent( wxKeyEvent& event); void OnRegularUpdateCheck( wxIdleEvent& event); @@ -286,7 +283,7 @@ private: std::stack<wxString> stackObjects; //compare status panel (hidden on start, shown when comparing) - CompareStatus* compareStatus; + CompareStatus compareStatus; //save the last used config filename history std::vector<wxString> cfgFileNames; @@ -301,10 +298,10 @@ private: #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_; + //enable moving window by clicking on sub-windows instead of header line + FreeFileSync::MouseMoveWindow moveWholeWindow; +#endif //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 cab26472..346b0ae6 100644 --- a/ui/SmallDialogs.cpp +++ b/ui/SmallDialogs.cpp @@ -1,25 +1,39 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// +#include "guiGenerated.h" #include "smallDialogs.h" +#include "messagePopup.h" #include "../library/resources.h" #include "../algorithm.h" #include "../shared/stringConv.h" #include "util.h" #include "../synchronization.h" -#include <wx/msgdlg.h> #include "../library/customGrid.h" #include "../shared/customButton.h" -#include "../library/statistics.h" #include "../shared/localization.h" -#include "../shared/fileHandling.h" -#include "../library/statusHandler.h" -#include <wx/wupdlock.h> #include "../shared/globalFunctions.h" -#include "trayIcon.h" -#include "../shared/staticAssert.h" #include "../shared/buildInfo.h" +#include <wx/wupdlock.h> +#include <wx/msgdlg.h> using namespace FreeFileSync; +class AboutDlg : public AboutDlgGenerated +{ +public: + AboutDlg(wxWindow* window); + +private: + void OnClose(wxCloseEvent& event); + void OnOK(wxCommandEvent& event); +}; + + AboutDlg::AboutDlg(wxWindow* window) : AboutDlgGenerated(window) { m_bitmap9->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("website"))); @@ -84,9 +98,28 @@ void AboutDlg::OnOK(wxCommandEvent& event) { EndModal(0); } + + +void FreeFileSync::showAboutDialog() +{ + AboutDlg* aboutDlg = new AboutDlg(NULL); + aboutDlg->ShowModal(); + aboutDlg->Destroy(); +} //######################################################################################## +class HelpDlg : public HelpDlgGenerated +{ +public: + HelpDlg(wxWindow* window); + +private: + void OnClose(wxCloseEvent& event); + void OnOK(wxCommandEvent& event); +}; + + HelpDlg::HelpDlg(wxWindow* window) : HelpDlgGenerated(window) { m_notebook1->SetFocus(); @@ -137,7 +170,43 @@ void HelpDlg::OnOK(wxCommandEvent& event) } +void FreeFileSync::showHelpDialog() +{ + HelpDlg* helpDlg = new HelpDlg(NULL); + helpDlg->ShowModal(); + helpDlg->Destroy(); +} //######################################################################################## + + +class FilterDlg : public FilterDlgGenerated +{ +public: + FilterDlg(wxWindow* window, + bool isGlobalFilter, + Zstring& filterIncl, + Zstring& filterExcl, + bool filterActive); + ~FilterDlg() {} + + enum + { + BUTTON_APPLY = 1 + }; + +private: + void OnHelp(wxCommandEvent& event); + void OnDefault(wxCommandEvent& event); + void OnApply(wxCommandEvent& event); + void OnCancel(wxCommandEvent& event); + void OnClose(wxCloseEvent& event); + + const bool isGlobalFilter_; + Zstring& includeFilter; + Zstring& excludeFilter; +}; + + FilterDlg::FilterDlg(wxWindow* window, bool isGlobalFilter, //global or local filter dialog? Zstring& filterIncl, @@ -227,7 +296,60 @@ void FilterDlg::OnClose(wxCloseEvent& event) } + +DefaultReturnCode::Response FreeFileSync::showFilterDialog(bool isGlobalFilter, + Zstring& filterIncl, + Zstring& filterExcl, + bool filterActive) +{ + DefaultReturnCode::Response rv = DefaultReturnCode::BUTTON_CANCEL; + FilterDlg* filterDlg = new FilterDlg(NULL, + isGlobalFilter, //is main filter dialog + filterIncl, + filterExcl, + filterActive); + if (filterDlg->ShowModal() == FilterDlg::BUTTON_APPLY) + rv = DefaultReturnCode::BUTTON_OKAY; + + filterDlg->Destroy(); + return rv; +} //######################################################################################## + + +class DeleteDialog : public DeleteDlgGenerated +{ +public: + DeleteDialog(wxWindow* main, + const std::vector<FreeFileSync::FileSystemObject*>& rowsOnLeft, + const std::vector<FreeFileSync::FileSystemObject*>& rowsOnRight, + bool& deleteOnBothSides, + bool& useRecycleBin, + int& totalDeleteCount); + + enum + { + BUTTON_OKAY = 1, + BUTTON_CANCEL + }; + +private: + void OnOK(wxCommandEvent& event); + void OnCancel(wxCommandEvent& event); + void OnClose(wxCloseEvent& event); + void OnDelOnBothSides(wxCommandEvent& event); + void OnUseRecycler(wxCommandEvent& event); + + void updateTexts(); + + const std::vector<FreeFileSync::FileSystemObject*>& rowsToDeleteOnLeft; + const std::vector<FreeFileSync::FileSystemObject*>& rowsToDeleteOnRight; + bool& m_deleteOnBothSides; + bool& m_useRecycleBin; + int& totalDelCount; +}; + + DeleteDialog::DeleteDialog(wxWindow* main, const std::vector<FileSystemObject*>& rowsOnLeft, const std::vector<FileSystemObject*>& rowsOnRight, @@ -299,202 +421,60 @@ void DeleteDialog::OnDelOnBothSides(wxCommandEvent& event) void DeleteDialog::OnUseRecycler(wxCommandEvent& event) { - if (m_checkBoxUseRecycler->GetValue()) - { - if (!FreeFileSync::recycleBinExists()) - { - wxMessageBox(_("Unable to initialize Recycle Bin!"), _("Error") , wxOK | wxICON_ERROR); - m_checkBoxUseRecycler->SetValue(false); - } - } - m_useRecycleBin = m_checkBoxUseRecycler->GetValue(); updateTexts(); } -//######################################################################################## - - -ErrorDlg::ErrorDlg(wxWindow* parentWindow, const int activeButtons, const wxString messageText, bool& ignoreNextErrors) : - ErrorDlgGenerated(parentWindow), - ignoreErrors(ignoreNextErrors) -{ - m_bitmap10->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("error"))); - m_textCtrl8->SetValue(messageText); - m_checkBoxIgnoreErrors->SetValue(ignoreNextErrors); - - if (~activeButtons & BUTTON_IGNORE) - { - m_buttonIgnore->Hide(); - m_checkBoxIgnoreErrors->Hide(); - } - - if (~activeButtons & BUTTON_RETRY) - m_buttonRetry->Hide(); - - if (~activeButtons & BUTTON_ABORT) - m_buttonAbort->Hide(); - - //set button focus precedence - if (activeButtons & BUTTON_RETRY) - m_buttonRetry->SetFocus(); - else if (activeButtons & BUTTON_IGNORE) - m_buttonIgnore->SetFocus(); - else if (activeButtons & BUTTON_ABORT) - m_buttonAbort->SetFocus(); -} - -ErrorDlg::~ErrorDlg() {} - - -void ErrorDlg::OnClose(wxCloseEvent& event) -{ - ignoreErrors = m_checkBoxIgnoreErrors->GetValue(); - EndModal(BUTTON_ABORT); -} - - -void ErrorDlg::OnIgnore(wxCommandEvent& event) -{ - ignoreErrors = m_checkBoxIgnoreErrors->GetValue(); - EndModal(BUTTON_IGNORE); -} - - -void ErrorDlg::OnRetry(wxCommandEvent& event) -{ - ignoreErrors = m_checkBoxIgnoreErrors->GetValue(); - EndModal(BUTTON_RETRY); -} - - -void ErrorDlg::OnAbort(wxCommandEvent& event) -{ - ignoreErrors = m_checkBoxIgnoreErrors->GetValue(); - EndModal(BUTTON_ABORT); -} -//######################################################################################## -WarningDlg::WarningDlg(wxWindow* parentWindow, int activeButtons, const wxString messageText, bool& dontShowDlgAgain) : - WarningDlgGenerated(parentWindow), - dontShowAgain(dontShowDlgAgain) +DefaultReturnCode::Response FreeFileSync::showDeleteDialog(const std::vector<FreeFileSync::FileSystemObject*>& rowsOnLeft, + const std::vector<FreeFileSync::FileSystemObject*>& rowsOnRight, + bool& deleteOnBothSides, + bool& useRecycleBin, + int& totalDeleteCount) { - m_bitmap10->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("warning"))); - m_textCtrl8->SetValue(messageText); - m_checkBoxDontShowAgain->SetValue(dontShowAgain); - - if (~activeButtons & BUTTON_IGNORE) - { - m_buttonIgnore->Hide(); - m_checkBoxDontShowAgain->Hide(); - } - - if (~activeButtons & BUTTON_ABORT) - m_buttonAbort->Hide(); - - //set button focus precedence - if (activeButtons & BUTTON_IGNORE) - m_buttonIgnore->SetFocus(); - else if (activeButtons & BUTTON_ABORT) - m_buttonAbort->SetFocus(); -} - -WarningDlg::~WarningDlg() {} - - -void WarningDlg::OnClose(wxCloseEvent& event) -{ - dontShowAgain = m_checkBoxDontShowAgain->GetValue(); - EndModal(BUTTON_ABORT); -} - - -void WarningDlg::OnIgnore(wxCommandEvent& event) -{ - dontShowAgain = m_checkBoxDontShowAgain->GetValue(); - EndModal(BUTTON_IGNORE); -} + DefaultReturnCode::Response rv = DefaultReturnCode::BUTTON_CANCEL; + DeleteDialog* confirmDeletion = new DeleteDialog(NULL, + rowsOnLeft, + rowsOnRight, + deleteOnBothSides, + useRecycleBin, + totalDeleteCount); + if (confirmDeletion->ShowModal() == DeleteDialog::BUTTON_OKAY) + rv = DefaultReturnCode::BUTTON_OKAY; -void WarningDlg::OnAbort(wxCommandEvent& event) -{ - dontShowAgain = m_checkBoxDontShowAgain->GetValue(); - EndModal(BUTTON_ABORT); + confirmDeletion->Destroy(); + return rv; } - //######################################################################################## -QuestionDlg::QuestionDlg(wxWindow* parentWindow, int activeButtons, const wxString messageText, bool* dontShowDlgAgain) : - QuestionDlgGenerated(parentWindow), - dontShowAgain(dontShowDlgAgain) +class CustomizeColsDlg : public CustomizeColsDlgGenerated { - m_bitmap10->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("question"))); - m_textCtrl8->SetValue(messageText); - if (dontShowAgain) - m_checkBoxDontAskAgain->SetValue(*dontShowAgain); - else - m_checkBoxDontAskAgain->Hide(); +public: + CustomizeColsDlg(wxWindow* window, xmlAccess::ColumnAttributes& attr); - if (~activeButtons & BUTTON_YES) - m_buttonYes->Hide(); - - if (~activeButtons & BUTTON_NO) + enum { - m_buttonNo->Hide(); - m_checkBoxDontAskAgain->Hide(); - } - - if (~activeButtons & BUTTON_CANCEL) - m_buttonCancel->Hide(); - - //set button focus precedence - if (activeButtons & BUTTON_YES) - m_buttonYes->SetFocus(); - else if (activeButtons & BUTTON_CANCEL) - m_buttonCancel->SetFocus(); - else if (activeButtons & BUTTON_NO) - m_buttonNo->SetFocus(); -} - - -void QuestionDlg::OnClose(wxCloseEvent& event) -{ - if (dontShowAgain) - *dontShowAgain = m_checkBoxDontAskAgain->GetValue(); - EndModal(BUTTON_CANCEL); -} - - -void QuestionDlg::OnCancel(wxCommandEvent& event) -{ - if (dontShowAgain) - *dontShowAgain = m_checkBoxDontAskAgain->GetValue(); - EndModal(BUTTON_CANCEL); -} + BUTTON_OKAY = 10 + }; +private: + void OnOkay(wxCommandEvent& event); + void OnDefault(wxCommandEvent& event); + void OnCancel(wxCommandEvent& event); + void OnClose(wxCloseEvent& event); -void QuestionDlg::OnYes(wxCommandEvent& event) -{ - if (dontShowAgain) - *dontShowAgain = m_checkBoxDontAskAgain->GetValue(); - EndModal(BUTTON_YES); -} - -void QuestionDlg::OnNo(wxCommandEvent& event) -{ - if (dontShowAgain) - *dontShowAgain = m_checkBoxDontAskAgain->GetValue(); - EndModal(BUTTON_NO); -} + void OnMoveUp(wxCommandEvent& event); + void OnMoveDown(wxCommandEvent& event); -//######################################################################################## + xmlAccess::ColumnAttributes& output; +}; -CustomizeColsDlg::CustomizeColsDlg(wxWindow* window, xmlAccess::ColumnAttributes& attr, bool& showFileIcons) : +CustomizeColsDlg::CustomizeColsDlg(wxWindow* window, xmlAccess::ColumnAttributes& attr) : CustomizeColsDlgGenerated(window), - output(attr), - m_showFileIcons(showFileIcons) + output(attr) { m_bpButton29->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("moveUp"))); m_bpButton30->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("moveDown"))); @@ -509,12 +489,6 @@ CustomizeColsDlg::CustomizeColsDlg(wxWindow* window, xmlAccess::ColumnAttributes m_checkListColumns->Check(i - columnSettings.begin(), i->visible); } -#ifdef FFS_LINUX //file icons currently supported on Windows only - m_checkBoxShowFileIcons->Hide(); -#endif - - m_checkBoxShowFileIcons->SetValue(m_showFileIcons); - m_checkListColumns->SetSelection(0); Fit(); } @@ -536,8 +510,6 @@ void CustomizeColsDlg::OnOkay(wxCommandEvent& event) } } - m_showFileIcons = m_checkBoxShowFileIcons->GetValue(); - EndModal(BUTTON_OKAY); } @@ -552,8 +524,6 @@ void CustomizeColsDlg::OnDefault(wxCommandEvent& event) m_checkListColumns->Append(CustomGridRim::getTypeName(i->type)); m_checkListColumns->Check(i - defaultColumnAttr.begin(), i->visible); } - - m_checkBoxShowFileIcons->SetValue(true); } @@ -602,9 +572,44 @@ void CustomizeColsDlg::OnMoveDown(wxCommandEvent& event) } } + +DefaultReturnCode::Response FreeFileSync::showCustomizeColsDlg(xmlAccess::ColumnAttributes& attr) +{ + DefaultReturnCode::Response rv = DefaultReturnCode::BUTTON_CANCEL; + + CustomizeColsDlg* customizeDlg = new CustomizeColsDlg(NULL, attr); + if (customizeDlg->ShowModal() == CustomizeColsDlg::BUTTON_OKAY) + rv = DefaultReturnCode::BUTTON_OKAY; + customizeDlg->Destroy(); + + return rv; +} //######################################################################################## +class SyncPreviewDlg : public SyncPreviewDlgGenerated +{ +public: + SyncPreviewDlg(wxWindow* parentWindow, + const wxString& variantName, + const FreeFileSync::SyncStatistics& statistics, + bool& dontShowAgain); + enum + { + BUTTON_START = 1, + BUTTON_CANCEL = 2 + }; + +private: + void OnClose(wxCloseEvent& event); + void OnCancel(wxCommandEvent& event); + void OnStartSync(wxCommandEvent& event); + + bool& m_dontShowAgain; +}; + + + SyncPreviewDlg::SyncPreviewDlg(wxWindow* parentWindow, const wxString& variantName, const FreeFileSync::SyncStatistics& statistics, @@ -658,8 +663,49 @@ void SyncPreviewDlg::OnStartSync(wxCommandEvent& event) } +DefaultReturnCode::Response FreeFileSync::showSyncPreviewDlg( + const wxString& variantName, + const FreeFileSync::SyncStatistics& statistics, + bool& dontShowAgain) +{ + DefaultReturnCode::Response rv = DefaultReturnCode::BUTTON_CANCEL; + + SyncPreviewDlg* preview = new SyncPreviewDlg(NULL, + variantName, + statistics, + dontShowAgain); + + if (preview->ShowModal() == SyncPreviewDlg::BUTTON_START) + rv = DefaultReturnCode::BUTTON_OKAY; + + preview->Destroy(); + + return rv; +} //######################################################################################## + +class CompareCfgDialog : public CmpCfgDlgGenerated +{ +public: + CompareCfgDialog(wxWindow* parentWindow, const wxPoint& position, FreeFileSync::CompareVariant& cmpVar); + + enum + { + BUTTON_OKAY = 10 + }; + +private: + void OnClose(wxCloseEvent& event); + void OnCancel(wxCommandEvent& event); + void OnTimeSize(wxCommandEvent& event); + void OnContent(wxCommandEvent& event); + void OnShowHelp(wxCommandEvent& event); + + FreeFileSync::CompareVariant& m_cmpVar; +}; + + CompareCfgDialog::CompareCfgDialog(wxWindow* parentWindow, const wxPoint& position, CompareVariant& cmpVar) : CmpCfgDlgGenerated(parentWindow), m_cmpVar(cmpVar) @@ -719,7 +765,47 @@ void CompareCfgDialog::OnShowHelp(wxCommandEvent& event) } +DefaultReturnCode::Response FreeFileSync::showCompareCfgDialog(const wxPoint& position, CompareVariant& cmpVar) +{ + DefaultReturnCode::Response rv = DefaultReturnCode::BUTTON_CANCEL; + + CompareCfgDialog* syncDlg = new CompareCfgDialog(NULL, position, cmpVar); + if (syncDlg->ShowModal() == CompareCfgDialog::BUTTON_OKAY) + rv = DefaultReturnCode::BUTTON_OKAY; + + syncDlg->Destroy(); + + return rv; +} //######################################################################################## + + +class GlobalSettingsDlg : public GlobalSettingsDlgGenerated +{ +public: + GlobalSettingsDlg(wxWindow* window, xmlAccess::XmlGlobalSettings& globalSettings); + + enum + { + BUTTON_OKAY = 10 + }; + +private: + void OnOkay(wxCommandEvent& event); + void OnResetDialogs(wxCommandEvent& event); + void OnDefault(wxCommandEvent& event); + void OnCancel(wxCommandEvent& event); + void OnClose(wxCloseEvent& event); + void OnAddRow(wxCommandEvent& event); + void OnRemoveRow(wxCommandEvent& event); + + void set(const xmlAccess::ExternalApps& extApp); + xmlAccess::ExternalApps getExtApp(); + + xmlAccess::XmlGlobalSettings& settings; +}; + + GlobalSettingsDlg::GlobalSettingsDlg(wxWindow* window, xmlAccess::XmlGlobalSettings& globalSettings) : GlobalSettingsDlgGenerated(window), settings(globalSettings) @@ -857,541 +943,16 @@ void GlobalSettingsDlg::OnRemoveRow(wxCommandEvent& event) } } -//######################################################################################## - -CompareStatus::CompareStatus(wxWindow* parentWindow) : - CompareStatusGenerated(parentWindow), - scannedObjects(0), - totalObjects(0), - totalData(0), - currentObjects(0), - currentData(0), - scalingFactor(0), - statistics(NULL), - lastStatCallSpeed(-1000000), //some big number - lastStatCallRemTime(-1000000) -{ - init(); -} - - -void CompareStatus::init() -{ - //initialize gauge - m_gauge2->SetRange(50000); - m_gauge2->SetValue(0); - - //initially hide status that's relevant for comparing bytewise only - bSizer42->Hide(sbSizer13); - m_gauge2->Hide(); - bSizer42->Layout(); - - scannedObjects = 0; - currentStatusText.clear(); - - totalObjects = 0; - totalData = 0; - currentObjects = 0; - currentData = 0; - scalingFactor = 0; - - statistics.reset(); - - timeElapsed.Start(); //measure total time - - updateStatusPanelNow(); -} - - -void CompareStatus::switchToCompareBytewise(int totalObjectsToProcess, wxLongLong totalDataToProcess) -{ - currentData = 0; - totalData = totalDataToProcess; - - currentObjects = 0; - totalObjects = totalObjectsToProcess; - - if (totalData != 0) - scalingFactor = 50000 / totalData.ToDouble(); //let's normalize to 50000 - else - scalingFactor = 0; - - //set new statistics handler: 10 seconds "window" for remaining time, 5 seconds for speed - statistics.reset(new Statistics(totalObjectsToProcess, totalDataToProcess.ToDouble(), 10000, 5000)); - lastStatCallSpeed = -1000000; //some big number - lastStatCallRemTime = -1000000; - - //show status for comparing bytewise - bSizer42->Show(sbSizer13); - m_gauge2->Show(); - bSizer42->Layout(); -} - - -void CompareStatus::incScannedObjects_NoUpdate(int number) -{ - scannedObjects += number; -} - - -void CompareStatus::incProcessedCmpData_NoUpdate(int objectsProcessed, wxLongLong dataProcessed) -{ - currentData += dataProcessed; - currentObjects += objectsProcessed; -} - - -void CompareStatus::setStatusText_NoUpdate(const Zstring& text) -{ - currentStatusText = text; -} - - -void CompareStatus::updateStatusPanelNow() -{ - //static RetrieveStatistics statistic; - //statistic.writeEntry(currentData, currentObjects); - { - wxWindowUpdateLocker dummy(this); //reduce display distortion - - bool screenChanged = false; //avoid screen flicker by calling layout() only if necessary - - //remove linebreaks from currentStatusText - wxString formattedStatusText = zToWx(currentStatusText); - for (wxString::iterator i = formattedStatusText.begin(); i != formattedStatusText.end(); ++i) - if (*i == wxChar('\n')) - *i = wxChar(' '); - - //status texts - if (m_textCtrlStatus->GetValue() != formattedStatusText && (screenChanged = true)) //avoid screen flicker - m_textCtrlStatus->SetValue(formattedStatusText); - - //nr of scanned objects - const wxString scannedObjTmp = globalFunctions::numberToWxString(scannedObjects); - if (m_staticTextScanned->GetLabel() != scannedObjTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextScanned->SetLabel(scannedObjTmp); - - //progress indicator for "compare file content" - m_gauge2->SetValue(int(currentData.ToDouble() * scalingFactor)); - - //remaining files left for file comparison - const wxString filesToCompareTmp = globalFunctions::numberToWxString(totalObjects - currentObjects); - if (m_staticTextFilesRemaining->GetLabel() != filesToCompareTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextFilesRemaining->SetLabel(filesToCompareTmp); - - //remaining bytes left for file comparison - const wxString remainingBytesTmp = FreeFileSync::formatFilesizeToShortString(totalData - currentData); - if (m_staticTextDataRemaining->GetLabel() != remainingBytesTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextDataRemaining->SetLabel(remainingBytesTmp); - - if (statistics.get()) - { - if (timeElapsed.Time() - lastStatCallSpeed >= 500) //call method every 500 ms - { - lastStatCallSpeed = timeElapsed.Time(); - - statistics->addMeasurement(currentObjects, currentData.ToDouble()); - - //current speed - const wxString speedTmp = statistics->getBytesPerSecond(); - if (m_staticTextSpeed->GetLabel() != speedTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextSpeed->SetLabel(speedTmp); - - if (timeElapsed.Time() - lastStatCallRemTime >= 2000) //call method every two seconds only - { - lastStatCallRemTime = timeElapsed.Time(); - - //remaining time - const wxString timeRemainingTmp = statistics->getRemainingTime(); - if (m_staticTextTimeRemaining->GetLabel() != timeRemainingTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextTimeRemaining->SetLabel(timeRemainingTmp); - } - } - } - - //time elapsed - const wxString timeElapsedTmp = (wxTimeSpan::Milliseconds(timeElapsed.Time())).Format(); - if (m_staticTextTimeElapsed->GetLabel() != timeElapsedTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextTimeElapsed->SetLabel(timeElapsedTmp); - - //do the ui update - if (screenChanged) - bSizer42->Layout(); - } - updateUiNow(); -} - - -//######################################################################################## - -SyncStatus::SyncStatus(StatusHandler* updater, wxWindow* parentWindow) : - SyncStatusDlgGenerated(parentWindow, - wxID_ANY, - parentWindow ? wxEmptyString : _("FreeFileSync - Folder Comparison and Synchronization"), - wxDefaultPosition, wxSize(638, 376), - parentWindow ? - wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT : - wxDEFAULT_FRAME_STYLE | wxTAB_TRAVERSAL), - processStatusHandler(updater), - mainDialog(parentWindow), - totalObjects(0), - totalData(0), - currentObjects(0), - currentData(0), - scalingFactor(0), - processPaused(false), - currentStatus(SyncStatus::ABORTED), - statistics(NULL), - lastStatCallSpeed(-1000000), //some big number - lastStatCallRemTime(-1000000) -{ - m_animationControl1->SetAnimation(*GlobalResources::getInstance().animationSync); - m_animationControl1->Play(); - - //initialize gauge - m_gauge1->SetRange(50000); - m_gauge1->SetValue(0); - - m_buttonAbort->SetFocus(); - - if (mainDialog) //disable (main) window while this status dialog is shown - mainDialog->Disable(); - - timeElapsed.Start(); //measure total time - - - SetIcon(*GlobalResources::getInstance().programIcon); //set application icon - - //register key event - Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(SyncStatus::OnKeyPressed), NULL, this); - -} - - -SyncStatus::~SyncStatus() -{ - if (mainDialog) - { - mainDialog->Enable(); - mainDialog->Raise(); - mainDialog->SetFocus(); - } - - if (minimizedToSysTray.get()) - minimizedToSysTray->keepHidden(); //avoid window flashing shortly before it is destroyed -} - - -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; - totalData = totalDataToProcess; - - currentObjects = 0; - totalObjects = totalObjectsToProcess; - - if (totalData != 0) - scalingFactor = 50000 / totalData.ToDouble(); //let's normalize to 50000 - else - scalingFactor = 0; - - //set new statistics handler: 10 seconds "window" for remaining time, 5 seconds for speed - statistics.reset(new Statistics(totalObjectsToProcess, totalDataToProcess.ToDouble(), 10000, 5000)); - lastStatCallSpeed = -1000000; //some big number - lastStatCallRemTime = -1000000; -} - - -void SyncStatus::incProgressIndicator_NoUpdate(int objectsProcessed, wxLongLong dataProcessed) -{ - currentData += dataProcessed; - currentObjects += objectsProcessed; -} - - -void SyncStatus::setStatusText_NoUpdate(const Zstring& text) -{ - currentStatusText = text; -} - - -void SyncStatus::updateStatusDialogNow() -{ - //static RetrieveStatistics statistic; - //statistic.writeEntry(currentData, currentObjects); - - //write status information systray, too, if window is minimized - if (minimizedToSysTray.get()) - switch (currentStatus) - { - case SCANNING: - minimizedToSysTray->setToolTip(wxString(wxT("FreeFileSync - ")) + wxString(_("Scanning..."))); - //+ wxT(" ") + globalFunctions::numberToWxString(currentObjects)); - break; - case COMPARING_CONTENT: - minimizedToSysTray->setToolTip(wxString(wxT("FreeFileSync - ")) + wxString(_("Comparing content...")) + wxT(" ") + - fromatPercentage(currentData, totalData), currentData.ToDouble() * 100 / totalData.ToDouble()); - break; - case SYNCHRONIZING: - minimizedToSysTray->setToolTip(wxString(wxT("FreeFileSync - ")) + wxString(_("Synchronizing...")) + wxT(" ") + - fromatPercentage(currentData, totalData), currentData.ToDouble() * 100 / totalData.ToDouble()); - break; - case ABORTED: - case FINISHED_WITH_SUCCESS: - case FINISHED_WITH_ERROR: - case PAUSE: - minimizedToSysTray->setToolTip(wxT("FreeFileSync")); - } - - //write regular status information (if dialog is visible or not) - { - wxWindowUpdateLocker dummy(this); //reduce display distortion - - bool screenChanged = false; //avoid screen flicker by calling layout() only if necessary - - //progress indicator - if (currentStatus == SCANNING) - m_gauge1->Pulse(); - else - m_gauge1->SetValue(globalFunctions::round(currentData.ToDouble() * scalingFactor)); - - //status text - const wxString statusTxt = zToWx(currentStatusText); - if (m_textCtrlInfo->GetValue() != statusTxt && (screenChanged = true)) //avoid screen flicker - m_textCtrlInfo->SetValue(statusTxt); - - //remaining objects - const wxString remainingObjTmp = globalFunctions::numberToWxString(totalObjects - currentObjects); - if (m_staticTextRemainingObj->GetLabel() != remainingObjTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextRemainingObj->SetLabel(remainingObjTmp); - - //remaining bytes left for copy - const wxString remainingBytesTmp = FreeFileSync::formatFilesizeToShortString(totalData - currentData); - if (m_staticTextDataRemaining->GetLabel() != remainingBytesTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextDataRemaining->SetLabel(remainingBytesTmp); - - if (statistics.get()) - { - if (timeElapsed.Time() - lastStatCallSpeed >= 500) //call method every 500 ms - { - lastStatCallSpeed = timeElapsed.Time(); - - statistics->addMeasurement(currentObjects, currentData.ToDouble()); - - //current speed - const wxString speedTmp = statistics->getBytesPerSecond(); - if (m_staticTextSpeed->GetLabel() != speedTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextSpeed->SetLabel(speedTmp); - - if (timeElapsed.Time() - lastStatCallRemTime >= 2000) //call method every two seconds only - { - lastStatCallRemTime = timeElapsed.Time(); - - //remaining time - const wxString timeRemainingTmp = statistics->getRemainingTime(); - if (m_staticTextTimeRemaining->GetLabel() != timeRemainingTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextTimeRemaining->SetLabel(timeRemainingTmp); - } - } - } - - //time elapsed - const wxString timeElapsedTmp = wxTimeSpan::Milliseconds(timeElapsed.Time()).Format(); - if (m_staticTextTimeElapsed->GetLabel() != timeElapsedTmp && (screenChanged = true)) //avoid screen flicker - m_staticTextTimeElapsed->SetLabel(timeElapsedTmp); - - - //do the ui update - if (screenChanged) - { - bSizer28->Layout(); - bSizer31->Layout(); - } - } - updateUiNow(); - -//support for pause button - while (processPaused && currentProcessIsRunning()) - { - wxMilliSleep(UI_UPDATE_INTERVAL); - updateUiNow(); - } -} - -bool SyncStatus::currentProcessIsRunning() +DefaultReturnCode::Response FreeFileSync::showGlobalSettingsDlg(xmlAccess::XmlGlobalSettings& globalSettings) { - return processStatusHandler != NULL; -} + DefaultReturnCode::Response rv = DefaultReturnCode::BUTTON_CANCEL; + wxDialog* settingsDlg = new GlobalSettingsDlg(NULL, globalSettings); + if (settingsDlg->ShowModal() == GlobalSettingsDlg::BUTTON_OKAY) + rv = DefaultReturnCode::BUTTON_OKAY; -void SyncStatus::setCurrentStatus(SyncStatusID id) -{ - switch (id) - { - case ABORTED: - m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusError"))); - m_staticTextStatus->SetLabel(_("Aborted")); - break; - - case FINISHED_WITH_SUCCESS: - m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusSuccess"))); - m_staticTextStatus->SetLabel(_("Completed")); - break; - - case FINISHED_WITH_ERROR: - m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusWarning"))); - m_staticTextStatus->SetLabel(_("Completed")); - break; - - case PAUSE: - m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusPause"))); - m_staticTextStatus->SetLabel(_("Paused")); - break; - - case SCANNING: - m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusScanning"))); - m_staticTextStatus->SetLabel(_("Scanning...")); - break; + settingsDlg->Destroy(); - case COMPARING_CONTENT: - m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusBinaryCompare"))); - m_staticTextStatus->SetLabel(_("Comparing content...")); - break; - - case SYNCHRONIZING: - m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusSyncing"))); - m_staticTextStatus->SetLabel(_("Synchronizing...")); - break; - } - - currentStatus = id; - Layout(); + return rv; } - - -void SyncStatus::processHasFinished(SyncStatusID id, const wxString& finalMessage) //essential to call this in StatusHandler derived class destructor -{ - //at the LATEST(!) to prevent access to currentStatusHandler - //enable okay and close events; may be set in this method ONLY - - processStatusHandler = NULL; //avoid callback to (maybe) deleted parent process - - setCurrentStatus(id); - - resumeFromSystray(); //if in tray mode... - - m_buttonAbort->Disable(); - m_buttonAbort->Hide(); - m_buttonPause->Disable(); - m_buttonPause->Hide(); - m_buttonOK->Show(); - m_buttonOK->SetFocus(); - - m_animationControl1->Stop(); - m_animationControl1->Hide(); - - bSizerSpeed->Show(false); - bSizerRemTime->Show(false); - - updateStatusDialogNow(); //keep this sequence to avoid display distortion, if e.g. only 1 item is sync'ed - m_textCtrlInfo->SetValue(finalMessage); - Layout(); // -} - - -void SyncStatus::OnOkay(wxCommandEvent& event) -{ - if (!currentProcessIsRunning()) Destroy(); -} - - -void SyncStatus::OnPause(wxCommandEvent& event) -{ - static SyncStatusID previousStatus = SyncStatus::ABORTED; - - if (processPaused) - { - setCurrentStatus(previousStatus); - processPaused = false; - m_buttonPause->SetLabel(_("Pause")); - m_animationControl1->Play(); - - //resume timers - timeElapsed.Resume(); - if (statistics.get()) - statistics->resumeTimer(); - } - else - { - previousStatus = currentStatus; //save current status - - setCurrentStatus(SyncStatus::PAUSE); - processPaused = true; - m_buttonPause->SetLabel(_("Continue")); - m_animationControl1->Stop(); - - //pause timers - timeElapsed.Pause(); - if (statistics.get()) - statistics->pauseTimer(); - } -} - - -void SyncStatus::OnAbort(wxCommandEvent& event) -{ - processPaused = false; - if (currentProcessIsRunning()) - { - m_buttonAbort->Disable(); - m_buttonAbort->Hide(); - m_buttonPause->Disable(); - m_buttonPause->Hide(); - - setStatusText_NoUpdate(wxToZ(_("Abort requested: Waiting for current operation to finish..."))); - //no Layout() or UI-update here to avoid cascaded Yield()-call - - processStatusHandler->requestAbortion(); - } -} - - -void SyncStatus::OnClose(wxCloseEvent& event) -{ - processPaused = false; - if (processStatusHandler) - processStatusHandler->requestAbortion(); - else - Destroy(); -} - - -void SyncStatus::OnIconize(wxIconizeEvent& event) -{ - if (event.Iconized()) //ATTENTION: iconize event is also triggered on "Restore"! (at least under Linux) - minimizeToTray(); -} - - -void SyncStatus::minimizeToTray() -{ - minimizedToSysTray.reset(new MinimizeToTray(this, mainDialog)); -} - - -void SyncStatus::resumeFromSystray() -{ - minimizedToSysTray.reset(); -} - diff --git a/ui/SmallDialogs.h b/ui/SmallDialogs.h index 22a271c9..73e4d13a 100644 --- a/ui/SmallDialogs.h +++ b/ui/SmallDialogs.h @@ -1,365 +1,57 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// #ifndef SMALLDIALOGS_H_INCLUDED #define SMALLDIALOGS_H_INCLUDED #include "../fileHierarchy.h" #include "../library/processXml.h" -#include "guiGenerated.h" -#include <wx/stopwatch.h> -#include <memory> - -class Statistics; -class StatusHandler; -class MinimizeToTray; namespace FreeFileSync { class SyncStatistics; -} - - -class AboutDlg : public AboutDlgGenerated -{ -public: - AboutDlg(wxWindow* window); - ~AboutDlg() {} - -private: - void OnClose(wxCloseEvent& event); - void OnOK(wxCommandEvent& event); -}; -class HelpDlg : public HelpDlgGenerated +struct DefaultReturnCode { -public: - HelpDlg(wxWindow* window); - -private: - void OnClose(wxCloseEvent& event); - void OnOK(wxCommandEvent& event); -}; - - -class FilterDlg : public FilterDlgGenerated -{ -public: - FilterDlg(wxWindow* window, - bool isGlobalFilter, - Zstring& filterIncl, - Zstring& filterExcl, - bool filterActive); - ~FilterDlg() {} - - enum - { - BUTTON_APPLY = 1 - }; - -private: - void OnHelp(wxCommandEvent& event); - void OnDefault(wxCommandEvent& event); - void OnApply(wxCommandEvent& event); - void OnCancel(wxCommandEvent& event); - void OnClose(wxCloseEvent& event); - - const bool isGlobalFilter_; - Zstring& includeFilter; - Zstring& excludeFilter; -}; - - -class DeleteDialog : public DeleteDlgGenerated -{ -public: - DeleteDialog(wxWindow* main, - const std::vector<FreeFileSync::FileSystemObject*>& rowsOnLeft, - const std::vector<FreeFileSync::FileSystemObject*>& rowsOnRight, - bool& deleteOnBothSides, - bool& useRecycleBin, - int& totalDeleteCount); - - ~DeleteDialog() {} - - enum - { - BUTTON_OKAY = 1, - BUTTON_CANCEL - }; - -private: - void OnOK(wxCommandEvent& event); - void OnCancel(wxCommandEvent& event); - void OnClose(wxCloseEvent& event); - void OnDelOnBothSides(wxCommandEvent& event); - void OnUseRecycler(wxCommandEvent& event); - - void updateTexts(); - - const std::vector<FreeFileSync::FileSystemObject*>& rowsToDeleteOnLeft; - const std::vector<FreeFileSync::FileSystemObject*>& rowsToDeleteOnRight; - bool& m_deleteOnBothSides; - bool& m_useRecycleBin; - int& totalDelCount; -}; - - -class ErrorDlg : public ErrorDlgGenerated -{ -public: - ErrorDlg(wxWindow* parentWindow, const int activeButtons, const wxString messageText, bool& ignoreNextErrors); - ~ErrorDlg(); - - enum ReturnCodes - { - BUTTON_IGNORE = 1, - BUTTON_RETRY = 2, - BUTTON_ABORT = 4 - }; - -private: - void OnClose(wxCloseEvent& event); - void OnIgnore(wxCommandEvent& event); - void OnRetry(wxCommandEvent& event); - void OnAbort(wxCommandEvent& event); - - bool& ignoreErrors; -}; - - -class WarningDlg : public WarningDlgGenerated -{ -public: - WarningDlg(wxWindow* parentWindow, int activeButtons, const wxString messageText, bool& dontShowAgain); - ~WarningDlg(); - enum Response { - BUTTON_IGNORE = 1, - BUTTON_ABORT = 2 - }; - -private: - void OnClose(wxCloseEvent& event); - void OnIgnore(wxCommandEvent& event); - void OnResolve(wxCommandEvent& event); - void OnAbort(wxCommandEvent& event); - void OnOkay(wxCommandEvent& event); - - bool& dontShowAgain; -}; - - -class QuestionDlg : public QuestionDlgGenerated -{ -public: - QuestionDlg(wxWindow* parentWindow, int activeButtons, const wxString messageText, bool* dontShowAgain = NULL); - - enum - { - BUTTON_YES = 1, - BUTTON_NO = 2, - BUTTON_CANCEL = 4 - }; - -private: - void OnClose(wxCloseEvent& event); - void OnCancel(wxCommandEvent& event); - void OnYes(wxCommandEvent& event); - void OnNo(wxCommandEvent& event); - - bool* dontShowAgain; //optional -}; - - -class CustomizeColsDlg : public CustomizeColsDlgGenerated -{ -public: - CustomizeColsDlg(wxWindow* window, xmlAccess::ColumnAttributes& attr, bool& showFileIcons); - - enum - { - BUTTON_OKAY = 10 - }; - -private: - void OnOkay(wxCommandEvent& event); - void OnDefault(wxCommandEvent& event); - void OnCancel(wxCommandEvent& event); - void OnClose(wxCloseEvent& event); - - void OnMoveUp(wxCommandEvent& event); - void OnMoveDown(wxCommandEvent& event); - - xmlAccess::ColumnAttributes& output; - bool& m_showFileIcons; -}; - - -class SyncPreviewDlg : public SyncPreviewDlgGenerated -{ -public: - SyncPreviewDlg(wxWindow* parentWindow, - const wxString& variantName, - const FreeFileSync::SyncStatistics& statistics, - bool& dontShowAgain); - - enum - { - BUTTON_START = 1, - BUTTON_CANCEL = 2 - }; - -private: - void OnClose(wxCloseEvent& event); - void OnCancel(wxCommandEvent& event); - void OnStartSync(wxCommandEvent& event); - - bool& m_dontShowAgain; -}; - - -class CompareCfgDialog : public CmpCfgDlgGenerated -{ -public: - CompareCfgDialog(wxWindow* parentWindow, const wxPoint& position, FreeFileSync::CompareVariant& cmpVar); - - enum - { - BUTTON_OKAY = 10 - }; - -private: - void OnClose(wxCloseEvent& event); - void OnCancel(wxCommandEvent& event); - void OnTimeSize(wxCommandEvent& event); - void OnContent(wxCommandEvent& event); - void OnShowHelp(wxCommandEvent& event); - - FreeFileSync::CompareVariant& m_cmpVar; -}; - - -class GlobalSettingsDlg : public GlobalSettingsDlgGenerated -{ -public: - GlobalSettingsDlg(wxWindow* window, xmlAccess::XmlGlobalSettings& globalSettings); - ~GlobalSettingsDlg() {} - - enum - { - BUTTON_OKAY = 10 + BUTTON_OKAY, + BUTTON_CANCEL }; - -private: - void OnOkay(wxCommandEvent& event); - void OnResetDialogs(wxCommandEvent& event); - void OnDefault(wxCommandEvent& event); - void OnCancel(wxCommandEvent& event); - void OnClose(wxCloseEvent& event); - void OnAddRow(wxCommandEvent& event); - void OnRemoveRow(wxCommandEvent& event); - - void set(const xmlAccess::ExternalApps& extApp); - xmlAccess::ExternalApps getExtApp(); - - xmlAccess::XmlGlobalSettings& settings; -}; - - -class CompareStatus : public CompareStatusGenerated -{ -public: - CompareStatus(wxWindow* parentWindow); - - void init(); //initialize all status values - - void switchToCompareBytewise(int totalObjectsToProcess, wxLongLong totalDataToProcess); - void incScannedObjects_NoUpdate(int number); - void incProcessedCmpData_NoUpdate(int objectsProcessed, wxLongLong dataProcessed); - void setStatusText_NoUpdate(const Zstring& text); - void updateStatusPanelNow(); - -private: - //status variables - unsigned int scannedObjects; - Zstring currentStatusText; - - wxStopWatch timeElapsed; - - //gauge variables - int totalObjects; - wxLongLong totalData; //each data element represents one byte for proper progress indicator scaling - int currentObjects; //each object represents a file or directory processed - wxLongLong currentData; - double scalingFactor; //nr of elements has to be normalized to smaller nr. because of range of int limitation - - //remaining time - std::auto_ptr<Statistics> statistics; - long lastStatCallSpeed; //used for calculating intervals between statistics update - long lastStatCallRemTime; // }; +void showAboutDialog(); -class SyncStatus : public SyncStatusDlgGenerated -{ -public: - SyncStatus(StatusHandler* updater, wxWindow* parentWindow); - ~SyncStatus(); - - enum SyncStatusID - { - ABORTED, - FINISHED_WITH_SUCCESS, - FINISHED_WITH_ERROR, - PAUSE, - SCANNING, - COMPARING_CONTENT, - SYNCHRONIZING - }; - - void resetGauge(int totalObjectsToProcess, wxLongLong totalDataToProcess); - void incProgressIndicator_NoUpdate(int objectsProcessed, wxLongLong dataProcessed); - void setStatusText_NoUpdate(const Zstring& text); - void updateStatusDialogNow(); - - void setCurrentStatus(SyncStatusID id); - void processHasFinished(SyncStatusID id, const wxString& finalMessage); //essential to call this in StatusUpdater derived class destructor at the LATEST(!) to prevent access to currentStatusUpdater +void showHelpDialog(); - void minimizeToTray(); +DefaultReturnCode::Response showFilterDialog(bool isGlobalFilter, + Zstring& filterIncl, + Zstring& filterExcl, + bool filterActive); -private: - void OnKeyPressed(wxKeyEvent& event); - virtual void OnOkay(wxCommandEvent& event); - virtual void OnPause(wxCommandEvent& event); - virtual void OnAbort(wxCommandEvent& event); - virtual void OnClose(wxCloseEvent& event); - virtual void OnIconize(wxIconizeEvent& event); +DefaultReturnCode::Response showDeleteDialog( + const std::vector<FileSystemObject*>& rowsOnLeft, + const std::vector<FileSystemObject*>& rowsOnRight, + bool& deleteOnBothSides, + bool& useRecycleBin, + int& totalDeleteCount); - void resumeFromSystray(); - bool currentProcessIsRunning(); +DefaultReturnCode::Response showCustomizeColsDlg(xmlAccess::ColumnAttributes& attr); - wxStopWatch timeElapsed; +DefaultReturnCode::Response showSyncPreviewDlg( + const wxString& variantName, + const SyncStatistics& statistics, + bool& dontShowAgain); - StatusHandler* processStatusHandler; - wxWindow* mainDialog; +DefaultReturnCode::Response showCompareCfgDialog(const wxPoint& position, CompareVariant& cmpVar); - //gauge variables - int totalObjects; - wxLongLong totalData; - int currentObjects; //each object represents a file or directory processed - wxLongLong currentData; //each data element represents one byte for proper progress indicator scaling - double scalingFactor; //nr of elements has to be normalized to smaller nr. because of range of int limitation - - Zstring currentStatusText; - bool processPaused; - SyncStatusID currentStatus; +DefaultReturnCode::Response showGlobalSettingsDlg(xmlAccess::XmlGlobalSettings& globalSettings); +} - //remaining time - std::auto_ptr<Statistics> statistics; - long lastStatCallSpeed; //used for calculating intervals between statistics update - long lastStatCallRemTime; // +#endif // SMALLDIALOGS_H_INCLUDED - boost::shared_ptr<MinimizeToTray> minimizedToSysTray; //optional: if filled, hides all visible windows, shows again if destroyed -}; -#endif // SMALLDIALOGS_H_INCLUDED diff --git a/ui/appMain.h b/ui/appMain.h deleted file mode 100644 index 2922d093..00000000 --- a/ui/appMain.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef APPMAIN_H_INCLUDED -#define APPMAIN_H_INCLUDED - -#include <wx/app.h> - -namespace FreeFileSync -{ -class AppMainWindow -{ -public: - static void setMainWindow(wxWindow* window); - static bool mainWindowActive(); - -private: - static bool mainWndAct; -}; -} - - -#endif // APPMAIN_H_INCLUDED diff --git a/ui/batchStatusHandler.cpp b/ui/batchStatusHandler.cpp index 793f18fd..f6e59924 100644 --- a/ui/batchStatusHandler.cpp +++ b/ui/batchStatusHandler.cpp @@ -1,5 +1,12 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// #include "batchStatusHandler.h" -#include "smallDialogs.h" +//#include "smallDialogs.h" +#include "messagePopup.h" #include <wx/ffile.h> #include <wx/msgdlg.h> #include "../shared/standardPaths.h" @@ -14,9 +21,9 @@ using namespace FreeFileSync; class LogFile { public: - LogFile(const wxString& logfileDirectory) //throw (FileError&) + LogFile(const wxString& logfileDirectory, const wxString& batchFilename) //throw (FileError&) { - const wxString logfileName = findUniqueLogname(logfileDirectory); + const wxString logfileName = findUniqueLogname(logfileDirectory, batchFilename); logFile.Open(logfileName, wxT("w")); if (!logFile.IsOpened()) @@ -42,8 +49,8 @@ public: void writeLog(const ErrorLogging& log) { //write actual logfile - const std::vector<wxString>& messages = log.getFormattedMessages(); - for (std::vector<wxString>::const_iterator i = messages.begin(); i != messages.end(); ++i) + const ErrorLogging::MessageEntry& messages = log.getFormattedMessages(); + for (ErrorLogging::MessageEntry::const_iterator i = messages.begin(); i != messages.end(); ++i) logFile.Write(*i + wxChar('\n')); } @@ -58,13 +65,23 @@ public: } private: - static wxString findUniqueLogname(const wxString& logfileDirectory) + static wxString extractJobName(const wxString& batchFilename) + { + using namespace globalFunctions; + + const wxString shortName = batchFilename.AfterLast(FILE_NAME_SEPARATOR); //returns the whole string if seperator not found + const wxString jobName = shortName.BeforeLast(wxChar('.')); //returns empty string if seperator not found + return jobName.IsEmpty() ? shortName : jobName; + } + + + static wxString findUniqueLogname(const wxString& logfileDirectory, const wxString& batchFilename) { using namespace globalFunctions; //create logfile directory Zstring logfileDir = logfileDirectory.empty() ? - wxToZ(FreeFileSync::getDefaultLogDirectory()) : + wxToZ(FreeFileSync::getConfigDir() + wxT("Logs")) : FreeFileSync::getFormattedDirectoryName(wxToZ(logfileDirectory)); if (!FreeFileSync::dirExists(logfileDir)) @@ -76,6 +93,10 @@ private: wxString logfileName = zToWx(logfileDir); + //add prefix + logfileName += extractJobName(batchFilename) + wxT(" "); + + //add timestamp wxString timeNow = wxDateTime::Now().FormatISOTime(); timeNow.Replace(wxT(":"), wxT("-")); logfileName += wxDateTime::Now().FormatISODate() + wxChar(' ') + timeNow; @@ -103,19 +124,21 @@ private: //############################################################################################################################## BatchStatusHandler::BatchStatusHandler(bool runSilent, + const wxString& batchFilename, const wxString* logfileDirectory, const xmlAccess::OnError handleError, int& returnVal) : exitWhenFinished(runSilent), //=> exit immediately when finished handleError_(handleError), currentProcess(StatusHandler::PROCESS_NONE), - returnValue(returnVal) + returnValue(returnVal), + syncStatusFrame(*this, NULL, runSilent) { if (logfileDirectory) { try { - logFile.reset(new LogFile(*logfileDirectory)); + logFile.reset(new LogFile(*logfileDirectory, batchFilename)); } catch (FreeFileSync::FileError& error) { @@ -126,12 +149,6 @@ BatchStatusHandler::BatchStatusHandler(bool runSilent, } assert(runSilent || handleError != xmlAccess::ON_ERROR_EXIT); //shouldn't be selectable from GUI settings - - syncStatusFrame = new SyncStatus(this, NULL); - if (runSilent) - syncStatusFrame->minimizeToTray(); - else - syncStatusFrame->Show(); } @@ -159,7 +176,7 @@ BatchStatusHandler::~BatchStatusHandler() logFile->writeLog(errorLog); //decide whether to stay on status screen or exit immediately... - if (!exitWhenFinished || syncStatusFrame->IsShown()) //warning: wxWindow::Show() is called within processHasFinished()! + if (!exitWhenFinished || syncStatusFrame.getAsWindow()->IsShown()) //warning: wxWindow::Show() is called within processHasFinished()! { //print the results list: GUI wxString finalMessage; @@ -170,36 +187,36 @@ BatchStatusHandler::~BatchStatusHandler() finalMessage += header + wxT("\n\n"); } - const std::vector<wxString>& messages = errorLog.getFormattedMessages(); - for (std::vector<wxString>::const_iterator i = messages.begin(); i != messages.end(); ++i) + const ErrorLogging::MessageEntry& messages = errorLog.getFormattedMessages(); + for (ErrorLogging::MessageEntry::const_iterator i = messages.begin(); i != messages.end(); ++i) { finalMessage += *i; - finalMessage += wxChar('\n'); + finalMessage += wxT("\n\n"); } //notify about (logical) application main window => program won't quit, but stay on this dialog - FreeFileSync::AppMainWindow::setMainWindow(syncStatusFrame); + FreeFileSync::AppMainWindow::setMainWindow(syncStatusFrame.getAsWindow()); //notify to syncStatusFrame that current process has ended if (abortIsRequested()) - syncStatusFrame->processHasFinished(SyncStatus::ABORTED, finalMessage); //enable okay and close events - else if (errorLog.errorsTotal()) - syncStatusFrame->processHasFinished(SyncStatus::FINISHED_WITH_ERROR, finalMessage); + syncStatusFrame.processHasFinished(SyncStatus::ABORTED, finalMessage); //enable okay and close events + else if (totalErrors) + syncStatusFrame.processHasFinished(SyncStatus::FINISHED_WITH_ERROR, finalMessage); else - syncStatusFrame->processHasFinished(SyncStatus::FINISHED_WITH_SUCCESS, finalMessage); + syncStatusFrame.processHasFinished(SyncStatus::FINISHED_WITH_SUCCESS, finalMessage); } else - syncStatusFrame->Destroy(); //syncStatusFrame is not main window => program will quit directly + syncStatusFrame.closeWindowDirectly(); //syncStatusFrame is main window => program will quit directly } inline void BatchStatusHandler::updateStatusText(const Zstring& text) { - if (currentProcess == StatusHandler::PROCESS_SYNCHRONIZING && logFile.get()) //write file transfer information to logfile + if (currentProcess == StatusHandler::PROCESS_SYNCHRONIZING && logFile.get()) //write file transfer information to log errorLog.logInfo(zToWx(text)); - syncStatusFrame->setStatusText_NoUpdate(text); + syncStatusFrame.setStatusText_NoUpdate(text); } @@ -210,16 +227,16 @@ void BatchStatusHandler::initNewProcess(int objectsTotal, wxLongLong dataTotal, switch (currentProcess) { case StatusHandler::PROCESS_SCANNING: - syncStatusFrame->resetGauge(0, 0); //dummy call to initialize some gui elements (remaining time, speed) - syncStatusFrame->setCurrentStatus(SyncStatus::SCANNING); + syncStatusFrame.resetGauge(0, 0); //dummy call to initialize some gui elements (remaining time, speed) + syncStatusFrame.setCurrentStatus(SyncStatus::SCANNING); break; case StatusHandler::PROCESS_COMPARING_CONTENT: - syncStatusFrame->resetGauge(objectsTotal, dataTotal); - syncStatusFrame->setCurrentStatus(SyncStatus::COMPARING_CONTENT); + syncStatusFrame.resetGauge(objectsTotal, dataTotal); + syncStatusFrame.setCurrentStatus(SyncStatus::COMPARING_CONTENT); break; case StatusHandler::PROCESS_SYNCHRONIZING: - syncStatusFrame->resetGauge(objectsTotal, dataTotal); - syncStatusFrame->setCurrentStatus(SyncStatus::SYNCHRONIZING); + syncStatusFrame.resetGauge(objectsTotal, dataTotal); + syncStatusFrame.setCurrentStatus(SyncStatus::SYNCHRONIZING); break; case StatusHandler::PROCESS_NONE: assert(false); @@ -237,7 +254,7 @@ void BatchStatusHandler::updateProcessedData(int objectsProcessed, wxLongLong da break; case StatusHandler::PROCESS_COMPARING_CONTENT: case StatusHandler::PROCESS_SYNCHRONIZING: - syncStatusFrame->incProgressIndicator_NoUpdate(objectsProcessed, dataProcessed); + syncStatusFrame.incProgressIndicator_NoUpdate(objectsProcessed, dataProcessed); break; case StatusHandler::PROCESS_NONE: assert(false); @@ -353,7 +370,7 @@ void BatchStatusHandler::reportFatalError(const wxString& errorMessage) inline void BatchStatusHandler::forceUiRefresh() { - syncStatusFrame->updateStatusDialogNow(); + syncStatusFrame.updateStatusDialogNow(); } diff --git a/ui/batchStatusHandler.h b/ui/batchStatusHandler.h index e4d0cae2..b2ef125b 100644 --- a/ui/batchStatusHandler.h +++ b/ui/batchStatusHandler.h @@ -1,9 +1,16 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// #ifndef BATCHSTATUSHANDLER_H_INCLUDED #define BATCHSTATUSHANDLER_H_INCLUDED #include "../library/statusHandler.h" #include "../library/processXml.h" #include "../library/errorLogging.h" +#include "progressIndicator.h" class LogFile; class SyncStatus; @@ -13,6 +20,7 @@ class BatchStatusHandler : public StatusHandler { public: BatchStatusHandler(bool runSilent, //defines: -start minimized and -quit immediately when finished + const wxString& batchFilename, const wxString* logfileDirectory, //optional: enable logging if available const xmlAccess::OnError handleError, int& returnVal); @@ -37,7 +45,7 @@ private: Process currentProcess; int& returnValue; - SyncStatus* syncStatusFrame; + SyncStatus syncStatusFrame; //the window managed by SyncStatus has longer lifetime than this handler! boost::shared_ptr<LogFile> logFile; //optional! }; diff --git a/ui/checkVersion.cpp b/ui/checkVersion.cpp index 9ecb8876..7a509204 100644 --- a/ui/checkVersion.cpp +++ b/ui/checkVersion.cpp @@ -1,3 +1,9 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// #include "checkVersion.h" #include <wx/msgdlg.h> #include <wx/protocol/http.h> @@ -6,7 +12,9 @@ #include <wx/utils.h> #include <wx/timer.h> #include "../shared/globalFunctions.h" -#include "smallDialogs.h" +//#include "smallDialogs.h" +#include "messagePopup.h" +#include "../shared/standardPaths.h" class CloseConnectionOnExit @@ -108,6 +116,11 @@ void FreeFileSync::checkForUpdateNow() void FreeFileSync::checkForUpdatePeriodically(long& lastUpdateCheck) { +#ifdef FFS_LINUX + if (!FreeFileSync::isPortableVersion()) //don't check for updates in installer version -> else: handled by .deb + return; +#endif + if (lastUpdateCheck != -1) { if (lastUpdateCheck == 0) @@ -120,7 +133,7 @@ void FreeFileSync::checkForUpdatePeriodically(long& lastUpdateCheck) const bool checkRegularly = messageDlg->ShowModal() == QuestionDlg::BUTTON_YES; messageDlg->Destroy(); if (checkRegularly) - { + { lastUpdateCheck = 123; //some old date (few seconds after 1970) checkForUpdatePeriodically(lastUpdateCheck); //check for updates now diff --git a/ui/checkVersion.h b/ui/checkVersion.h index b7f7f2ee..5aeaeb3a 100644 --- a/ui/checkVersion.h +++ b/ui/checkVersion.h @@ -1,3 +1,9 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// #ifndef UPDATEVERSION_H_INCLUDED #define UPDATEVERSION_H_INCLUDED diff --git a/ui/folderPair.h b/ui/folderPair.h index a67e5078..d20dde76 100644 --- a/ui/folderPair.h +++ b/ui/folderPair.h @@ -1,3 +1,9 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// #ifndef FOLDERPAIR_H_INCLUDED #define FOLDERPAIR_H_INCLUDED @@ -62,7 +68,7 @@ public: { basicPanel_.m_bpButtonAltSyncCfg->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("syncConfigSmall"))); basicPanel_.m_bpButtonAltSyncCfg->SetToolTip(wxString(_("Select alternate synchronization settings")) + wxT(" ") + globalFunctions::LINE_BREAK + - wxT("(") + altSyncConfig->syncConfiguration.getVariantName() + wxT(")")); + wxT("(") + getVariantName(altSyncConfig->syncConfiguration) + wxT(")")); } else { @@ -123,21 +129,31 @@ protected: private: void OnLocalFilterCfgRemove(wxCommandEvent& event) { + const int menuId = 1234; contextMenu.reset(new wxMenu); //re-create context menu - contextMenu->Append(wxID_ANY, _("Remove local filter settings")); + contextMenu->Append(menuId, _("Remove local filter settings")); contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(FolderPairPanelBasic::OnLocalFilterCfgRemoveConfirm), NULL, this); + + if (NameFilter(localFilter.includeFilter, localFilter.excludeFilter).isNull()) + contextMenu->Enable(menuId, false); //disable menu item, if clicking wouldn't make sense anyway + basicPanel_.PopupMenu(contextMenu.get()); //show context menu } void OnAltSyncCfgRemove(wxCommandEvent& event) { + const int menuId = 1234; contextMenu.reset(new wxMenu); //re-create context menu - contextMenu->Append(wxID_ANY, _("Remove alternate settings")); + contextMenu->Append(menuId, _("Remove alternate settings")); contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(FolderPairPanelBasic::OnAltSyncCfgRemoveConfirm), NULL, this); + + if (!altSyncConfig.get()) + contextMenu->Enable(menuId, false); //disable menu item, if clicking wouldn't make sense anyway + basicPanel_.PopupMenu(contextMenu.get()); //show context menu } - virtual MainConfiguration getMainConfig() const = 0; + virtual MainConfiguration getMainConfig() const = 0; virtual wxWindow* getParentWindow() = 0; virtual void OnAltSyncCfgChange() {}; @@ -170,12 +186,11 @@ private: void OnLocalFilterCfg(wxCommandEvent& event) { 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) + + if (showFilterDialog(false, //is local filter dialog + localFiltTmp.includeFilter, + localFiltTmp.excludeFilter, + getMainConfig().filterIsActive) == DefaultReturnCode::BUTTON_OKAY) { localFilter = localFiltTmp; refreshButtons(); diff --git a/ui/gridView.cpp b/ui/gridView.cpp index 9b841e56..585296a9 100644 --- a/ui/gridView.cpp +++ b/ui/gridView.cpp @@ -1,3 +1,9 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// #include "gridView.h" #include "sorting.h" #include "../synchronization.h" @@ -92,11 +98,11 @@ GridView::StatusCmpResult GridView::updateCmpResult(bool hideFiltered, //maps so } else { - if (!fsObj->isEmpty<LEFT_SIDE>()) - ++output.foldersOnLeftView; + if (!fsObj->isEmpty<LEFT_SIDE>()) + ++output.foldersOnLeftView; - if (!fsObj->isEmpty<RIGHT_SIDE>()) - ++output.foldersOnRightView; + if (!fsObj->isEmpty<RIGHT_SIDE>()) + ++output.foldersOnRightView; } viewRef.push_back(*j); @@ -206,11 +212,11 @@ GridView::StatusSyncPreview GridView::updateSyncPreview(bool hideFiltered, //map } else { - if (!fsObj->isEmpty<LEFT_SIDE>()) - ++output.foldersOnLeftView; + if (!fsObj->isEmpty<LEFT_SIDE>()) + ++output.foldersOnLeftView; - if (!fsObj->isEmpty<RIGHT_SIDE>()) - ++output.foldersOnRightView; + if (!fsObj->isEmpty<RIGHT_SIDE>()) + ++output.foldersOnRightView; } viewRef.push_back(*j); @@ -416,6 +422,28 @@ private: }; +template <bool ascending, FreeFileSync::SelectedSide side> +class GridView::SortByExtension : public std::binary_function<RefIndex, RefIndex, bool> +{ +public: + SortByExtension(const GridView& view) : m_view(view) {} + + bool operator()(const RefIndex a, const RefIndex b) const + { + const FileSystemObject* fsObjA = m_view.getReferencedRow(a); + const FileSystemObject* fsObjB = m_view.getReferencedRow(b); + if (fsObjA == NULL) //invalid rows shall appear at the end + return false; + else if (fsObjB == NULL) + return true; + + return sortByExtension<ascending, side>(*fsObjA, *fsObjB); + } +private: + const GridView& m_view; +}; + + template <bool ascending> class GridView::SortByCmpResult : public std::binary_function<RefIndex, RefIndex, bool> { @@ -490,6 +518,12 @@ void GridView::sortView(const SortType type, const bool onLeft, const bool ascen else if (!ascending && onLeft) std::sort(sortedRef.begin(), sortedRef.end(), SortByDate<false, LEFT_SIDE >(*this)); else if (!ascending && !onLeft) std::sort(sortedRef.begin(), sortedRef.end(), SortByDate<false, RIGHT_SIDE>(*this)); break; + case SORT_BY_EXTENSION: + if ( ascending && onLeft) std::stable_sort(sortedRef.begin(), sortedRef.end(), SortByExtension<true, LEFT_SIDE >(*this)); + else if ( ascending && !onLeft) std::stable_sort(sortedRef.begin(), sortedRef.end(), SortByExtension<true, RIGHT_SIDE>(*this)); + else if (!ascending && onLeft) std::stable_sort(sortedRef.begin(), sortedRef.end(), SortByExtension<false, LEFT_SIDE >(*this)); + else if (!ascending && !onLeft) std::stable_sort(sortedRef.begin(), sortedRef.end(), SortByExtension<false, RIGHT_SIDE>(*this)); + break; case SORT_BY_CMP_RESULT: if ( ascending) std::stable_sort(sortedRef.begin(), sortedRef.end(), SortByCmpResult<true >(*this)); else if (!ascending) std::stable_sort(sortedRef.begin(), sortedRef.end(), SortByCmpResult<false>(*this)); diff --git a/ui/gridView.h b/ui/gridView.h index eaa8ad8c..8cd21915 100644 --- a/ui/gridView.h +++ b/ui/gridView.h @@ -1,3 +1,9 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// #ifndef GRIDVIEW_H_INCLUDED #define GRIDVIEW_H_INCLUDED @@ -99,6 +105,7 @@ public: SORT_BY_FILENAME, SORT_BY_FILESIZE, SORT_BY_DATE, + SORT_BY_EXTENSION, SORT_BY_CMP_RESULT, SORT_BY_DIRECTORY, SORT_BY_SYNC_DIRECTION @@ -150,6 +157,9 @@ private: template <bool ascending, SelectedSide side> class SortByDate; + template <bool ascending, SelectedSide side> + class SortByExtension; + template <bool ascending> class SortByCmpResult; diff --git a/ui/guiGenerated.cpp b/ui/guiGenerated.cpp index c522ccff..573c7b1c 100644 --- a/ui/guiGenerated.cpp +++ b/ui/guiGenerated.cpp @@ -36,10 +36,10 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_menuItemNew = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("&New") ) + wxT('\t') + wxT("CTRL-N"), wxEmptyString, wxITEM_NORMAL ); m_menuFile->Append( m_menuItemNew ); - m_menuItemSave = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("S&ave configuration") ) + wxT('\t') + wxT("CTRL-S"), wxEmptyString, wxITEM_NORMAL ); + m_menuItemSave = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("S&ave configuration...") ) + wxT('\t') + wxT("CTRL-S"), wxEmptyString, wxITEM_NORMAL ); m_menuFile->Append( m_menuItemSave ); - m_menuItemLoad = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("&Load configuration") ) + wxT('\t') + wxT("CTRL-L"), wxEmptyString, wxITEM_NORMAL ); + m_menuItemLoad = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("&Load configuration...") ) + wxT('\t') + wxT("CTRL-L"), wxEmptyString, wxITEM_NORMAL ); m_menuFile->Append( m_menuItemLoad ); m_menuFile->AppendSeparator(); @@ -56,14 +56,14 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_menuAdvanced->AppendSeparator(); - m_menuItemGlobSett = new wxMenuItem( m_menuAdvanced, wxID_ANY, wxString( _("&Global settings") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuItemGlobSett = new wxMenuItem( m_menuAdvanced, wxID_ANY, wxString( _("&Global settings...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuAdvanced->Append( m_menuItemGlobSett ); - m_menuItem7 = new wxMenuItem( m_menuAdvanced, wxID_ANY, wxString( _("&Create batch job") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuItem7 = new wxMenuItem( m_menuAdvanced, wxID_ANY, wxString( _("&Create batch job...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuAdvanced->Append( m_menuItem7 ); wxMenuItem* m_menuItem5; - m_menuItem5 = new wxMenuItem( m_menuAdvanced, wxID_ANY, wxString( _("&Export file list") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuItem5 = new wxMenuItem( m_menuAdvanced, wxID_ANY, wxString( _("&Export file list...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuAdvanced->Append( m_menuItem5 ); m_menubar1->Append( m_menuAdvanced, _("&Advanced") ); @@ -73,13 +73,12 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const 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...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuItemAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( _("&About...") ) + wxT('\t') + wxT("SHIFT-F1"), wxEmptyString, wxITEM_NORMAL ); m_menuHelp->Append( m_menuItemAbout ); m_menubar1->Append( m_menuHelp, _("&Help") ); @@ -411,7 +410,6 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer1->Add( bSizer2, 1, wxEXPAND, 5 ); - wxPanel* m_panelBottom; m_panelBottom = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); bSizer3 = new wxBoxSizer( wxHORIZONTAL ); @@ -641,7 +639,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer3->Fit( m_panelBottom ); bSizer1->Add( m_panelBottom, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); - m_panel7 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSTATIC_BORDER|wxTAB_TRAVERSAL ); + m_panelStatusBar = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSTATIC_BORDER|wxTAB_TRAVERSAL ); wxBoxSizer* bSizer451; bSizer451 = new wxBoxSizer( wxHORIZONTAL ); @@ -652,7 +650,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer53->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL, 5 ); - m_staticTextStatusLeft = new wxStaticText( m_panel7, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextStatusLeft = new wxStaticText( m_panelStatusBar, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextStatusLeft->Wrap( -1 ); m_staticTextStatusLeft->SetFont( wxFont( 8, 74, 90, 92, false, wxT("Tahoma") ) ); @@ -663,13 +661,13 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer451->Add( bSizer53, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - m_staticline9 = new wxStaticLine( m_panel7, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ); + m_staticline9 = new wxStaticLine( m_panelStatusBar, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ); bSizer451->Add( m_staticline9, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxEXPAND, 2 ); bSizer451->Add( 26, 0, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_staticTextStatusMiddle = new wxStaticText( m_panel7, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextStatusMiddle = new wxStaticText( m_panelStatusBar, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextStatusMiddle->Wrap( -1 ); m_staticTextStatusMiddle->SetFont( wxFont( 8, 74, 90, 92, false, wxT("Tahoma") ) ); @@ -678,7 +676,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer451->Add( 26, 0, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_staticline10 = new wxStaticLine( m_panel7, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ); + m_staticline10 = new wxStaticLine( m_panelStatusBar, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ); bSizer451->Add( m_staticline10, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP, 2 ); wxBoxSizer* bSizer52; @@ -687,7 +685,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer52->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL, 5 ); - m_staticTextStatusRight = new wxStaticText( m_panel7, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextStatusRight = new wxStaticText( m_panelStatusBar, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextStatusRight->Wrap( -1 ); m_staticTextStatusRight->SetFont( wxFont( 8, 74, 90, 92, false, wxT("Tahoma") ) ); @@ -699,17 +697,17 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer50->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL, 5 ); - m_bitmap15 = new wxStaticBitmap( m_panel7, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 10,10 ), 0 ); + m_bitmap15 = new wxStaticBitmap( m_panelStatusBar, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 10,10 ), 0 ); bSizer50->Add( m_bitmap15, 0, wxALIGN_BOTTOM, 2 ); bSizer52->Add( bSizer50, 1, wxALIGN_BOTTOM|wxEXPAND, 5 ); bSizer451->Add( bSizer52, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - m_panel7->SetSizer( bSizer451 ); - m_panel7->Layout(); - bSizer451->Fit( m_panel7 ); - bSizer1->Add( m_panel7, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + m_panelStatusBar->SetSizer( bSizer451 ); + m_panelStatusBar->Layout(); + bSizer451->Fit( m_panelStatusBar ); + bSizer1->Add( m_panelStatusBar, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); this->SetSizer( bSizer1 ); this->Layout(); @@ -1081,11 +1079,21 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer69->Add( 0, 5, 0, 0, 5 ); - m_staticText54 = new wxStaticText( this, wxID_ANY, _("Assemble a batch file for automated synchronization. To start in batch mode simply pass the name of the file to the FreeFileSync executable: FreeFileSync.exe <batchfile>. This can also be scheduled in your operating system's task planner."), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText54->Wrap( 520 ); - m_staticText54->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxT("Tahoma") ) ); + wxBoxSizer* bSizer70; + bSizer70 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText44 = new wxStaticText( this, wxID_ANY, _("Assemble a batch file for automated synchronization. To start in batch mode simply pass the name of the file to the FreeFileSync executable: FreeFileSync.exe <batchfile>. This can also be scheduled in your operating system's task planner."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText44->Wrap( 500 ); + bSizer70->Add( m_staticText44, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + m_bpButtonHelp = new wxBitmapButton( this, wxID_HELP, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); + m_bpButtonHelp->SetToolTip( _("Help") ); - bSizer69->Add( m_staticText54, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); + m_bpButtonHelp->SetToolTip( _("Help") ); + + bSizer70->Add( m_bpButtonHelp, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + + bSizer69->Add( bSizer70, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); bSizer69->Add( 0, 5, 0, 0, 5 ); @@ -1244,12 +1252,12 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS m_radioBtnSizeDate = new wxRadioButton( m_panelOverview, wxID_ANY, _("File size and date"), wxDefaultPosition, wxDefaultSize, 0 ); m_radioBtnSizeDate->SetValue( true ); - m_radioBtnSizeDate->SetToolTip( _("Files are found equal if\n - filesize\n - last write time and date\nare the same.") ); + m_radioBtnSizeDate->SetToolTip( _("Files are found equal if\n - filesize\n - last write time and date\nare the same") ); sbSizer6->Add( m_radioBtnSizeDate, 0, 0, 5 ); m_radioBtnContent = new wxRadioButton( m_panelOverview, wxID_ANY, _("File content"), wxDefaultPosition, wxDefaultSize, 0 ); - m_radioBtnContent->SetToolTip( _("Files are found equal if\n - file content\nis the same.") ); + m_radioBtnContent->SetToolTip( _("Files are found equal if\n - file content\nis the same") ); sbSizer6->Add( m_radioBtnContent, 0, wxTOP, 5 ); @@ -1266,7 +1274,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS m_checkBoxAutomatic = new wxCheckBox( m_panelOverview, wxID_ANY, _("Automatic mode"), wxDefaultPosition, wxDefaultSize, 0 ); - m_checkBoxAutomatic->SetToolTip( _("Synchronize both sides using a database. Deletions are detected automatically.") ); + m_checkBoxAutomatic->SetToolTip( _("Synchronize both sides using a database. Deletions are detected automatically") ); sbSizer24->Add( m_checkBoxAutomatic, 0, wxALL, 5 ); @@ -1591,6 +1599,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS // Connect Events this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( BatchDlgGenerated::OnClose ) ); + m_bpButtonHelp->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnHelp ), NULL, this ); 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 ); @@ -1615,6 +1624,7 @@ BatchDlgGenerated::~BatchDlgGenerated() { // Disconnect Events this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( BatchDlgGenerated::OnClose ) ); + m_bpButtonHelp->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnHelp ), NULL, this ); 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 ); @@ -1804,7 +1814,7 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const sbSizer7->Add( m_staticText1, 0, wxALL, 5 ); wxFlexGridSizer* fgSizer1; - fgSizer1 = new wxFlexGridSizer( 5, 3, 8, 5 ); + fgSizer1 = new wxFlexGridSizer( 4, 3, 8, 5 ); fgSizer1->SetFlexibleDirection( wxHORIZONTAL ); fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); @@ -1851,24 +1861,6 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const m_staticText101->Wrap( 300 ); fgSizer1->Add( m_staticText101, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - 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 ); m_radioBtnCustom->SetFont( wxFont( 11, 74, 90, 92, false, wxT("Tahoma") ) ); m_radioBtnCustom->Enable( false ); @@ -1949,11 +1941,11 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const wxBoxSizer* bSizer291; bSizer291 = new wxBoxSizer( wxHORIZONTAL ); - m_buttonApply = new wxButton( this, wxID_OK, _("&Apply"), wxDefaultPosition, wxSize( 120,35 ), 0 ); - m_buttonApply->SetDefault(); - m_buttonApply->SetFont( wxFont( 10, 74, 90, 92, false, wxT("Tahoma") ) ); + m_buttonOK = new wxButton( this, wxID_OK, _("&OK"), wxDefaultPosition, wxSize( 100,35 ), 0 ); + m_buttonOK->SetDefault(); + m_buttonOK->SetFont( wxFont( 10, 74, 90, 92, false, wxT("Tahoma") ) ); - bSizer291->Add( m_buttonApply, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + bSizer291->Add( m_buttonOK, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); m_button16 = new wxButton( this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxSize( -1,30 ), 0 ); m_button16->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); @@ -2111,11 +2103,10 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const m_buttonOneWay->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncLeftToRight ), NULL, this ); m_radioBtnUpdate->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncUpdate ), NULL, this ); m_buttonUpdate->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncUpdate ), NULL, this ); - m_radioBtnTwoWay->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncBothSides ), NULL, this ); - m_buttonTwoWay->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncBothSides ), NULL, this ); + m_radioBtnCustom->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncCustom ), NULL, this ); m_choiceHandleError->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnChangeErrorHandling ), NULL, this ); m_choiceHandleDeletion->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnChangeDeletionHandling ), NULL, this ); - m_buttonApply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnApply ), NULL, this ); + m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnApply ), NULL, this ); m_button16->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnCancel ), NULL, this ); m_bpButtonLeftOnly->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnExLeftSideOnly ), NULL, this ); m_bpButtonRightOnly->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnExRightSideOnly ), NULL, this ); @@ -2135,11 +2126,10 @@ SyncCfgDlgGenerated::~SyncCfgDlgGenerated() m_buttonOneWay->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncLeftToRight ), NULL, this ); m_radioBtnUpdate->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncUpdate ), NULL, this ); m_buttonUpdate->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncUpdate ), NULL, this ); - m_radioBtnTwoWay->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncBothSides ), NULL, this ); - m_buttonTwoWay->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncBothSides ), NULL, this ); + m_radioBtnCustom->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncCustom ), NULL, this ); m_choiceHandleError->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnChangeErrorHandling ), NULL, this ); m_choiceHandleDeletion->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( SyncCfgDlgGenerated::OnChangeDeletionHandling ), NULL, this ); - m_buttonApply->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnApply ), NULL, this ); + m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnApply ), NULL, this ); m_button16->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnCancel ), NULL, this ); m_bpButtonLeftOnly->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnExLeftSideOnly ), NULL, this ); m_bpButtonRightOnly->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnExRightSideOnly ), NULL, this ); @@ -2169,34 +2159,34 @@ CmpCfgDlgGenerated::CmpCfgDlgGenerated( wxWindow* parent, wxWindowID id, const w m_radioBtnSizeDate = new wxRadioButton( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxRB_GROUP ); m_radioBtnSizeDate->SetValue( true ); - m_radioBtnSizeDate->SetToolTip( _("Files are found equal if\n - filesize\n - last write time and date\nare the same.") ); + m_radioBtnSizeDate->SetToolTip( _("Files are found equal if\n - filesize\n - last write time and date\nare the same") ); fgSizer16->Add( m_radioBtnSizeDate, 0, wxALIGN_CENTER_VERTICAL, 5 ); m_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.") ); + 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.") ); + m_buttonTimeSize->SetToolTip( _("Files are found equal if\n - filesize\n - last write time and date\nare the same") ); 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.") ); + m_radioBtnContent->SetToolTip( _("Files are found equal if\n - file content\nis the same") ); fgSizer16->Add( m_radioBtnContent, 0, wxALIGN_CENTER_VERTICAL, 5 ); 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.") ); + 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.") ); + m_buttonContent->SetToolTip( _("Files are found equal if\n - file content\nis the same") ); fgSizer16->Add( m_buttonContent, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); @@ -2205,7 +2195,7 @@ CmpCfgDlgGenerated::CmpCfgDlgGenerated( wxWindow* parent, wxWindowID id, const w m_staticline14 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ); sbSizer6->Add( m_staticline14, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); - m_bpButtonHelp = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); + m_bpButtonHelp = new wxBitmapButton( this, wxID_HELP, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); m_bpButtonHelp->SetToolTip( _("Help") ); m_bpButtonHelp->SetToolTip( _("Help") ); @@ -2344,22 +2334,37 @@ SyncStatusDlgGenerated::SyncStatusDlgGenerated( wxWindow* parent, wxWindowID id, wxBoxSizer* bSizer111; bSizer111 = new wxBoxSizer( wxVERTICAL ); - wxBoxSizer* bSizer113; - bSizer113 = new wxBoxSizer( wxHORIZONTAL ); + bSizerObjectsRemaining = new wxBoxSizer( wxHORIZONTAL ); m_staticText25 = new wxStaticText( this, wxID_ANY, _("Files/folders remaining:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText25->Wrap( -1 ); m_staticText25->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); - bSizer113->Add( m_staticText25, 0, wxALIGN_BOTTOM, 5 ); + bSizerObjectsRemaining->Add( m_staticText25, 0, wxALIGN_BOTTOM, 5 ); m_staticTextRemainingObj = new wxStaticText( this, wxID_ANY, _("dummy"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); m_staticTextRemainingObj->Wrap( -1 ); m_staticTextRemainingObj->SetFont( wxFont( 9, 74, 90, 92, false, wxT("Arial") ) ); - bSizer113->Add( m_staticTextRemainingObj, 0, wxLEFT|wxALIGN_BOTTOM, 5 ); + bSizerObjectsRemaining->Add( m_staticTextRemainingObj, 0, wxLEFT|wxALIGN_BOTTOM, 5 ); + + bSizer111->Add( bSizerObjectsRemaining, 0, 0, 5 ); + + bSizerObjectsProcessed = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText251 = new wxStaticText( this, wxID_ANY, _("Files/folders processed:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText251->Wrap( -1 ); + m_staticText251->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); - bSizer111->Add( bSizer113, 0, 0, 5 ); + bSizerObjectsProcessed->Add( m_staticText251, 0, wxALIGN_BOTTOM, 5 ); + + m_staticTextProcessedObj = new wxStaticText( this, wxID_ANY, _("dummy"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_staticTextProcessedObj->Wrap( -1 ); + m_staticTextProcessedObj->SetFont( wxFont( 9, 74, 90, 92, false, wxT("Arial") ) ); + + bSizerObjectsProcessed->Add( m_staticTextProcessedObj, 0, wxLEFT|wxALIGN_BOTTOM, 5 ); + + bSizer111->Add( bSizerObjectsProcessed, 0, 0, 5 ); bSizerSpeed = new wxBoxSizer( wxHORIZONTAL ); @@ -2404,22 +2409,37 @@ SyncStatusDlgGenerated::SyncStatusDlgGenerated( wxWindow* parent, wxWindowID id, wxBoxSizer* bSizer114; bSizer114 = new wxBoxSizer( wxVERTICAL ); - wxBoxSizer* bSizer116; - bSizer116 = new wxBoxSizer( wxHORIZONTAL ); + bSizerDataRemaining = new wxBoxSizer( wxHORIZONTAL ); m_staticText26 = new wxStaticText( this, wxID_ANY, _("Data remaining:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText26->Wrap( -1 ); m_staticText26->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); - bSizer116->Add( m_staticText26, 0, wxALIGN_BOTTOM, 5 ); + bSizerDataRemaining->Add( m_staticText26, 0, wxALIGN_BOTTOM, 5 ); m_staticTextDataRemaining = new wxStaticText( this, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextDataRemaining->Wrap( -1 ); m_staticTextDataRemaining->SetFont( wxFont( 9, 74, 90, 92, false, wxT("Arial") ) ); - bSizer116->Add( m_staticTextDataRemaining, 0, wxLEFT|wxALIGN_BOTTOM, 5 ); + bSizerDataRemaining->Add( m_staticTextDataRemaining, 0, wxLEFT|wxALIGN_BOTTOM, 5 ); + + bSizer114->Add( bSizerDataRemaining, 0, wxALIGN_RIGHT, 5 ); + + bSizerDataProcessed = new wxBoxSizer( wxHORIZONTAL ); - bSizer114->Add( bSizer116, 0, wxALIGN_RIGHT, 5 ); + m_staticText261 = new wxStaticText( this, wxID_ANY, _("Data transferred:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText261->Wrap( -1 ); + m_staticText261->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); + + bSizerDataProcessed->Add( m_staticText261, 0, wxALIGN_BOTTOM, 5 ); + + m_staticTextDataProcessed = new wxStaticText( this, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextDataProcessed->Wrap( -1 ); + m_staticTextDataProcessed->SetFont( wxFont( 9, 74, 90, 92, false, wxT("Arial") ) ); + + bSizerDataProcessed->Add( m_staticTextDataProcessed, 0, wxLEFT|wxALIGN_BOTTOM, 5 ); + + bSizer114->Add( bSizerDataProcessed, 0, wxALIGN_RIGHT, 5 ); bSizerRemTime = new wxBoxSizer( wxHORIZONTAL ); @@ -2533,7 +2553,7 @@ HelpDlgGenerated::HelpDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr m_staticText61->Wrap( 500 ); bSizer70->Add( m_staticText61, 0, wxALL, 5 ); - m_treeCtrl1 = new wxTreeCtrl( m_scrolledWindow1, wxID_ANY, wxDefaultPosition, wxSize( -1,180 ), wxTR_DEFAULT_STYLE ); + m_treeCtrl1 = new wxTreeCtrl( m_scrolledWindow1, wxID_ANY, wxDefaultPosition, wxSize( -1,175 ), wxTR_DEFAULT_STYLE ); m_treeCtrl1->SetBackgroundColour( wxColour( 237, 236, 235 ) ); bSizer70->Add( m_treeCtrl1, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); @@ -2570,7 +2590,7 @@ HelpDlgGenerated::HelpDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr m_scrolledWindow1->Layout(); bSizer70->Fit( m_scrolledWindow1 ); m_notebook1->AddPage( m_scrolledWindow1, _("File size and date"), true ); - m_scrolledWindow5 = new wxScrolledWindow( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL ); + m_scrolledWindow5 = new wxScrolledWindow( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxSIMPLE_BORDER|wxVSCROLL ); m_scrolledWindow5->SetScrollRate( 5, 5 ); m_scrolledWindow5->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_INACTIVEBORDER ) ); @@ -2641,79 +2661,6 @@ 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 ); @@ -2846,9 +2793,9 @@ AboutDlgGenerated::AboutDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer103->Add( 20, 0, 1, wxEXPAND, 5 ); - m_hyperlink6 = new wxHyperlinkCtrl( this, wxID_ANY, _("Report translation error"), wxT("http://sourceforge.net/forum/forum.php?forum_id=976976"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_hyperlink6 = new wxHyperlinkCtrl( this, wxID_ANY, _("Report translation error"), wxT("http://sourceforge.net/projects/freefilesync/forums/forum/976976"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); m_hyperlink6->SetFont( wxFont( 10, 74, 90, 92, true, wxT("Tahoma") ) ); - m_hyperlink6->SetToolTip( _("https://sourceforge.net/forum/forum.php?forum_id=976976") ); + m_hyperlink6->SetToolTip( _("http://sourceforge.net/projects/freefilesync/forums/forum/976976") ); bSizer103->Add( m_hyperlink6, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); @@ -2966,6 +2913,7 @@ ErrorDlgGenerated::ErrorDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer25 = new wxBoxSizer( wxHORIZONTAL ); m_buttonIgnore = new wxButton( this, wxID_OK, _("&Ignore"), wxDefaultPosition, wxSize( -1,30 ), 0 ); + m_buttonIgnore->SetDefault(); m_buttonIgnore->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); bSizer25->Add( m_buttonIgnore, 0, wxTOP|wxBOTTOM|wxLEFT, 5 ); @@ -3038,6 +2986,7 @@ WarningDlgGenerated::WarningDlgGenerated( wxWindow* parent, wxWindowID id, const bSizer25 = new wxBoxSizer( wxHORIZONTAL ); m_buttonIgnore = new wxButton( this, wxID_IGNORE, _("&Ignore"), wxDefaultPosition, wxSize( -1,30 ), 0 ); + m_buttonIgnore->SetDefault(); m_buttonIgnore->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); bSizer25->Add( m_buttonIgnore, 0, wxTOP|wxBOTTOM|wxLEFT, 5 ); @@ -3103,6 +3052,7 @@ QuestionDlgGenerated::QuestionDlgGenerated( wxWindow* parent, wxWindowID id, con bSizer25 = new wxBoxSizer( wxHORIZONTAL ); m_buttonYes = new wxButton( this, wxID_YES, _("&Yes"), wxDefaultPosition, wxSize( -1,30 ), 0 ); + m_buttonYes->SetDefault(); m_buttonYes->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); bSizer25->Add( m_buttonYes, 0, wxTOP|wxBOTTOM|wxLEFT, 5 ); @@ -3274,7 +3224,7 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w m_staticText44->Wrap( 400 ); bSizer70->Add( m_staticText44, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); - m_bpButtonHelp = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); + m_bpButtonHelp = new wxBitmapButton( this, wxID_HELP, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); m_bpButtonHelp->SetToolTip( _("Help") ); m_bpButtonHelp->SetToolTip( _("Help") ); @@ -3410,21 +3360,23 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w m_button9 = new wxButton( this, wxID_DEFAULT, _("&Default"), wxDefaultPosition, wxSize( -1,30 ), 0 ); m_button9->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); - bSizer22->Add( m_button9, 0, wxALL, 5 ); + bSizer22->Add( m_button9, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - bSizer22->Add( 0, 0, 1, wxEXPAND, 5 ); + bSizer22->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL, 5 ); - m_button10 = new wxButton( this, wxID_OK, _("&Apply"), wxDefaultPosition, wxSize( -1,30 ), 0 ); + m_button10 = new wxButton( this, wxID_OK, _("&OK"), wxDefaultPosition, wxSize( -1,30 ), 0 ); m_button10->SetDefault(); m_button10->SetFont( wxFont( 10, 74, 90, 92, false, wxT("Tahoma") ) ); - bSizer22->Add( m_button10, 0, wxALL, 5 ); + bSizer22->Add( m_button10, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_button17 = new wxButton( this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxSize( -1,30 ), 0 ); + m_button17->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); - m_button17 = new wxButton( this, wxID_CANCEL, _("dummy"), wxDefaultPosition, wxSize( 0,0 ), 0 ); - bSizer22->Add( m_button17, 0, wxALIGN_BOTTOM, 5 ); + bSizer22->Add( m_button17, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - bSizer21->Add( bSizer22, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxTOP|wxBOTTOM, 5 ); + bSizer21->Add( bSizer22, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP|wxBOTTOM|wxEXPAND, 5 ); this->SetSizer( bSizer21 ); this->Layout(); @@ -3485,30 +3437,29 @@ CustomizeColsDlgGenerated::CustomizeColsDlgGenerated( wxWindow* parent, wxWindow bSizer96->Add( bSizer99, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); - m_checkBoxShowFileIcons = new wxCheckBox( this, wxID_ANY, _("Show file icons"), wxDefaultPosition, wxDefaultSize, 0 ); - - bSizer96->Add( m_checkBoxShowFileIcons, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP|wxBOTTOM, 5 ); - wxBoxSizer* bSizer97; bSizer97 = new wxBoxSizer( wxHORIZONTAL ); - m_button28 = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,30 ), 0 ); - m_button28->SetDefault(); - m_button28->SetFont( wxFont( 10, 74, 90, 92, false, wxT("Tahoma") ) ); - - bSizer97->Add( m_button28, 0, wxALL, 5 ); - m_button9 = new wxButton( this, wxID_DEFAULT, _("&Default"), wxDefaultPosition, wxSize( -1,30 ), 0 ); m_button9->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); bSizer97->Add( m_button9, 0, wxALL, 5 ); - m_button29 = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,30 ), 0 ); + + bSizer97->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL, 5 ); + + m_button28 = new wxButton( this, wxID_OK, _("&OK"), wxDefaultPosition, wxSize( -1,30 ), 0 ); + m_button28->SetDefault(); + m_button28->SetFont( wxFont( 10, 74, 90, 92, false, wxT("Tahoma") ) ); + + bSizer97->Add( m_button28, 0, wxALL, 5 ); + + m_button29 = new wxButton( this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxSize( -1,30 ), 0 ); m_button29->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); bSizer97->Add( m_button29, 0, wxALL, 5 ); - bSizer96->Add( bSizer97, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + bSizer96->Add( bSizer97, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 ); this->SetSizer( bSizer96 ); this->Layout(); @@ -3518,8 +3469,8 @@ CustomizeColsDlgGenerated::CustomizeColsDlgGenerated( wxWindow* parent, wxWindow this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CustomizeColsDlgGenerated::OnClose ) ); m_bpButton29->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnMoveUp ), NULL, this ); m_bpButton30->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnMoveDown ), NULL, this ); - m_button28->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnOkay ), NULL, this ); m_button9->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnDefault ), NULL, this ); + m_button28->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnOkay ), NULL, this ); m_button29->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnCancel ), NULL, this ); } @@ -3529,8 +3480,8 @@ CustomizeColsDlgGenerated::~CustomizeColsDlgGenerated() this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CustomizeColsDlgGenerated::OnClose ) ); m_bpButton29->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnMoveUp ), NULL, this ); m_bpButton30->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnMoveDown ), NULL, this ); - m_button28->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnOkay ), NULL, this ); m_button9->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnDefault ), NULL, this ); + m_button28->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnOkay ), NULL, this ); m_button29->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnCancel ), NULL, this ); } @@ -3580,7 +3531,7 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind m_staticText114 = new wxStaticText( this, wxID_ANY, _("Ignore 1-hour file time difference"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText114->Wrap( -1 ); - m_staticText114->SetToolTip( _("Treat file times that differ by exactly +/- 1 hour as equal, less than 1 hour as conflict in order to handle Daylight Saving Time changes.") ); + m_staticText114->SetToolTip( _("Treat file times that differ by exactly +/- 1 hour as equal, less than 1 hour as conflict in order to handle Daylight Saving Time changes") ); bSizer120->Add( m_staticText114, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); @@ -3589,7 +3540,7 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind m_checkBoxIgnoreOneHour = new wxCheckBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_checkBoxIgnoreOneHour->SetToolTip( _("Treat file times that differ by exactly +/- 1 hour as equal, less than 1 hour as conflict in order to handle Daylight Saving Time changes.") ); + m_checkBoxIgnoreOneHour->SetToolTip( _("Treat file times that differ by exactly +/- 1 hour as equal, less than 1 hour as conflict in order to handle Daylight Saving Time changes") ); bSizer120->Add( m_checkBoxIgnoreOneHour, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); @@ -3600,7 +3551,7 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind m_staticTextCopyLocked = new wxStaticText( this, wxID_ANY, _("Copy locked files"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextCopyLocked->Wrap( -1 ); - m_staticTextCopyLocked->SetToolTip( _("Copy shared or locked files using Volume Shadow Copy Service.") ); + m_staticTextCopyLocked->SetToolTip( _("Copy shared or locked files using Volume Shadow Copy Service") ); bSizer1201->Add( m_staticTextCopyLocked, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); @@ -3609,7 +3560,7 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind m_checkBoxCopyLocked = new wxCheckBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_checkBoxCopyLocked->SetToolTip( _("Copy shared or locked files using Volume Shadow Copy Service.") ); + m_checkBoxCopyLocked->SetToolTip( _("Copy shared or locked files using Volume Shadow Copy Service") ); bSizer1201->Add( m_checkBoxCopyLocked, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); @@ -3696,23 +3647,26 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind wxBoxSizer* bSizer97; bSizer97 = new wxBoxSizer( wxHORIZONTAL ); - m_buttonOkay = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,30 ), 0 ); - m_buttonOkay->SetDefault(); - m_buttonOkay->SetFont( wxFont( 10, 74, 90, 92, false, wxT("Tahoma") ) ); - - bSizer97->Add( m_buttonOkay, 0, wxALL, 5 ); - m_button9 = new wxButton( this, wxID_DEFAULT, _("&Default"), wxDefaultPosition, wxSize( -1,30 ), 0 ); m_button9->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); bSizer97->Add( m_button9, 0, wxALL, 5 ); - m_button29 = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,30 ), 0 ); + + bSizer97->Add( 0, 0, 1, 0, 5 ); + + m_buttonOkay = new wxButton( this, wxID_OK, _("&OK"), wxDefaultPosition, wxSize( -1,30 ), 0 ); + m_buttonOkay->SetDefault(); + m_buttonOkay->SetFont( wxFont( 10, 74, 90, 92, false, wxT("Tahoma") ) ); + + bSizer97->Add( m_buttonOkay, 0, wxALL, 5 ); + + m_button29 = new wxButton( this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxSize( -1,30 ), 0 ); m_button29->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); bSizer97->Add( m_button29, 0, wxALL, 5 ); - bSizer95->Add( bSizer97, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer95->Add( bSizer97, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); this->SetSizer( bSizer95 ); this->Layout(); @@ -3723,8 +3677,8 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind m_buttonResetDialogs->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnResetDialogs ), NULL, this ); m_bpButtonAddRow->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnAddRow ), NULL, this ); m_bpButtonRemoveRow->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnRemoveRow ), NULL, this ); - m_buttonOkay->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnOkay ), NULL, this ); m_button9->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnDefault ), NULL, this ); + m_buttonOkay->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnOkay ), NULL, this ); m_button29->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnCancel ), NULL, this ); } @@ -3735,8 +3689,8 @@ GlobalSettingsDlgGenerated::~GlobalSettingsDlgGenerated() m_buttonResetDialogs->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnResetDialogs ), NULL, this ); m_bpButtonAddRow->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnAddRow ), NULL, this ); m_bpButtonRemoveRow->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnRemoveRow ), NULL, this ); - m_buttonOkay->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnOkay ), NULL, this ); m_button9->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnDefault ), NULL, this ); + m_buttonOkay->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnOkay ), NULL, this ); m_button29->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GlobalSettingsDlgGenerated::OnCancel ), NULL, this ); } @@ -3964,3 +3918,70 @@ PopupFrameGenerated1::PopupFrameGenerated1( wxWindow* parent, wxWindowID id, con PopupFrameGenerated1::~PopupFrameGenerated1() { } + +SearchDialogGenerated::SearchDialogGenerated( 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* bSizer161; + bSizer161 = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizer166; + bSizer166 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer162; + bSizer162 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText101 = new wxStaticText( this, wxID_ANY, _("Find what:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText101->Wrap( -1 ); + bSizer162->Add( m_staticText101, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlSearchTxt = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 220,-1 ), 0 ); + bSizer162->Add( m_textCtrlSearchTxt, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer166->Add( bSizer162, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + + bSizer166->Add( 0, 10, 0, 0, 5 ); + + m_checkBoxMatchCase = new wxCheckBox( this, wxID_ANY, _("Match case"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer166->Add( m_checkBoxMatchCase, 0, wxALL, 5 ); + + bSizer161->Add( bSizer166, 1, wxALIGN_CENTER_VERTICAL, 5 ); + + wxBoxSizer* bSizer97; + bSizer97 = new wxBoxSizer( wxVERTICAL ); + + m_buttonFindNext = new wxButton( this, wxID_OK, _("&Find next"), wxDefaultPosition, wxSize( -1,30 ), 0 ); + m_buttonFindNext->SetDefault(); + m_buttonFindNext->SetFont( wxFont( 10, 74, 90, 92, false, wxT("Tahoma") ) ); + + bSizer97->Add( m_buttonFindNext, 0, wxALL|wxEXPAND, 5 ); + + m_button29 = new wxButton( this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxSize( -1,30 ), 0 ); + m_button29->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); + + bSizer97->Add( m_button29, 0, wxALL|wxEXPAND, 5 ); + + bSizer161->Add( bSizer97, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + this->SetSizer( bSizer161 ); + this->Layout(); + bSizer161->Fit( this ); + + // Connect Events + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( SearchDialogGenerated::OnClose ) ); + m_textCtrlSearchTxt->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( SearchDialogGenerated::OnText ), NULL, this ); + m_buttonFindNext->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SearchDialogGenerated::OnFindNext ), NULL, this ); + m_button29->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SearchDialogGenerated::OnCancel ), NULL, this ); +} + +SearchDialogGenerated::~SearchDialogGenerated() +{ + // Disconnect Events + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( SearchDialogGenerated::OnClose ) ); + m_textCtrlSearchTxt->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( SearchDialogGenerated::OnText ), NULL, this ); + m_buttonFindNext->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SearchDialogGenerated::OnFindNext ), NULL, this ); + m_button29->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SearchDialogGenerated::OnCancel ), NULL, this ); +} diff --git a/ui/guiGenerated.h b/ui/guiGenerated.h index ab4d3c12..ff1c4ddc 100644 --- a/ui/guiGenerated.h +++ b/ui/guiGenerated.h @@ -75,6 +75,7 @@ class MainDialogGenerated : public wxFrame wxMenuItem* m_menuItemGlobSett; wxMenuItem* m_menuItem7; wxMenu* m_menuHelp; + wxMenuItem* m_menuItemCheckVer; wxMenuItem* m_menuItemAbout; wxBoxSizer* bSizer1; wxPanel* m_panel71; @@ -106,6 +107,7 @@ class MainDialogGenerated : public wxFrame wxPanel* m_panelMiddle; CustomGridMiddle* m_gridMiddle; CustomGridRight* m_gridRight; + wxPanel* m_panelBottom; wxBoxSizer* bSizer3; wxNotebook* m_notebookBottomLeft; wxPanel* m_panel30; @@ -145,7 +147,7 @@ class MainDialogGenerated : public wxFrame wxStaticBitmap* m_bitmapData; wxTextCtrl* m_textCtrlData; wxBitmapButton* m_bpButton10; - wxPanel* m_panel7; + wxPanel* m_panelStatusBar; wxStaticText* m_staticTextStatusLeft; @@ -300,7 +302,8 @@ class BatchDlgGenerated : public wxDialog wxStaticText* m_staticText56; - wxStaticText* m_staticText54; + wxStaticText* m_staticText44; + wxBitmapButton* m_bpButtonHelp; wxStaticLine* m_staticline10; wxStaticText* m_staticText531; @@ -368,6 +371,7 @@ class BatchDlgGenerated : public wxDialog // Virtual event handlers, overide them in your derived class virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } + virtual void OnHelp( wxCommandEvent& event ){ event.Skip(); } virtual void OnAddFolderPair( wxCommandEvent& event ){ event.Skip(); } virtual void OnRemoveTopFolderPair( wxCommandEvent& event ){ event.Skip(); } virtual void OnChangeCompareVar( wxCommandEvent& event ){ event.Skip(); } @@ -456,9 +460,6 @@ class SyncCfgDlgGenerated : public wxDialog wxRadioButton* m_radioBtnUpdate; wxButton* m_buttonUpdate; wxStaticText* m_staticText101; - wxRadioButton* m_radioBtnTwoWay; - wxButton* m_buttonTwoWay; - wxStaticText* m_staticText10; wxRadioButton* m_radioBtnCustom; wxStaticText* m_staticText23; @@ -473,7 +474,7 @@ class SyncCfgDlgGenerated : public wxDialog wxTextCtrl* m_textCtrlCustomDelFolder; wxDirPickerCtrl* m_dirPickerCustomDelFolder; - wxButton* m_buttonApply; + wxButton* m_buttonOK; wxButton* m_button16; @@ -505,7 +506,7 @@ class SyncCfgDlgGenerated : public wxDialog virtual void OnSyncAutomatic( wxCommandEvent& event ){ event.Skip(); } virtual void OnSyncLeftToRight( wxCommandEvent& event ){ event.Skip(); } virtual void OnSyncUpdate( wxCommandEvent& event ){ event.Skip(); } - virtual void OnSyncBothSides( wxCommandEvent& event ){ event.Skip(); } + virtual void OnSyncCustom( wxCommandEvent& event ){ event.Skip(); } virtual void OnChangeErrorHandling( wxCommandEvent& event ){ event.Skip(); } virtual void OnChangeDeletionHandling( wxCommandEvent& event ){ event.Skip(); } virtual void OnApply( wxCommandEvent& event ){ event.Skip(); } @@ -580,8 +581,12 @@ class SyncStatusDlgGenerated : public wxFrame wxStaticText* m_staticTextTimeElapsed; wxTextCtrl* m_textCtrlInfo; wxBoxSizer* bSizer28; + wxBoxSizer* bSizerObjectsRemaining; wxStaticText* m_staticText25; wxStaticText* m_staticTextRemainingObj; + wxBoxSizer* bSizerObjectsProcessed; + wxStaticText* m_staticText251; + wxStaticText* m_staticTextProcessedObj; wxBoxSizer* bSizerSpeed; wxStaticText* m_staticText108; wxStaticText* m_staticTextSpeed; @@ -590,8 +595,12 @@ class SyncStatusDlgGenerated : public wxFrame wxButton* m_buttonPause; wxButton* m_buttonAbort; + wxBoxSizer* bSizerDataRemaining; wxStaticText* m_staticText26; wxStaticText* m_staticTextDataRemaining; + wxBoxSizer* bSizerDataProcessed; + wxStaticText* m_staticText261; + wxStaticText* m_staticTextDataProcessed; wxBoxSizer* bSizerRemTime; wxStaticText* m_staticText106; wxStaticText* m_staticTextTimeRemaining; @@ -657,41 +666,12 @@ class HelpDlgGenerated : public wxDialog public: - HelpDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 565,501 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + HelpDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 579,543 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~HelpDlgGenerated(); }; /////////////////////////////////////////////////////////////////////////////// -/// 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 @@ -933,17 +913,17 @@ class CustomizeColsDlgGenerated : public wxDialog wxCheckListBox* m_checkListColumns; wxBitmapButton* m_bpButton29; wxBitmapButton* m_bpButton30; - wxCheckBox* m_checkBoxShowFileIcons; - wxButton* m_button28; wxButton* m_button9; + + wxButton* m_button28; wxButton* m_button29; // Virtual event handlers, overide them in your derived class virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } virtual void OnMoveUp( wxCommandEvent& event ){ event.Skip(); } virtual void OnMoveDown( wxCommandEvent& event ){ event.Skip(); } - virtual void OnOkay( wxCommandEvent& event ){ event.Skip(); } virtual void OnDefault( wxCommandEvent& event ){ event.Skip(); } + virtual void OnOkay( wxCommandEvent& event ){ event.Skip(); } virtual void OnCancel( wxCommandEvent& event ){ event.Skip(); } @@ -982,8 +962,9 @@ class GlobalSettingsDlgGenerated : public wxDialog wxBitmapButton* m_bpButtonAddRow; wxBitmapButton* m_bpButtonRemoveRow; - wxButton* m_buttonOkay; wxButton* m_button9; + + wxButton* m_buttonOkay; wxButton* m_button29; // Virtual event handlers, overide them in your derived class @@ -991,8 +972,8 @@ class GlobalSettingsDlgGenerated : public wxDialog virtual void OnResetDialogs( wxCommandEvent& event ){ event.Skip(); } virtual void OnAddRow( wxCommandEvent& event ){ event.Skip(); } virtual void OnRemoveRow( wxCommandEvent& event ){ event.Skip(); } - virtual void OnOkay( wxCommandEvent& event ){ event.Skip(); } virtual void OnDefault( wxCommandEvent& event ){ event.Skip(); } + virtual void OnOkay( wxCommandEvent& event ){ event.Skip(); } virtual void OnCancel( wxCommandEvent& event ){ event.Skip(); } @@ -1065,4 +1046,32 @@ class PopupFrameGenerated1 : public wxFrame }; +/////////////////////////////////////////////////////////////////////////////// +/// Class SearchDialogGenerated +/////////////////////////////////////////////////////////////////////////////// +class SearchDialogGenerated : public wxDialog +{ + private: + + protected: + wxStaticText* m_staticText101; + wxTextCtrl* m_textCtrlSearchTxt; + + wxCheckBox* m_checkBoxMatchCase; + wxButton* m_buttonFindNext; + wxButton* m_button29; + + // Virtual event handlers, overide them in your derived class + virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } + virtual void OnText( wxCommandEvent& event ){ event.Skip(); } + virtual void OnFindNext( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCancel( wxCommandEvent& event ){ event.Skip(); } + + + public: + SearchDialogGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Find"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~SearchDialogGenerated(); + +}; + #endif //__guiGenerated__ diff --git a/ui/guiStatusHandler.cpp b/ui/guiStatusHandler.cpp index 3cf6eb01..bd5f001e 100644 --- a/ui/guiStatusHandler.cpp +++ b/ui/guiStatusHandler.cpp @@ -1,9 +1,19 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// #include "guiStatusHandler.h" #include "smallDialogs.h" +#include "messagePopup.h" #include "../shared/systemConstants.h" #include "mainDialog.h" #include <wx/wupdlock.h> #include "../shared/globalFunctions.h" +#include "../shared/stringConv.h" + +using namespace FreeFileSync; CompareStatusHandler::CompareStatusHandler(MainDialog* dlg) : @@ -17,8 +27,8 @@ CompareStatusHandler::CompareStatusHandler(MainDialog* dlg) : mainDialog->disableAllElements(); //display status panel during compare - mainDialog->compareStatus->init(); //clear old values - mainDialog->compareStatus->Show(); + mainDialog->compareStatus.init(); //clear old values + mainDialog->compareStatus.getAsWindow()->Show(); mainDialog->bSizer1->Layout(); //both sizers need to recalculate! mainDialog->bSizer6->Layout(); //adapt layout for wxBitmapWithImage @@ -40,7 +50,7 @@ CompareStatusHandler::~CompareStatusHandler() mainDialog->pushStatusInformation(_("Operation aborted!")); //hide status panel from main window - mainDialog->compareStatus->Hide(); + mainDialog->compareStatus.getAsWindow()->Hide(); mainDialog->bSizer6->Layout(); //adapt layout for wxBitmapWithImage mainDialog->Layout(); @@ -54,7 +64,7 @@ CompareStatusHandler::~CompareStatusHandler() inline void CompareStatusHandler::updateStatusText(const Zstring& text) { - mainDialog->compareStatus->setStatusText_NoUpdate(text); + mainDialog->compareStatus.setStatusText_NoUpdate(text); } @@ -67,7 +77,7 @@ void CompareStatusHandler::initNewProcess(int objectsTotal, wxLongLong dataTotal case StatusHandler::PROCESS_SCANNING: break; case StatusHandler::PROCESS_COMPARING_CONTENT: - mainDialog->compareStatus->switchToCompareBytewise(objectsTotal, dataTotal); + mainDialog->compareStatus.switchToCompareBytewise(objectsTotal, dataTotal); mainDialog->Layout(); break; case StatusHandler::PROCESS_SYNCHRONIZING: @@ -84,10 +94,10 @@ void CompareStatusHandler::updateProcessedData(int objectsProcessed, wxLongLong switch (currentProcess) { case StatusHandler::PROCESS_SCANNING: - mainDialog->compareStatus->incScannedObjects_NoUpdate(objectsProcessed); + mainDialog->compareStatus.incScannedObjects_NoUpdate(objectsProcessed); break; case StatusHandler::PROCESS_COMPARING_CONTENT: - mainDialog->compareStatus->incProcessedCmpData_NoUpdate(objectsProcessed, dataProcessed); + mainDialog->compareStatus.incProcessedCmpData_NoUpdate(objectsProcessed, dataProcessed); break; case StatusHandler::PROCESS_SYNCHRONIZING: case StatusHandler::PROCESS_NONE: @@ -102,7 +112,7 @@ ErrorHandler::Response CompareStatusHandler::reportError(const wxString& message if (ignoreErrors) return ErrorHandler::IGNORE_ERROR; - mainDialog->compareStatus->updateStatusPanelNow(); + mainDialog->compareStatus.updateStatusPanelNow(); bool ignoreNextErrors = false; const wxString errorMessage = message + wxT("\n\n\n") + _("Ignore this error, retry or abort?"); @@ -129,7 +139,7 @@ ErrorHandler::Response CompareStatusHandler::reportError(const wxString& message void CompareStatusHandler::reportFatalError(const wxString& errorMessage) { - mainDialog->compareStatus->updateStatusPanelNow(); + mainDialog->compareStatus.updateStatusPanelNow(); bool dummy = false; ErrorDlg* errorDlg = new ErrorDlg(mainDialog, @@ -145,7 +155,7 @@ void CompareStatusHandler::reportWarning(const wxString& warningMessage, bool& w if (!warningActive || ignoreErrors) //if errors are ignored, then warnings should also return; - mainDialog->compareStatus->updateStatusPanelNow(); + mainDialog->compareStatus.updateStatusPanelNow(); //show popup and ask user how to handle warning bool dontWarnAgain = false; @@ -169,7 +179,7 @@ void CompareStatusHandler::reportWarning(const wxString& warningMessage, bool& w inline void CompareStatusHandler::forceUiRefresh() { - mainDialog->compareStatus->updateStatusPanelNow(); + mainDialog->compareStatus.updateStatusPanelNow(); } @@ -182,66 +192,59 @@ void CompareStatusHandler::OnAbortCompare(wxCommandEvent& event) void CompareStatusHandler::abortThisProcess() { requestAbortion(); - throw FreeFileSync::AbortThisProcess(); //abort can be triggered by syncStatusFrame + throw FreeFileSync::AbortThisProcess(); } //######################################################################################################## SyncStatusHandler::SyncStatusHandler(wxWindow* dlg, bool ignoreAllErrors) : - ignoreErrors(ignoreAllErrors) -{ - syncStatusFrame = new SyncStatus(this, dlg); - syncStatusFrame->Show(); - updateUiNow(); -} + syncStatusFrame(*this, dlg, false), + ignoreErrors(ignoreAllErrors) {} SyncStatusHandler::~SyncStatusHandler() { - //print the results list - wxString result; - if (errorLog.messageCount() > 0) - { - if (errorLog.errorsTotal() > 0) - { - wxString header(_("Warning: Synchronization failed for %x item(s):")); - header.Replace(wxT("%x"), globalFunctions::numberToWxString(errorLog.errorsTotal()), false); - result += header + wxT("\n\n"); - } + const int totalErrors = errorLog.errorsTotal(); //evaluate before finalizing log - const std::vector<wxString>& messages = errorLog.getFormattedMessages(); - for (std::vector<wxString>::const_iterator i = messages.begin(); i != messages.end(); ++i) - { - result += *i; - result += wxChar('\n'); - } + //finalize error log + if (abortIsRequested()) + errorLog.logError(wxString(_("Synchronization aborted!")) + wxT(" ") + _("You may try to synchronize remaining items again (WITHOUT having to re-compare)!")); + else if (totalErrors) + errorLog.logWarning(wxString(_("Synchronization completed with errors!")) + wxT(" ") + _("You may try to synchronize remaining items again (WITHOUT having to re-compare)!")); + else + errorLog.logInfo(_("Synchronization completed successfully!")); - result += wxT("\n"); - } - //notify to syncStatusFrame that current process has ended - if (abortIsRequested()) + //print the results list + wxString finalMessage; + if (totalErrors > 0) { - result += wxString(_("Synchronization aborted!")) + wxT(" ") + _("You may try to synchronize remaining items again (WITHOUT having to re-compare)!"); - syncStatusFrame->processHasFinished(SyncStatus::ABORTED, result); //enable okay and close events + wxString header(_("Warning: Synchronization failed for %x item(s):")); + header.Replace(wxT("%x"), globalFunctions::numberToWxString(totalErrors), false); + finalMessage += header + wxT("\n\n"); } - else if (errorLog.errorsTotal() > 0) + + const ErrorLogging::MessageEntry& messages = errorLog.getFormattedMessages(); + for (ErrorLogging::MessageEntry::const_iterator i = messages.begin(); i != messages.end(); ++i) { - result += wxString(_("Synchronization completed with errors!")) + wxT(" ") + _("You may try to synchronize remaining items again (WITHOUT having to re-compare)!"); - syncStatusFrame->processHasFinished(SyncStatus::FINISHED_WITH_ERROR, result); + finalMessage += *i; + finalMessage += wxT("\n\n"); } + + //notify to syncStatusFrame that current process has ended + if (abortIsRequested()) + syncStatusFrame.processHasFinished(SyncStatus::ABORTED, finalMessage); //enable okay and close events + else if (totalErrors > 0) + syncStatusFrame.processHasFinished(SyncStatus::FINISHED_WITH_ERROR, finalMessage); else - { - result += _("Synchronization completed successfully!"); - syncStatusFrame->processHasFinished(SyncStatus::FINISHED_WITH_SUCCESS, result); - } + syncStatusFrame.processHasFinished(SyncStatus::FINISHED_WITH_SUCCESS, finalMessage); } inline void SyncStatusHandler::updateStatusText(const Zstring& text) { - syncStatusFrame->setStatusText_NoUpdate(text); + syncStatusFrame.setStatusText_NoUpdate(text); } @@ -250,8 +253,8 @@ void SyncStatusHandler::initNewProcess(int objectsTotal, wxLongLong dataTotal, P switch (processID) { case StatusHandler::PROCESS_SYNCHRONIZING: - syncStatusFrame->resetGauge(objectsTotal, dataTotal); - syncStatusFrame->setCurrentStatus(SyncStatus::SYNCHRONIZING); + syncStatusFrame.resetGauge(objectsTotal, dataTotal); + syncStatusFrame.setCurrentStatus(SyncStatus::SYNCHRONIZING); break; case StatusHandler::PROCESS_SCANNING: case StatusHandler::PROCESS_COMPARING_CONTENT: @@ -265,7 +268,7 @@ void SyncStatusHandler::initNewProcess(int objectsTotal, wxLongLong dataTotal, P inline void SyncStatusHandler::updateProcessedData(int objectsProcessed, wxLongLong dataProcessed) { - syncStatusFrame->incProgressIndicator_NoUpdate(objectsProcessed, dataProcessed); + syncStatusFrame.incProgressIndicator_NoUpdate(objectsProcessed, dataProcessed); } @@ -277,14 +280,17 @@ ErrorHandler::Response SyncStatusHandler::reportError(const wxString& errorMessa return ErrorHandler::IGNORE_ERROR; } - syncStatusFrame->updateStatusDialogNow(); + syncStatusFrame.updateStatusDialogNow(); bool ignoreNextErrors = false; - ErrorDlg* errorDlg = new ErrorDlg(syncStatusFrame, + ErrorDlg* errorDlg = new ErrorDlg(NULL, ErrorDlg::BUTTON_IGNORE | ErrorDlg::BUTTON_RETRY | ErrorDlg::BUTTON_ABORT, errorMessage + wxT("\n\n\n") + _("Ignore this error, retry or abort synchronization?"), ignoreNextErrors); - switch (static_cast<ErrorDlg::ReturnCodes>(errorDlg->ShowModal())) + const ErrorDlg::ReturnCodes rv = static_cast<ErrorDlg::ReturnCodes>(errorDlg->ShowModal()); + errorDlg->Destroy(); + + switch (rv) { case ErrorDlg::BUTTON_IGNORE: ignoreErrors = ignoreNextErrors; @@ -320,15 +326,18 @@ void SyncStatusHandler::reportWarning(const wxString& warningMessage, bool& warn return; else { - syncStatusFrame->updateStatusDialogNow(); + syncStatusFrame.updateStatusDialogNow(); //show popup and ask user how to handle warning bool dontWarnAgain = false; - WarningDlg* warningDlg = new WarningDlg(syncStatusFrame, + WarningDlg* warningDlg = new WarningDlg(NULL, WarningDlg::BUTTON_IGNORE | WarningDlg::BUTTON_ABORT, warningMessage, dontWarnAgain); - switch (static_cast<WarningDlg::Response>(warningDlg->ShowModal())) + const WarningDlg::Response rv = static_cast<WarningDlg::Response>(warningDlg->ShowModal()); + warningDlg->Destroy(); + + switch (rv) { case WarningDlg::BUTTON_IGNORE: //no unhandled error situation! warningActive = !dontWarnAgain; @@ -346,7 +355,7 @@ void SyncStatusHandler::reportWarning(const wxString& warningMessage, bool& warn void SyncStatusHandler::forceUiRefresh() { - syncStatusFrame->updateStatusDialogNow(); + syncStatusFrame.updateStatusDialogNow(); } diff --git a/ui/guiStatusHandler.h b/ui/guiStatusHandler.h index eb067102..cb64069a 100644 --- a/ui/guiStatusHandler.h +++ b/ui/guiStatusHandler.h @@ -1,9 +1,16 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// #ifndef GUISTATUSHANDLER_H_INCLUDED #define GUISTATUSHANDLER_H_INCLUDED #include "../library/statusHandler.h" #include <wx/event.h> #include "../library/errorLogging.h" +#include "progressIndicator.h" class SyncStatus; class MainDialog; @@ -55,7 +62,7 @@ public: private: virtual void abortThisProcess(); - SyncStatus* syncStatusFrame; + SyncStatus syncStatusFrame; //the window managed by SyncStatus has longer lifetime than this handler! bool ignoreErrors; FreeFileSync::ErrorLogging errorLog; }; diff --git a/ui/messagePopup.cpp b/ui/messagePopup.cpp new file mode 100644 index 00000000..fe051eed --- /dev/null +++ b/ui/messagePopup.cpp @@ -0,0 +1,180 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// +#include "messagePopup.h" +#include "../library/resources.h" + + +ErrorDlg::ErrorDlg(wxWindow* parentWindow, const int activeButtons, const wxString messageText, bool& ignoreNextErrors) : + ErrorDlgGenerated(parentWindow), + ignoreErrors(ignoreNextErrors) +{ + m_bitmap10->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("error"))); + m_textCtrl8->SetValue(messageText); + m_checkBoxIgnoreErrors->SetValue(ignoreNextErrors); + + if (~activeButtons & BUTTON_IGNORE) + { + m_buttonIgnore->Hide(); + m_checkBoxIgnoreErrors->Hide(); + } + + if (~activeButtons & BUTTON_RETRY) + m_buttonRetry->Hide(); + + if (~activeButtons & BUTTON_ABORT) + m_buttonAbort->Hide(); + + //set button focus precedence + if (activeButtons & BUTTON_RETRY) + m_buttonRetry->SetFocus(); + else if (activeButtons & BUTTON_IGNORE) + m_buttonIgnore->SetFocus(); + else if (activeButtons & BUTTON_ABORT) + m_buttonAbort->SetFocus(); +} + + +void ErrorDlg::OnClose(wxCloseEvent& event) +{ + ignoreErrors = m_checkBoxIgnoreErrors->GetValue(); + EndModal(BUTTON_ABORT); +} + + +void ErrorDlg::OnIgnore(wxCommandEvent& event) +{ + ignoreErrors = m_checkBoxIgnoreErrors->GetValue(); + EndModal(BUTTON_IGNORE); +} + + +void ErrorDlg::OnRetry(wxCommandEvent& event) +{ + ignoreErrors = m_checkBoxIgnoreErrors->GetValue(); + EndModal(BUTTON_RETRY); +} + + +void ErrorDlg::OnAbort(wxCommandEvent& event) +{ + ignoreErrors = m_checkBoxIgnoreErrors->GetValue(); + EndModal(BUTTON_ABORT); +} +//######################################################################################## + + +WarningDlg::WarningDlg(wxWindow* parentWindow, int activeButtons, const wxString messageText, bool& dontShowDlgAgain) : + WarningDlgGenerated(parentWindow), + dontShowAgain(dontShowDlgAgain) +{ + m_bitmap10->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("warning"))); + m_textCtrl8->SetValue(messageText); + m_checkBoxDontShowAgain->SetValue(dontShowAgain); + + if (~activeButtons & BUTTON_IGNORE) + { + m_buttonIgnore->Hide(); + m_checkBoxDontShowAgain->Hide(); + } + + if (~activeButtons & BUTTON_ABORT) + m_buttonAbort->Hide(); + + //set button focus precedence + if (activeButtons & BUTTON_IGNORE) + m_buttonIgnore->SetFocus(); + else if (activeButtons & BUTTON_ABORT) + m_buttonAbort->SetFocus(); +} + +WarningDlg::~WarningDlg() {} + + +void WarningDlg::OnClose(wxCloseEvent& event) +{ + dontShowAgain = m_checkBoxDontShowAgain->GetValue(); + EndModal(BUTTON_ABORT); +} + + +void WarningDlg::OnIgnore(wxCommandEvent& event) +{ + dontShowAgain = m_checkBoxDontShowAgain->GetValue(); + EndModal(BUTTON_IGNORE); +} + + +void WarningDlg::OnAbort(wxCommandEvent& event) +{ + dontShowAgain = m_checkBoxDontShowAgain->GetValue(); + EndModal(BUTTON_ABORT); +} +//######################################################################################## + + +QuestionDlg::QuestionDlg(wxWindow* parentWindow, int activeButtons, const wxString messageText, bool* dontShowDlgAgain) : + QuestionDlgGenerated(parentWindow), + dontShowAgain(dontShowDlgAgain) +{ + m_bitmap10->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("question"))); + m_textCtrl8->SetValue(messageText); + if (dontShowAgain) + m_checkBoxDontAskAgain->SetValue(*dontShowAgain); + else + m_checkBoxDontAskAgain->Hide(); + + if (~activeButtons & BUTTON_YES) + m_buttonYes->Hide(); + + if (~activeButtons & BUTTON_NO) + { + m_buttonNo->Hide(); + m_checkBoxDontAskAgain->Hide(); + } + + if (~activeButtons & BUTTON_CANCEL) + m_buttonCancel->Hide(); + + //set button focus precedence + if (activeButtons & BUTTON_YES) + m_buttonYes->SetFocus(); + else if (activeButtons & BUTTON_CANCEL) + m_buttonCancel->SetFocus(); + else if (activeButtons & BUTTON_NO) + m_buttonNo->SetFocus(); +} + + +void QuestionDlg::OnClose(wxCloseEvent& event) +{ + if (dontShowAgain) + *dontShowAgain = m_checkBoxDontAskAgain->GetValue(); + EndModal(BUTTON_CANCEL); +} + + +void QuestionDlg::OnCancel(wxCommandEvent& event) +{ + if (dontShowAgain) + *dontShowAgain = m_checkBoxDontAskAgain->GetValue(); + EndModal(BUTTON_CANCEL); +} + + +void QuestionDlg::OnYes(wxCommandEvent& event) +{ + if (dontShowAgain) + *dontShowAgain = m_checkBoxDontAskAgain->GetValue(); + EndModal(BUTTON_YES); +} + +void QuestionDlg::OnNo(wxCommandEvent& event) +{ + if (dontShowAgain) + *dontShowAgain = m_checkBoxDontAskAgain->GetValue(); + EndModal(BUTTON_NO); +} diff --git a/ui/messagePopup.h b/ui/messagePopup.h new file mode 100644 index 00000000..e1fa58fb --- /dev/null +++ b/ui/messagePopup.h @@ -0,0 +1,80 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// +#ifndef MESSAGEPOPUP_H_INCLUDED +#define MESSAGEPOPUP_H_INCLUDED + +#include "guiGenerated.h" + + +class ErrorDlg : public ErrorDlgGenerated +{ +public: + ErrorDlg(wxWindow* parentWindow, const int activeButtons, const wxString messageText, bool& ignoreNextErrors); + + enum ReturnCodes + { + BUTTON_IGNORE = 1, + BUTTON_RETRY = 2, + BUTTON_ABORT = 4 + }; + +private: + void OnClose(wxCloseEvent& event); + void OnIgnore(wxCommandEvent& event); + void OnRetry(wxCommandEvent& event); + void OnAbort(wxCommandEvent& event); + + bool& ignoreErrors; +}; + + +class WarningDlg : public WarningDlgGenerated +{ +public: + WarningDlg(wxWindow* parentWindow, int activeButtons, const wxString messageText, bool& dontShowAgain); + ~WarningDlg(); + + enum Response + { + BUTTON_IGNORE = 1, + BUTTON_ABORT = 2 + }; + +private: + void OnClose(wxCloseEvent& event); + void OnIgnore(wxCommandEvent& event); + void OnResolve(wxCommandEvent& event); + void OnAbort(wxCommandEvent& event); + void OnOkay(wxCommandEvent& event); + + bool& dontShowAgain; +}; + + +class QuestionDlg : public QuestionDlgGenerated +{ +public: + QuestionDlg(wxWindow* parentWindow, int activeButtons, const wxString messageText, bool* dontShowAgain = NULL); + + enum + { + BUTTON_YES = 1, + BUTTON_NO = 2, + BUTTON_CANCEL = 4 + }; + +private: + void OnClose(wxCloseEvent& event); + void OnCancel(wxCommandEvent& event); + void OnYes(wxCommandEvent& event); + void OnNo(wxCommandEvent& event); + + bool* dontShowAgain; //optional +}; + + +#endif // MESSAGEPOPUP_H_INCLUDED diff --git a/ui/mouseMoveWindow.cpp b/ui/mouseMoveWindow.cpp new file mode 100644 index 00000000..86064141 --- /dev/null +++ b/ui/mouseMoveWindow.cpp @@ -0,0 +1,26 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// +#include "mouseMoveWindow.h" +#include <wx/msw/wrapwin.h> //includes "windows.h" + +using namespace FreeFileSync; + + +void MouseMoveWindow::connectSourceWindow(wxWindow* sourceWindow) +{ + sourceWindow->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(MouseMoveWindow::LeftButtonDown), NULL, this); +} + + +void MouseMoveWindow::LeftButtonDown(wxMouseEvent& event) +{ + ::ReleaseCapture(); + //::SendMessage(GetHwndOf(dialogToMove_), WM_NCLBUTTONDOWN, HTCAPTION, 0); + ::SendMessage(static_cast<HWND>(dialogToMove_->GetHWND()), WM_NCLBUTTONDOWN, HTCAPTION, 0); + + //event.Skip(); -> swallow event, to avoid other windows losing focus +} diff --git a/ui/mouseMoveWindow.h b/ui/mouseMoveWindow.h new file mode 100644 index 00000000..bc7ee904 --- /dev/null +++ b/ui/mouseMoveWindow.h @@ -0,0 +1,36 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// +#ifndef MOUSEMOVEWINDOW_H_INCLUDED +#define MOUSEMOVEWINDOW_H_INCLUDED + +#include <wx/window.h> + +namespace FreeFileSync +{ + +//move main dialog by mouse-dragging contained sub-windows: +//---------------------------------------------------------------------------------------- +//keep it as an attribute of the to-be-moved dialog and ensure that all connected source windows +//have a longer lifetime than the dialog which is moved (should be fulfilled naturally) +class MouseMoveWindow : private wxEvtHandler +{ +public: + MouseMoveWindow(wxWindow* dialogToMove) : + dialogToMove_(dialogToMove) {} + + void connectSourceWindow(wxWindow* sourceWindow); + +private: + void LeftButtonDown(wxMouseEvent& event); + + wxWindow* dialogToMove_; +}; + +} + + +#endif // MOUSEMOVEWINDOW_H_INCLUDED diff --git a/ui/progressIndicator.cpp b/ui/progressIndicator.cpp new file mode 100644 index 00000000..1ba70888 --- /dev/null +++ b/ui/progressIndicator.cpp @@ -0,0 +1,773 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// +#include "progressIndicator.h" +#include <memory> +#include "guiGenerated.h" +#include <wx/stopwatch.h> +#include "../library/resources.h" +#include "../shared/stringConv.h" +#include "util.h" +#include "../library/statistics.h" +#include "../library/statusHandler.h" +#include <wx/wupdlock.h> +#include "../shared/globalFunctions.h" +#include "trayIcon.h" +#include <boost/shared_ptr.hpp> + +using namespace FreeFileSync; + + +class CompareStatusImpl : public CompareStatusGenerated +{ +public: + CompareStatusImpl(wxWindow& parentWindow); + + void init(); //initialize all status values + + void switchToCompareBytewise(int totalObjectsToProcess, wxLongLong totalDataToProcess); + void incScannedObjects_NoUpdate(int number); + void incProcessedCmpData_NoUpdate(int objectsProcessed, wxLongLong dataProcessed); + void setStatusText_NoUpdate(const Zstring& text); + void updateStatusPanelNow(); + +private: + //status variables + unsigned int scannedObjects; + Zstring currentStatusText; + + wxStopWatch timeElapsed; + + //gauge variables + int totalObjects; + wxLongLong totalData; //each data element represents one byte for proper progress indicator scaling + int currentObjects; //each object represents a file or directory processed + wxLongLong currentData; + double scalingFactor; //nr of elements has to be normalized to smaller nr. because of range of int limitation + + //remaining time + std::auto_ptr<Statistics> statistics; + long lastStatCallSpeed; //used for calculating intervals between statistics update + long lastStatCallRemTime; // +}; + +//redirect to implementation +CompareStatus::CompareStatus(wxWindow& parentWindow) : + pimpl(new CompareStatusImpl(parentWindow)) {} + +CompareStatus::~CompareStatus() +{ + //DON'T delete pimpl! it relies on wxWidgets destruction (parent window destroys child windows!) +} + +wxWindow* CompareStatus::getAsWindow() +{ + return pimpl; +} + +void CompareStatus::init() +{ + pimpl->init(); +} + +void CompareStatus::switchToCompareBytewise(int totalObjectsToProcess, wxLongLong totalDataToProcess) +{ + pimpl->switchToCompareBytewise(totalObjectsToProcess, totalDataToProcess); +} + +void CompareStatus::incScannedObjects_NoUpdate(int number) +{ + pimpl->incScannedObjects_NoUpdate(number); +} + +void CompareStatus::incProcessedCmpData_NoUpdate(int objectsProcessed, wxLongLong dataProcessed) +{ + pimpl->incProcessedCmpData_NoUpdate(objectsProcessed, dataProcessed); +} + +void CompareStatus::setStatusText_NoUpdate(const Zstring& text) +{ + pimpl->setStatusText_NoUpdate(text); +} + +void CompareStatus::updateStatusPanelNow() +{ + pimpl->updateStatusPanelNow(); +} +//######################################################################################## + + +CompareStatusImpl::CompareStatusImpl(wxWindow& parentWindow) : + CompareStatusGenerated(&parentWindow), + scannedObjects(0), + totalObjects(0), + totalData(0), + currentObjects(0), + currentData(0), + scalingFactor(0), + statistics(NULL), + lastStatCallSpeed(-1000000), //some big number + lastStatCallRemTime(-1000000) +{ + init(); +} + + +void CompareStatusImpl::init() +{ + //initialize gauge + m_gauge2->SetRange(50000); + m_gauge2->SetValue(0); + + //initially hide status that's relevant for comparing bytewise only + bSizer42->Hide(sbSizer13); + m_gauge2->Hide(); + bSizer42->Layout(); + + scannedObjects = 0; + currentStatusText.clear(); + + totalObjects = 0; + totalData = 0; + currentObjects = 0; + currentData = 0; + scalingFactor = 0; + + statistics.reset(); + + timeElapsed.Start(); //measure total time + + updateStatusPanelNow(); +} + + +void CompareStatusImpl::switchToCompareBytewise(int totalObjectsToProcess, wxLongLong totalDataToProcess) +{ + currentData = 0; + totalData = totalDataToProcess; + + currentObjects = 0; + totalObjects = totalObjectsToProcess; + + if (totalData != 0) + scalingFactor = 50000 / totalData.ToDouble(); //let's normalize to 50000 + else + scalingFactor = 0; + + //set new statistics handler: 10 seconds "window" for remaining time, 5 seconds for speed + statistics.reset(new Statistics(totalObjectsToProcess, totalDataToProcess.ToDouble(), 10000, 5000)); + lastStatCallSpeed = -1000000; //some big number + lastStatCallRemTime = -1000000; + + //show status for comparing bytewise + bSizer42->Show(sbSizer13); + m_gauge2->Show(); + bSizer42->Layout(); +} + + +void CompareStatusImpl::incScannedObjects_NoUpdate(int number) +{ + scannedObjects += number; +} + + +void CompareStatusImpl::incProcessedCmpData_NoUpdate(int objectsProcessed, wxLongLong dataProcessed) +{ + currentData += dataProcessed; + currentObjects += objectsProcessed; +} + + +void CompareStatusImpl::setStatusText_NoUpdate(const Zstring& text) +{ + currentStatusText = text; +} + + +void CompareStatusImpl::updateStatusPanelNow() +{ + //static RetrieveStatistics statistic; + //statistic.writeEntry(currentData, currentObjects); + { + wxWindowUpdateLocker dummy(this); //reduce display distortion + + bool screenChanged = false; //avoid screen flicker by calling layout() only if necessary + + //remove linebreaks from currentStatusText + wxString formattedStatusText = zToWx(currentStatusText); + for (wxString::iterator i = formattedStatusText.begin(); i != formattedStatusText.end(); ++i) + if (*i == wxChar('\n')) + *i = wxChar(' '); + + //status texts + if (m_textCtrlStatus->GetValue() != formattedStatusText && (screenChanged = true)) //avoid screen flicker + m_textCtrlStatus->SetValue(formattedStatusText); + + //nr of scanned objects + const wxString scannedObjTmp = globalFunctions::numberToWxString(scannedObjects); + if (m_staticTextScanned->GetLabel() != scannedObjTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextScanned->SetLabel(scannedObjTmp); + + //progress indicator for "compare file content" + m_gauge2->SetValue(int(currentData.ToDouble() * scalingFactor)); + + //remaining files left for file comparison + const wxString filesToCompareTmp = globalFunctions::numberToWxString(totalObjects - currentObjects); + if (m_staticTextFilesRemaining->GetLabel() != filesToCompareTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextFilesRemaining->SetLabel(filesToCompareTmp); + + //remaining bytes left for file comparison + const wxString remainingBytesTmp = FreeFileSync::formatFilesizeToShortString(totalData - currentData); + if (m_staticTextDataRemaining->GetLabel() != remainingBytesTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextDataRemaining->SetLabel(remainingBytesTmp); + + if (statistics.get()) + { + if (timeElapsed.Time() - lastStatCallSpeed >= 500) //call method every 500 ms + { + lastStatCallSpeed = timeElapsed.Time(); + + statistics->addMeasurement(currentObjects, currentData.ToDouble()); + + //current speed + const wxString speedTmp = statistics->getBytesPerSecond(); + if (m_staticTextSpeed->GetLabel() != speedTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextSpeed->SetLabel(speedTmp); + + if (timeElapsed.Time() - lastStatCallRemTime >= 2000) //call method every two seconds only + { + lastStatCallRemTime = timeElapsed.Time(); + + //remaining time + const wxString timeRemainingTmp = statistics->getRemainingTime(); + if (m_staticTextTimeRemaining->GetLabel() != timeRemainingTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextTimeRemaining->SetLabel(timeRemainingTmp); + } + } + } + + //time elapsed + const wxString timeElapsedTmp = (wxTimeSpan::Milliseconds(timeElapsed.Time())).Format(); + if (m_staticTextTimeElapsed->GetLabel() != timeElapsedTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextTimeElapsed->SetLabel(timeElapsedTmp); + + //do the ui update + if (screenChanged) + bSizer42->Layout(); + } + updateUiNow(); +} +//######################################################################################## + + +class SyncStatusImpl : public SyncStatusDlgGenerated +{ +public: + SyncStatusImpl(StatusHandler& updater, wxWindow* parentWindow); + ~SyncStatusImpl(); + + void resetGauge(int totalObjectsToProcess, wxLongLong totalDataToProcess); + void incProgressIndicator_NoUpdate(int objectsProcessed, wxLongLong dataProcessed); + void setStatusText_NoUpdate(const Zstring& text); + void updateStatusDialogNow(); + + void setCurrentStatus(SyncStatus::SyncStatusID id); + void processHasFinished(SyncStatus::SyncStatusID id, const wxString& finalMessage); //essential to call this in StatusUpdater derived class destructor at the LATEST(!) to prevent access to currentStatusUpdater + + void minimizeToTray(); + +private: + void OnKeyPressed(wxKeyEvent& event); + virtual void OnOkay(wxCommandEvent& event); + virtual void OnPause(wxCommandEvent& event); + virtual void OnAbort(wxCommandEvent& event); + virtual void OnClose(wxCloseEvent& event); + virtual void OnIconize(wxIconizeEvent& event); + + void resumeFromSystray(); + bool currentProcessIsRunning(); + + wxStopWatch timeElapsed; + + StatusHandler* processStatusHandler; + wxWindow* mainDialog; + + //gauge variables + int totalObjects; + wxLongLong totalData; + int currentObjects; //each object represents a file or directory processed + wxLongLong currentData; //each data element represents one byte for proper progress indicator scaling + double scalingFactor; //nr of elements has to be normalized to smaller nr. because of range of int limitation + + Zstring currentStatusText; + bool processPaused; + SyncStatus::SyncStatusID currentStatus; + + //remaining time + std::auto_ptr<Statistics> statistics; + long lastStatCallSpeed; //used for calculating intervals between statistics update + long lastStatCallRemTime; // + + boost::shared_ptr<MinimizeToTray> minimizedToSysTray; //optional: if filled, hides all visible windows, shows again if destroyed +}; + + +//redirect to implementation +SyncStatus::SyncStatus(StatusHandler& updater, wxWindow* parentWindow, bool startSilent) : + pimpl(new SyncStatusImpl(updater, parentWindow)) +{ + if (startSilent) + pimpl->minimizeToTray(); + else + { + pimpl->Show(); + pimpl->updateStatusDialogNow(); //update visual statistics to get rid of "dummy" texts + } +} + +SyncStatus::~SyncStatus() +{ + //DON'T delete pimpl! it will be deleted by the user clicking "OK/Cancel" -> (wxWindow::Destroy()) +} + +wxWindow* SyncStatus::getAsWindow() +{ + return pimpl; +} + +void SyncStatus::closeWindowDirectly() //don't wait for user (silent mode) +{ + pimpl->Destroy(); +} + +void SyncStatus::resetGauge(int totalObjectsToProcess, wxLongLong totalDataToProcess) +{ + pimpl->resetGauge(totalObjectsToProcess, totalDataToProcess); +} + +void SyncStatus::incProgressIndicator_NoUpdate(int objectsProcessed, wxLongLong dataProcessed) +{ + pimpl->incProgressIndicator_NoUpdate(objectsProcessed, dataProcessed); +} + +void SyncStatus::setStatusText_NoUpdate(const Zstring& text) +{ + pimpl->setStatusText_NoUpdate(text); +} + +void SyncStatus::updateStatusDialogNow() +{ + pimpl->updateStatusDialogNow(); +} + +void SyncStatus::setCurrentStatus(SyncStatusID id) +{ + pimpl->setCurrentStatus(id); +} + +void SyncStatus::processHasFinished(SyncStatusID id, const wxString& finalMessage) +{ + pimpl->processHasFinished(id, finalMessage); +} +//######################################################################################## + + +SyncStatusImpl::SyncStatusImpl(StatusHandler& updater, wxWindow* parentWindow) : + SyncStatusDlgGenerated(parentWindow, + wxID_ANY, + parentWindow ? wxEmptyString : _("FreeFileSync - Folder Comparison and Synchronization"), + wxDefaultPosition, wxSize(638, 376), + parentWindow ? + wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT : + wxDEFAULT_FRAME_STYLE | wxTAB_TRAVERSAL), + processStatusHandler(&updater), + mainDialog(parentWindow), + totalObjects(0), + totalData(0), + currentObjects(0), + currentData(0), + scalingFactor(0), + processPaused(false), + currentStatus(SyncStatus::ABORTED), + statistics(NULL), + lastStatCallSpeed(-1000000), //some big number + lastStatCallRemTime(-1000000) +{ + m_animationControl1->SetAnimation(*GlobalResources::getInstance().animationSync); + m_animationControl1->Play(); + + m_staticTextSpeed->SetLabel(wxT("-")); + m_staticTextTimeRemaining->SetLabel(wxT("-")); + + //initialize gauge + m_gauge1->SetRange(50000); + m_gauge1->SetValue(0); + + m_buttonAbort->SetFocus(); + + if (mainDialog) //disable (main) window while this status dialog is shown + mainDialog->Disable(); + + timeElapsed.Start(); //measure total time + + //hide "processed" statistics until end of process + bSizerObjectsProcessed->Show(false); + bSizerDataProcessed->Show(false); + + + SetIcon(*GlobalResources::getInstance().programIcon); //set application icon + + //register key event + Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(SyncStatusImpl::OnKeyPressed), NULL, this); +} + + +SyncStatusImpl::~SyncStatusImpl() +{ + if (mainDialog) + { + mainDialog->Enable(); + mainDialog->Raise(); + mainDialog->SetFocus(); + } + + if (minimizedToSysTray.get()) + minimizedToSysTray->keepHidden(); //avoid window flashing shortly before it is destroyed +} + + +void SyncStatusImpl::OnKeyPressed(wxKeyEvent& event) +{ + const int keyCode = event.GetKeyCode(); + if (keyCode == WXK_ESCAPE) + Close(); //generate close event: do NOT destroy window unconditionally! + + event.Skip(); +} + + +void SyncStatusImpl::resetGauge(int totalObjectsToProcess, wxLongLong totalDataToProcess) +{ + currentData = 0; + totalData = totalDataToProcess; + + currentObjects = 0; + totalObjects = totalObjectsToProcess; + + if (totalData != 0) + scalingFactor = 50000 / totalData.ToDouble(); //let's normalize to 50000 + else + scalingFactor = 0; + + //set new statistics handler: 10 seconds "window" for remaining time, 5 seconds for speed + statistics.reset(new Statistics(totalObjectsToProcess, totalDataToProcess.ToDouble(), 10000, 5000)); + lastStatCallSpeed = -1000000; //some big number + lastStatCallRemTime = -1000000; +} + + +void SyncStatusImpl::incProgressIndicator_NoUpdate(int objectsProcessed, wxLongLong dataProcessed) +{ + currentData += dataProcessed; + currentObjects += objectsProcessed; +} + + +void SyncStatusImpl::setStatusText_NoUpdate(const Zstring& text) +{ + currentStatusText = text; +} + + +void SyncStatusImpl::updateStatusDialogNow() +{ + //static RetrieveStatistics statistic; + //statistic.writeEntry(currentData, currentObjects); + + //write status information to systray, if window is minimized + if (minimizedToSysTray.get()) + switch (currentStatus) + { + case SyncStatus::SCANNING: + minimizedToSysTray->setToolTip(wxString(wxT("FreeFileSync - ")) + wxString(_("Scanning..."))); + //+ wxT(" ") + globalFunctions::numberToWxString(currentObjects)); + break; + case SyncStatus::COMPARING_CONTENT: + minimizedToSysTray->setToolTip(wxString(wxT("FreeFileSync - ")) + wxString(_("Comparing content...")) + wxT(" ") + + formatPercentage(currentData, totalData), currentData.ToDouble() * 100 / totalData.ToDouble()); + break; + case SyncStatus::SYNCHRONIZING: + minimizedToSysTray->setToolTip(wxString(wxT("FreeFileSync - ")) + wxString(_("Synchronizing...")) + wxT(" ") + + formatPercentage(currentData, totalData), currentData.ToDouble() * 100 / totalData.ToDouble()); + break; + case SyncStatus::ABORTED: + case SyncStatus::FINISHED_WITH_SUCCESS: + case SyncStatus::FINISHED_WITH_ERROR: + case SyncStatus::PAUSE: + minimizedToSysTray->setToolTip(wxT("FreeFileSync")); + } + + //write regular status information (if dialog is visible or not) + { + wxWindowUpdateLocker dummy(this); //reduce display distortion + + bool screenChanged = false; //avoid screen flicker by calling layout() only if necessary + + //progress indicator + if (currentStatus == SyncStatus::SCANNING) + m_gauge1->Pulse(); + else + m_gauge1->SetValue(globalFunctions::round(currentData.ToDouble() * scalingFactor)); + + //status text + const wxString statusTxt = zToWx(currentStatusText); + if (m_textCtrlInfo->GetValue() != statusTxt && (screenChanged = true)) //avoid screen flicker + m_textCtrlInfo->SetValue(statusTxt); + + //remaining objects + const wxString remainingObjTmp = globalFunctions::numberToWxString(totalObjects - currentObjects); + if (m_staticTextRemainingObj->GetLabel() != remainingObjTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextRemainingObj->SetLabel(remainingObjTmp); + + //remaining bytes left for copy + const wxString remainingBytesTmp = FreeFileSync::formatFilesizeToShortString(totalData - currentData); + if (m_staticTextDataRemaining->GetLabel() != remainingBytesTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextDataRemaining->SetLabel(remainingBytesTmp); + + if (statistics.get()) + { + if (timeElapsed.Time() - lastStatCallSpeed >= 500) //call method every 500 ms + { + lastStatCallSpeed = timeElapsed.Time(); + + statistics->addMeasurement(currentObjects, currentData.ToDouble()); + + //current speed + const wxString speedTmp = statistics->getBytesPerSecond(); + if (m_staticTextSpeed->GetLabel() != speedTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextSpeed->SetLabel(speedTmp); + + if (timeElapsed.Time() - lastStatCallRemTime >= 2000) //call method every two seconds only + { + lastStatCallRemTime = timeElapsed.Time(); + + //remaining time + const wxString timeRemainingTmp = statistics->getRemainingTime(); + if (m_staticTextTimeRemaining->GetLabel() != timeRemainingTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextTimeRemaining->SetLabel(timeRemainingTmp); + } + } + } + + //time elapsed + const wxString timeElapsedTmp = wxTimeSpan::Milliseconds(timeElapsed.Time()).Format(); + if (m_staticTextTimeElapsed->GetLabel() != timeElapsedTmp && (screenChanged = true)) //avoid screen flicker + m_staticTextTimeElapsed->SetLabel(timeElapsedTmp); + + + //do the ui update + if (screenChanged) + { + bSizer28->Layout(); + bSizer31->Layout(); + } + } + updateUiNow(); + +//support for pause button + while (processPaused && currentProcessIsRunning()) + { + wxMilliSleep(UI_UPDATE_INTERVAL); + updateUiNow(); + } +} + + +bool SyncStatusImpl::currentProcessIsRunning() +{ + return processStatusHandler != NULL; +} + + +void SyncStatusImpl::setCurrentStatus(SyncStatus::SyncStatusID id) +{ + switch (id) + { + case SyncStatus::ABORTED: + m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusError"))); + m_staticTextStatus->SetLabel(_("Aborted")); + break; + + case SyncStatus::FINISHED_WITH_SUCCESS: + m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusSuccess"))); + m_staticTextStatus->SetLabel(_("Completed")); + break; + + case SyncStatus::FINISHED_WITH_ERROR: + m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusWarning"))); + m_staticTextStatus->SetLabel(_("Completed")); + break; + + case SyncStatus::PAUSE: + m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusPause"))); + m_staticTextStatus->SetLabel(_("Paused")); + break; + + case SyncStatus::SCANNING: + m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusScanning"))); + m_staticTextStatus->SetLabel(_("Scanning...")); + break; + + case SyncStatus::COMPARING_CONTENT: + m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusBinaryCompare"))); + m_staticTextStatus->SetLabel(_("Comparing content...")); + break; + + case SyncStatus::SYNCHRONIZING: + m_bitmapStatus->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("statusSyncing"))); + m_staticTextStatus->SetLabel(_("Synchronizing...")); + break; + } + + currentStatus = id; + Layout(); +} + + +void SyncStatusImpl::processHasFinished(SyncStatus::SyncStatusID id, const wxString& finalMessage) //essential to call this in StatusHandler derived class destructor +{ + //at the LATEST(!) to prevent access to currentStatusHandler + //enable okay and close events; may be set in this method ONLY + + processStatusHandler = NULL; //avoid callback to (maybe) deleted parent process + + setCurrentStatus(id); + + resumeFromSystray(); //if in tray mode... + + m_buttonAbort->Disable(); + m_buttonAbort->Hide(); + m_buttonPause->Disable(); + m_buttonPause->Hide(); + m_buttonOK->Show(); + m_buttonOK->SetFocus(); + + m_animationControl1->Stop(); + m_animationControl1->Hide(); + + //hide speed and remaining time + bSizerSpeed ->Show(false); + bSizerRemTime->Show(false); + + //if everything was processed successfully, hide remaining statistics (is 0 anyway) + if ( totalObjects == currentObjects && + totalData == currentData) + { + bSizerObjectsRemaining->Show(false); + bSizerDataRemaining ->Show(false); + + //show processed statistics at the end (but only if there was some work to be done) + if (totalObjects != 0 || totalData != 0) + { + bSizerObjectsProcessed->Show(true); + bSizerDataProcessed ->Show(true); + + m_staticTextProcessedObj->SetLabel(globalFunctions::numberToWxString(currentObjects)); + m_staticTextDataProcessed->SetLabel(FreeFileSync::formatFilesizeToShortString(currentData)); + } + } + + updateStatusDialogNow(); //keep this sequence to avoid display distortion, if e.g. only 1 item is sync'ed + m_textCtrlInfo->SetValue(finalMessage); // + Layout(); // +} + + +void SyncStatusImpl::OnOkay(wxCommandEvent& event) +{ + if (!currentProcessIsRunning()) Destroy(); +} + + +void SyncStatusImpl::OnPause(wxCommandEvent& event) +{ + static SyncStatus::SyncStatusID previousStatus = SyncStatus::ABORTED; + + if (processPaused) + { + setCurrentStatus(previousStatus); + processPaused = false; + m_buttonPause->SetLabel(_("Pause")); + m_animationControl1->Play(); + + //resume timers + timeElapsed.Resume(); + if (statistics.get()) + statistics->resumeTimer(); + } + else + { + previousStatus = currentStatus; //save current status + + setCurrentStatus(SyncStatus::PAUSE); + processPaused = true; + m_buttonPause->SetLabel(_("Continue")); + m_animationControl1->Stop(); + + //pause timers + timeElapsed.Pause(); + if (statistics.get()) + statistics->pauseTimer(); + } +} + + +void SyncStatusImpl::OnAbort(wxCommandEvent& event) +{ + processPaused = false; + if (currentProcessIsRunning()) + { + m_buttonAbort->Disable(); + m_buttonAbort->Hide(); + m_buttonPause->Disable(); + m_buttonPause->Hide(); + + setStatusText_NoUpdate(wxToZ(_("Abort requested: Waiting for current operation to finish..."))); + //no Layout() or UI-update here to avoid cascaded Yield()-call + + processStatusHandler->requestAbortion(); + } +} + + +void SyncStatusImpl::OnClose(wxCloseEvent& event) +{ + processPaused = false; + if (processStatusHandler) + processStatusHandler->requestAbortion(); + else + Destroy(); +} + + +void SyncStatusImpl::OnIconize(wxIconizeEvent& event) +{ + if (event.Iconized()) //ATTENTION: iconize event is also triggered on "Restore"! (at least under Linux) + minimizeToTray(); +} + + +void SyncStatusImpl::minimizeToTray() +{ + minimizedToSysTray.reset(new MinimizeToTray(this, mainDialog)); +} + + +void SyncStatusImpl::resumeFromSystray() +{ + minimizedToSysTray.reset(); +} diff --git a/ui/progressIndicator.h b/ui/progressIndicator.h new file mode 100644 index 00000000..78044653 --- /dev/null +++ b/ui/progressIndicator.h @@ -0,0 +1,76 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// +#ifndef PROGRESSINDICATOR_H_INCLUDED +#define PROGRESSINDICATOR_H_INCLUDED + +#include "../shared/zstring.h" +#include <wx/window.h> + +class CompareStatusImpl; +class SyncStatusImpl; +class StatusHandler; + + +class CompareStatus +{ +public: + CompareStatus(wxWindow& parentWindow); //CompareStatus will be owned by parentWindow! + ~CompareStatus(); + + wxWindow* getAsWindow(); //convenience! don't abuse! + + void init(); //initialize all status values + + void switchToCompareBytewise(int totalObjectsToProcess, wxLongLong totalDataToProcess); + void incScannedObjects_NoUpdate(int number); + void incProcessedCmpData_NoUpdate(int objectsProcessed, wxLongLong dataProcessed); + void setStatusText_NoUpdate(const Zstring& text); + void updateStatusPanelNow(); + +private: + CompareStatusImpl* const pimpl; +}; + + +class SyncStatus +{ +public: + SyncStatus(StatusHandler& updater, + wxWindow* parentWindow, //may be NULL + bool startSilent); + ~SyncStatus(); + + wxWindow* getAsWindow(); //convenience! don't abuse! + + enum SyncStatusID + { + ABORTED, + FINISHED_WITH_SUCCESS, + FINISHED_WITH_ERROR, + PAUSE, + SCANNING, + COMPARING_CONTENT, + SYNCHRONIZING + }; + + void resetGauge(int totalObjectsToProcess, wxLongLong totalDataToProcess); + void incProgressIndicator_NoUpdate(int objectsProcessed, wxLongLong dataProcessed); + void setStatusText_NoUpdate(const Zstring& text); + void updateStatusDialogNow(); + + void setCurrentStatus(SyncStatusID id); + + //essential to call one of these two methods in StatusUpdater derived class destructor at the LATEST(!) + //to prevent access to callback to updater (e.g. request abort) + void processHasFinished(SyncStatusID id, const wxString& finalMessage); + void closeWindowDirectly(); //don't wait for user + +private: + SyncStatusImpl* const pimpl; +}; + +#endif // PROGRESSINDICATOR_H_INCLUDED diff --git a/ui/search.cpp b/ui/search.cpp new file mode 100644 index 00000000..494be608 --- /dev/null +++ b/ui/search.cpp @@ -0,0 +1,264 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// +#include "search.h" +#include "guiGenerated.h" +#include <wx/msgdlg.h> +#include <wx/utils.h> + + +class SearchDlg : public SearchDialogGenerated +{ +public: + SearchDlg(wxWindow& parentWindow, wxString& searchText, bool& respectCase); + + enum ReturnCodes + { + BUTTON_OKAY = 1 //mustn't be 0 + }; + +private: + void OnClose(wxCloseEvent& event); + void OnCancel(wxCommandEvent& event); + void OnFindNext(wxCommandEvent& event); + void OnText(wxCommandEvent& event); + + wxString& searchText_; + bool& respectCase_; +}; + + +SearchDlg::SearchDlg(wxWindow& parentWindow, wxString& searchText, bool& respectCase) : + SearchDialogGenerated(&parentWindow), + searchText_(searchText), + respectCase_(respectCase) +{ + m_checkBoxMatchCase->SetValue(respectCase_); + m_textCtrlSearchTxt->SetValue(searchText_); + + CentreOnParent(); //this requires a parent window! +} + + +void SearchDlg::OnClose(wxCloseEvent& event) +{ + EndModal(0); +} + + +void SearchDlg::OnCancel(wxCommandEvent& event) +{ + EndModal(0); +} + + +void SearchDlg::OnFindNext(wxCommandEvent& event) +{ + respectCase_ = m_checkBoxMatchCase->GetValue(); + searchText_ = m_textCtrlSearchTxt->GetValue(); + EndModal(BUTTON_OKAY); +} + + +void SearchDlg::OnText(wxCommandEvent& event) +{ + if (m_textCtrlSearchTxt->GetValue().Trim().IsEmpty()) + m_buttonFindNext->Disable(); + else + m_buttonFindNext->Enable(); + + event.Skip(); +} +//########################################################################################### + + +template <bool respectCase> +class FindInText +{ +public: + FindInText(const wxString& textToFind); + bool found(const wxString& phrase) const; + +private: + wxString textToFind_; +}; + + +template <> +FindInText<true>::FindInText(const wxString& textToFind) : + textToFind_(textToFind) {} + + +template <> +inline +bool FindInText<true>::found(const wxString& phrase) const +{ + return phrase.Find(textToFind_) != wxNOT_FOUND; +} + + +template <> +FindInText<false>::FindInText(const wxString& textToFind) : + textToFind_(textToFind) +{ + textToFind_.MakeUpper(); +} + + +template <> +inline +bool FindInText<false>::found(const wxString& phrase) const +{ + wxString phraseTmp = phrase; //wxWidgets::MakeUpper() is inefficient! + phraseTmp.MakeUpper(); //But performance is not THAT important for this high-level search functionality + return phraseTmp.Find(textToFind_) != wxNOT_FOUND; +} +//########################################################################################### + + +template <bool respectCase> +std::pair<int, int> searchGrid(const wxGrid& grid, + const wxString& searchString, + bool fromBeginToCursor, //specify area to search + bool afterCursorToEnd) // +{ + const int rowCount = const_cast<wxGrid&>(grid).GetNumberRows(); + const int columnCount = const_cast<wxGrid&>(grid).GetNumberCols(); + + //consistency checks on ints: wxGrid uses ints, so we have to use them, too + if (rowCount <= 0 || columnCount <= 0) + return std::make_pair(-1, -1); + + int cursorRow = const_cast<wxGrid&>(grid).GetGridCursorRow(); + int cursorColumn = const_cast<wxGrid&>(grid).GetGridCursorCol(); + + if ( cursorRow < 0 || + cursorRow >= rowCount || + cursorColumn < 0 || + cursorColumn >= columnCount) + { + //cursor not on valid position... + cursorRow = 0; + cursorColumn = 0; + } + + const FindInText<respectCase> searchTxt(searchString); + + if (fromBeginToCursor) + { + for (int row = 0; row < cursorRow; ++row) + for (int col = 0; col < columnCount; ++col) + if (searchTxt.found(const_cast<wxGrid&>(grid).GetCellValue(row, col))) + return std::make_pair(row, col); + + for (int col = 0; col <= cursorColumn; ++col) + if (searchTxt.found(const_cast<wxGrid&>(grid).GetCellValue(cursorRow, col))) + return std::make_pair(cursorRow, col); + } + + if (afterCursorToEnd) + { + //begin search after cursor cell... + for (int col = cursorColumn + 1; col < columnCount; ++col) + if (searchTxt.found(const_cast<wxGrid&>(grid).GetCellValue(cursorRow, col))) + return std::make_pair(cursorRow, col); + + for (int row = cursorRow + 1; row < rowCount; ++row) + for (int col = 0; col < columnCount; ++col) + if (searchTxt.found(const_cast<wxGrid&>(grid).GetCellValue(row, col))) + return std::make_pair(row, col); + } + + return std::make_pair(-1, -1); +} + + +//syntactic sugar... +std::pair<int, int> searchGrid(const wxGrid& grid, + bool respectCase, + const wxString& searchString, + bool fromBeginToCursor, //specify area to search + bool afterCursorToEnd) // +{ + return respectCase ? + searchGrid<true>( grid, searchString, fromBeginToCursor, afterCursorToEnd) : + searchGrid<false>(grid, searchString, fromBeginToCursor, afterCursorToEnd); +} + + +wxString lastSearchString; //this variable really is conceptionally global... + + +void executeSearch(bool forceShowDialog, + bool& respectCase, + wxWindow& parentWindow, + wxGrid& leftGrid, + wxGrid& rightGrid) +{ + if (forceShowDialog || lastSearchString.IsEmpty()) + { + SearchDlg* searchDlg = new SearchDlg(parentWindow, lastSearchString, respectCase); //wxWidgets deletion handling -> deleted by parentWindow + if (static_cast<SearchDlg::ReturnCodes>(searchDlg->ShowModal()) != SearchDlg::BUTTON_OKAY) + return; + } + + wxGrid* targetGrid = NULL; //filled if match is found + std::pair<int, int> targetPos; // + { + wxBusyCursor showHourGlass; + + const bool startLeft = wxWindow::FindFocus() != rightGrid.GetGridWindow(); + wxGrid& firstGrid = startLeft ? leftGrid : rightGrid; + wxGrid& secondGrid = startLeft ? rightGrid : leftGrid; + + //begin with first grid after cursor + targetGrid = &firstGrid; + targetPos = searchGrid(firstGrid, respectCase, lastSearchString, false, true); + if (targetPos.first == -1) + { + //scan second grid completely + targetGrid = &secondGrid; + targetPos = searchGrid(secondGrid, respectCase, lastSearchString, true, true); + + //scan first grid up to cursor + if (targetPos.first == -1) + { + targetGrid = &firstGrid; + targetPos = searchGrid(firstGrid, respectCase, lastSearchString, true, false); + } + } + } + + if (targetPos.first != -1 && targetPos.second != -1) //new position found + { + targetGrid->SetFocus(); + targetGrid->SetGridCursor( targetPos.first, targetPos.second); + targetGrid->SelectRow( targetPos.first); + targetGrid->MakeCellVisible(targetPos.first, targetPos.second); + } + else + { + wxString messageNotFound = _("Cannot find %x"); + messageNotFound.Replace(wxT("%x"), wxString(wxT("\"")) + lastSearchString + wxT("\""), false); + wxMessageBox(messageNotFound, _("Find"), wxOK); + + //show search dialog again + executeSearch(true, respectCase, parentWindow, leftGrid, rightGrid); + } +} +//########################################################################################### + + +void FreeFileSync::startFind(wxWindow& parentWindow, wxGrid& leftGrid, wxGrid& rightGrid, bool& respectCase) //Strg + F +{ + executeSearch(true, respectCase, parentWindow, leftGrid, rightGrid); +} + + +void FreeFileSync::findNext(wxWindow& parentWindow, wxGrid& leftGrid, wxGrid& rightGrid, bool& respectCase) //F3 +{ + executeSearch(false, respectCase, parentWindow, leftGrid, rightGrid); +} diff --git a/ui/search.h b/ui/search.h new file mode 100644 index 00000000..51604b8d --- /dev/null +++ b/ui/search.h @@ -0,0 +1,20 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// +#ifndef SEARCH_H_INCLUDED +#define SEARCH_H_INCLUDED + +class wxGrid; +class wxWindow; + + +namespace FreeFileSync +{ +void startFind(wxWindow& parentWindow, wxGrid& leftGrid, wxGrid& rightGrid, bool& respectCase); //Strg + F +void findNext( wxWindow& parentWindow, wxGrid& leftGrid, wxGrid& rightGrid, bool& respectCase); //F3 +} + +#endif // SEARCH_H_INCLUDED diff --git a/ui/settingsDialog.cpp b/ui/settingsDialog.cpp index fe037322..754f9e01 100644 --- a/ui/settingsDialog.cpp +++ b/ui/settingsDialog.cpp @@ -1,10 +1,15 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// #include "settingsDialog.h" #include "../shared/systemConstants.h" #include "../library/resources.h" #include <wx/msgdlg.h> #include "../shared/customButton.h" #include "../synchronization.h" -//#include "../algorithm.h" #include "../shared/stringConv.h" #include "util.h" #include <wx/dnd.h> @@ -13,6 +18,8 @@ #include "../shared/xmlBase.h" #include <wx/wupdlock.h> #include "folderPair.h" +#include "messagePopup.h" +#include "../shared/helpProvider.h" using namespace FreeFileSync; @@ -25,7 +32,7 @@ SyncCfgDialog::SyncCfgDialog(wxWindow* window, bool* ignoreErrors) : SyncCfgDlgGenerated(window), cmpVariant(compareVar), - localSyncConfiguration(syncConfiguration), //make working copy of syncConfiguration + currentSyncConfig(syncConfiguration), //make working copy of syncConfiguration refSyncConfiguration(syncConfiguration), refHandleDeletion(handleDeletion), refCustomDeletionDirectory(customDeletionDirectory), @@ -45,7 +52,7 @@ SyncCfgDialog::SyncCfgDialog(wxWindow* window, } //set sync config icons - updateConfigIcons(cmpVariant, localSyncConfiguration); + updateConfigIcons(cmpVariant, currentSyncConfig); //set icons for this dialog m_bitmapLeftOnly->SetBitmap(GlobalResources::getInstance().getImageByName(wxT("leftOnly"))); @@ -57,14 +64,14 @@ SyncCfgDialog::SyncCfgDialog(wxWindow* window, bSizer201->Layout(); //wxButtonWithImage size might have changed - m_buttonApply->SetFocus(); + m_buttonOK->SetFocus(); Fit(); } //################################################################################################################# -SyncCfgDialog::~SyncCfgDialog() {} +SyncCfgDialog::~SyncCfgDialog() {} //non-inline destructor for std::auto_ptr to work with forward declaration void SyncCfgDialog::updateConfigIcons(const FreeFileSync::CompareVariant cmpVar, const FreeFileSync::SyncConfiguration& syncConfig) @@ -96,7 +103,7 @@ void SyncCfgDialog::updateConfigIcons(const FreeFileSync::CompareVariant cmpVar, sbSizerSyncDirections); //set radiobuttons -> have no parameter-ownership at all! - switch (localSyncConfiguration.getVariant()) + switch (FreeFileSync::getVariant(currentSyncConfig)) { case SyncConfiguration::AUTOMATIC: m_radioBtnAutomatic->SetValue(true); //automatic mode @@ -107,9 +114,6 @@ void SyncCfgDialog::updateConfigIcons(const FreeFileSync::CompareVariant cmpVar, case SyncConfiguration::UPDATE: m_radioBtnUpdate->SetValue(true); //Update -> break; - case SyncConfiguration::TWOWAY: - m_radioBtnTwoWay->SetValue(true); //two way <-> - break; case SyncConfiguration::CUSTOM: m_radioBtnCustom->SetValue(true); //custom break; @@ -285,7 +289,7 @@ void SyncCfgDialog::OnCancel(wxCommandEvent& event) void SyncCfgDialog::OnApply(wxCommandEvent& event) { //write configuration to main dialog - refSyncConfiguration = localSyncConfiguration; + refSyncConfiguration = currentSyncConfig; refHandleDeletion = getDeletionHandling(); refCustomDeletionDirectory = m_textCtrlCustomDelFolder->GetValue(); if (refIgnoreErrors) @@ -342,15 +346,15 @@ void updateToolTipDeletionHandling(wxChoice* choiceHandleError, wxPanel* customD switch (value) { case FreeFileSync::DELETE_PERMANENTLY: - choiceHandleError->SetToolTip(_("Delete or overwrite files permanently.")); + choiceHandleError->SetToolTip(_("Delete or overwrite files permanently")); break; case FreeFileSync::MOVE_TO_RECYCLE_BIN: - choiceHandleError->SetToolTip(_("Use Recycle Bin when deleting or overwriting files.")); + choiceHandleError->SetToolTip(_("Use Recycle Bin when deleting or overwriting files")); break; case FreeFileSync::MOVE_TO_CUSTOM_DIRECTORY: - choiceHandleError->SetToolTip(_("Move files into a time-stamped subdirectory.")); + choiceHandleError->SetToolTip(_("Move files into a time-stamped subdirectory")); customDir->Enable(); break; } @@ -406,29 +410,22 @@ void SyncCfgDialog::OnChangeDeletionHandling(wxCommandEvent& event) void SyncCfgDialog::OnSyncAutomatic(wxCommandEvent& event) { - localSyncConfiguration.setVariant(SyncConfiguration::AUTOMATIC); - updateConfigIcons(cmpVariant, localSyncConfiguration); + FreeFileSync::setVariant(currentSyncConfig, SyncConfiguration::AUTOMATIC); + updateConfigIcons(cmpVariant, currentSyncConfig); } void SyncCfgDialog::OnSyncLeftToRight(wxCommandEvent& event) { - localSyncConfiguration.setVariant(SyncConfiguration::MIRROR); - updateConfigIcons(cmpVariant, localSyncConfiguration); + FreeFileSync::setVariant(currentSyncConfig, SyncConfiguration::MIRROR); + updateConfigIcons(cmpVariant, currentSyncConfig); } void SyncCfgDialog::OnSyncUpdate(wxCommandEvent& event) { - localSyncConfiguration.setVariant(SyncConfiguration::UPDATE); - updateConfigIcons(cmpVariant, localSyncConfiguration); -} - - -void SyncCfgDialog::OnSyncBothSides(wxCommandEvent& event) -{ - localSyncConfiguration.setVariant(SyncConfiguration::TWOWAY); - updateConfigIcons(cmpVariant, localSyncConfiguration); + FreeFileSync::setVariant(currentSyncConfig, SyncConfiguration::UPDATE); + updateConfigIcons(cmpVariant, currentSyncConfig); } @@ -449,45 +446,45 @@ void toggleSyncDirection(SyncDirection& current) } -void SyncCfgDialog::OnExLeftSideOnly( wxCommandEvent& event ) +void SyncCfgDialog::OnExLeftSideOnly(wxCommandEvent& event ) { - toggleSyncDirection(localSyncConfiguration.exLeftSideOnly); - updateConfigIcons(cmpVariant, localSyncConfiguration); + toggleSyncDirection(currentSyncConfig.exLeftSideOnly); + updateConfigIcons(cmpVariant, currentSyncConfig); } -void SyncCfgDialog::OnExRightSideOnly( wxCommandEvent& event ) +void SyncCfgDialog::OnExRightSideOnly(wxCommandEvent& event ) { - toggleSyncDirection(localSyncConfiguration.exRightSideOnly); - updateConfigIcons(cmpVariant, localSyncConfiguration); + toggleSyncDirection(currentSyncConfig.exRightSideOnly); + updateConfigIcons(cmpVariant, currentSyncConfig); } -void SyncCfgDialog::OnLeftNewer( wxCommandEvent& event ) +void SyncCfgDialog::OnLeftNewer(wxCommandEvent& event ) { - toggleSyncDirection(localSyncConfiguration.leftNewer); - updateConfigIcons(cmpVariant, localSyncConfiguration); + toggleSyncDirection(currentSyncConfig.leftNewer); + updateConfigIcons(cmpVariant, currentSyncConfig); } -void SyncCfgDialog::OnRightNewer( wxCommandEvent& event ) +void SyncCfgDialog::OnRightNewer(wxCommandEvent& event ) { - toggleSyncDirection(localSyncConfiguration.rightNewer); - updateConfigIcons(cmpVariant, localSyncConfiguration); + toggleSyncDirection(currentSyncConfig.rightNewer); + updateConfigIcons(cmpVariant, currentSyncConfig); } -void SyncCfgDialog::OnDifferent( wxCommandEvent& event ) +void SyncCfgDialog::OnDifferent(wxCommandEvent& event ) { - toggleSyncDirection(localSyncConfiguration.different); - updateConfigIcons(cmpVariant, localSyncConfiguration); + toggleSyncDirection(currentSyncConfig.different); + updateConfigIcons(cmpVariant, currentSyncConfig); } void SyncCfgDialog::OnConflict(wxCommandEvent& event) { - toggleSyncDirection(localSyncConfiguration.conflict); - updateConfigIcons(cmpVariant, localSyncConfiguration); + toggleSyncDirection(currentSyncConfig.conflict); + updateConfigIcons(cmpVariant, currentSyncConfig); } @@ -620,10 +617,15 @@ BatchDialog::BatchDialog(wxWindow* window, const wxString& filename) : } +BatchDialog::~BatchDialog() {} //non-inline destructor for std::auto_ptr to work with forward declaration + + void BatchDialog::init() { wxWindowUpdateLocker dummy(this); //avoid display distortion + m_bpButtonHelp->SetBitmapLabel(GlobalResources::getInstance().getImageByName(wxT("help"))); + //init handling of first folder pair firstFolderPair.reset(new FirstBatchFolderPairCfg(*this)); @@ -681,7 +683,7 @@ void BatchDialog::updateToolTipErrorHandling(const xmlAccess::OnError value) m_choiceHandleError->SetToolTip(_("Hide all error and warning messages")); break; case xmlAccess::ON_ERROR_EXIT: - m_choiceHandleError->SetToolTip(_("Exit immediately and set returncode < 0")); + m_choiceHandleError->SetToolTip(_("Abort synchronization immediately")); break; } } @@ -693,7 +695,7 @@ void BatchDialog::setSelectionHandleError(const xmlAccess::OnError value) m_choiceHandleError->Append(_("Show popup")); m_choiceHandleError->Append(_("Ignore errors")); if (m_checkBoxSilent->GetValue()) //this option shall be available for silent mode only! - m_choiceHandleError->Append(_("Exit with RC < 0")); + m_choiceHandleError->Append(_("Exit instantly")); //default m_choiceHandleError->SetSelection(0); @@ -814,6 +816,16 @@ void BatchDialog::OnConflict(wxCommandEvent& event) } +void BatchDialog::OnHelp(wxCommandEvent& event) +{ +#ifdef FFS_WIN + FreeFileSync::displayHelpEntry(wxT("html\\advanced\\ScheduleBatch.html")); +#elif defined FFS_LINUX + FreeFileSync::displayHelpEntry(wxT("html/advanced/ScheduleBatch.html")); +#endif +} + + void BatchDialog::OnCheckFilter(wxCommandEvent& event) { updateVisibleTabs(); @@ -837,9 +849,6 @@ void BatchDialog::OnCheckAutomatic(wxCommandEvent& event) //toggle automatic setting localSyncConfiguration.automatic = !localSyncConfiguration.automatic; - if (localSyncConfiguration.automatic) - localSyncConfiguration.setVariant(SyncConfiguration::AUTOMATIC); //reset conflict-setting - updateConfigIcons(getCurrentCompareVar(), localSyncConfiguration); Fit(); } diff --git a/ui/settingsDialog.h b/ui/settingsDialog.h index 15d880f4..5a36b1c4 100644 --- a/ui/settingsDialog.h +++ b/ui/settingsDialog.h @@ -1,3 +1,9 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// #ifndef SYNCDIALOG_H_INCLUDED #define SYNCDIALOG_H_INCLUDED @@ -8,6 +14,7 @@ class BatchFileDropEvent; class BatchFolderPairPanel; class FirstBatchFolderPairCfg; +class wxHelpController; namespace FreeFileSync { @@ -54,7 +61,6 @@ private: virtual void OnSyncAutomatic( wxCommandEvent& event); virtual void OnSyncLeftToRight( wxCommandEvent& event); virtual void OnSyncUpdate( wxCommandEvent& event); - virtual void OnSyncBothSides( wxCommandEvent& event); virtual void OnExLeftSideOnly( wxCommandEvent& event); virtual void OnExRightSideOnly( wxCommandEvent& event); @@ -83,7 +89,7 @@ private: const FreeFileSync::CompareVariant cmpVariant; //temporal copy of maindialog.cfg.syncConfiguration - FreeFileSync::SyncConfiguration localSyncConfiguration; + FreeFileSync::SyncConfiguration currentSyncConfig; //changing data FreeFileSync::SyncConfiguration& refSyncConfiguration; @@ -104,7 +110,7 @@ class BatchDialog: public BatchDlgGenerated public: BatchDialog(wxWindow* window, const xmlAccess::XmlBatchConfig& batchCfg); BatchDialog(wxWindow* window, const wxString& filename); - ~BatchDialog() {}; + ~BatchDialog(); enum { @@ -120,6 +126,7 @@ private: virtual void OnRightNewer( wxCommandEvent& event); virtual void OnDifferent( wxCommandEvent& event); virtual void OnConflict( wxCommandEvent& event); + virtual void OnHelp( wxCommandEvent& event); virtual void OnCheckAutomatic( wxCommandEvent& event); virtual void OnCheckFilter( wxCommandEvent& event); diff --git a/ui/sorting.h b/ui/sorting.h index 5771d7db..9592b36f 100644 --- a/ui/sorting.h +++ b/ui/sorting.h @@ -1,3 +1,9 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// #ifndef SORTING_H_INCLUDED #define SORTING_H_INCLUDED @@ -12,11 +18,7 @@ namespace FreeFileSync inline int compareString(const Zstring& stringA, const Zstring& stringB) { -#ifdef FFS_WIN //Windows does NOT distinguish between upper/lower-case - return stringA.CmpNoCase(stringB); -#elif defined FFS_LINUX //Linux DOES distinguish between upper/lower-case - return stringA.Cmp(stringB); -#endif + return stringA.cmpFileName(stringB); } @@ -131,7 +133,7 @@ bool sortByFileSize(const FileSystemObject& a, const FileSystemObject& b) else if (fileObjB == NULL) return true; //directories last - //sortAscending shall result in list beginning with largest files first + //return list beginning with largest files first return Compare<!ascending>().isSmallerThan(fileObjA->getFileSize<side>(), fileObjB->getFileSize<side>()); } @@ -154,10 +156,33 @@ bool sortByDate(const FileSystemObject& a, const FileSystemObject& b) else if (fileObjB == NULL) return true; //directories last + //return list beginning with newest files first return Compare<!ascending>().isSmallerThan(fileObjA->getLastWriteTime<side>(), fileObjB->getLastWriteTime<side>()); } +template <bool ascending, SelectedSide side> +inline +bool sortByExtension(const FileSystemObject& a, const FileSystemObject& b) +{ + if (a.isEmpty<side>()) + return false; //empty rows always last + else if (b.isEmpty<side>()) + return true; //empty rows always last + + + const FileMapping* fileObjA = dynamic_cast<const FileMapping*>(&a); + const FileMapping* fileObjB = dynamic_cast<const FileMapping*>(&b); + + if (fileObjA == NULL) + return false; //directories last + else if (fileObjB == NULL) + return true; //directories last + + return Compare<ascending>().isSmallerThan(fileObjA->getExtension<side>(), fileObjB->getExtension<side>()); +} + + template <bool ascending> inline bool sortByCmpResult(const FileSystemObject& a, const FileSystemObject& b) diff --git a/ui/trayIcon.cpp b/ui/trayIcon.cpp index 921fe79f..b7f74d1d 100644 --- a/ui/trayIcon.cpp +++ b/ui/trayIcon.cpp @@ -1,10 +1,99 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// #include "trayIcon.h" #include "../library/resources.h" #include "smallDialogs.h" #include <wx/taskbar.h> #include <cmath> +#include <wx/image.h> +#include <wx/menu.h> +#include <wx/icon.h> //req. by Linux + +namespace +{ +inline +int roundNum(double d) //little rounding function +{ + return static_cast<int>(d < 0 ? d - .5 : d + .5); +} +wxIcon generateIcon(size_t percent) //generate icon with progress indicator +{ + percent = std::min(percent, static_cast<size_t>(100u)); //handle invalid input + +#ifdef FFS_WIN + static const wxBitmap trayIcon = GlobalResources::getInstance().getImageByName(wxT("FFS_tray_win.png")); +#elif defined FFS_LINUX + static const wxBitmap trayIcon = GlobalResources::getInstance().getImageByName(wxT("FFS_tray_linux.png")); +#endif + + const int indicatorHeight = roundNum((trayIcon.GetHeight() * percent) / 100.0); + + //minor optimization + static std::pair<int, wxIcon> buffer = std::make_pair(-1, wxNullIcon); + if (buffer.first == indicatorHeight) + return buffer.second; + + if ( trayIcon.GetWidth() > 0 && + trayIcon.GetHeight() > 0) + { + static const int indicatorWidth = trayIcon.GetWidth() * .25; + const int indicatorXBegin = ceil((trayIcon.GetWidth() - indicatorWidth) / 2.0); + const int indicatorYBegin = trayIcon.GetHeight() - indicatorHeight; + + wxImage genImage(trayIcon.ConvertToImage()); + + //draw progress indicator: do NOT use wxDC::DrawRectangle! Doesn't respect alpha in Windows, but does in Linux! + //We need a simple, working solution: + unsigned char* const data = genImage.GetData(); + for (int row = indicatorYBegin; row < genImage.GetHeight(); ++row) + { + for (int col = indicatorXBegin; col < indicatorXBegin + indicatorWidth; ++col) + { + unsigned char* const pixelBegin = data + (row * genImage.GetWidth() + col) * 3; + pixelBegin[0] = 255; //red + pixelBegin[1] = 255; //green + pixelBegin[2] = 0; //blue + } + } + + if (genImage.HasAlpha()) + { + unsigned char* const alpha = genImage.GetAlpha(); + //make progress indicator fully opaque: + for (int row = indicatorYBegin; row < genImage.GetHeight(); ++row) + ::memset(alpha + row * genImage.GetWidth() + indicatorXBegin, wxIMAGE_ALPHA_OPAQUE, indicatorWidth); + } + + wxIcon genIcon; + genIcon.CopyFromBitmap(wxBitmap(genImage)); + + //fill buffer + buffer.first = indicatorHeight; + buffer.second = genIcon; + + return genIcon; + } + + //fallback + wxIcon defaultIcon; + defaultIcon.CopyFromBitmap(trayIcon); + + //fill buffer + buffer.first = indicatorHeight; + buffer.second = defaultIcon; + + return defaultIcon; +} +} + + +//------------------------------------------------------------------------------------------------ enum Selection { CONTEXT_RESTORE, @@ -46,7 +135,7 @@ MinimizeToTray::MinimizeToTray(wxTopLevelWindow* callerWnd, wxWindow* secondWnd) secondWnd_(secondWnd), trayIcon(new TaskBarImpl(this)) { - trayIcon->SetIcon(*GlobalResources::getInstance().programIcon, wxT("FreeFileSync")); + trayIcon->SetIcon(generateIcon(0), wxT("FreeFileSync")); trayIcon->Connect(wxEVT_TASKBAR_LEFT_DCLICK, wxCommandEventHandler(MinimizeToTray::OnDoubleClick), NULL, this); //register double-click if (callerWnd_) @@ -89,86 +178,6 @@ void MinimizeToTray::resumeFromTray() //remove trayIcon and restore windows: Mi } -namespace -{ -inline -int roundNum(double d) //little rounding function -{ - return static_cast<int>(d < 0 ? d - .5 : d + .5); -} - - -wxIcon generateIcon(size_t percent) //generate icon with progress indicator -{ - percent = std::min(percent, static_cast<size_t>(100u)); //handle invalid input - -#ifdef FFS_WIN - static const wxBitmap trayIcon = GlobalResources::getInstance().getImageByName(wxT("FFS_tray_win.png")); -#elif defined FFS_LINUX - static const wxBitmap trayIcon = GlobalResources::getInstance().getImageByName(wxT("FFS_tray_linux.png")); -#endif - - const int indicatorHeight = roundNum((trayIcon.GetHeight() * percent) / 100.0); - - //minor optimization - static std::pair<int, wxIcon> buffer = std::make_pair(-1, wxNullIcon); - if (buffer.first == indicatorHeight) - return buffer.second; - - if ( trayIcon.GetWidth() > 0 && - trayIcon.GetHeight() > 0) - { - static const int indicatorWidth = trayIcon.GetWidth() * .25; - const int indicatorXBegin = ceil((trayIcon.GetWidth() - indicatorWidth) / 2.0); - const int indicatorYBegin = trayIcon.GetHeight() - indicatorHeight; - - wxImage genImage(trayIcon.ConvertToImage()); - - //draw progress indicator: do NOT use wxDC::DrawRectangle! Doesn't respect alpha in Windows, but does in Linux! - //We need a simple, working solution: - unsigned char* const data = genImage.GetData(); - for (int row = indicatorYBegin; row < genImage.GetHeight(); ++row) - { - for (int col = indicatorXBegin; col < indicatorXBegin + indicatorWidth; ++col) - { - unsigned char* const pixelBegin = data + (row * genImage.GetWidth() + col) * 3; - pixelBegin[0] = 255; //red - pixelBegin[1] = 255; //green - pixelBegin[2] = 0; //blue - } - } - - if (genImage.HasAlpha()) - { - unsigned char* const alpha = genImage.GetAlpha(); - //make progress indicator fully opaque: - for (int row = indicatorYBegin; row < genImage.GetHeight(); ++row) - ::memset(alpha + row * genImage.GetWidth() + indicatorXBegin, wxIMAGE_ALPHA_OPAQUE, indicatorWidth); - } - - wxIcon genIcon; - genIcon.CopyFromBitmap(wxBitmap(genImage)); - - //fill buffer - buffer.first = indicatorHeight; - buffer.second = genIcon; - - return genIcon; - } - - //fallback - wxIcon defaultIcon; - defaultIcon.CopyFromBitmap(trayIcon); - - //fill buffer - buffer.first = indicatorHeight; - buffer.second = defaultIcon; - - return defaultIcon; -} -} - - void MinimizeToTray::setToolTip(const wxString& toolTipText, size_t percent) { if (trayIcon) @@ -189,12 +198,8 @@ void MinimizeToTray::OnContextMenuSelection(wxCommandEvent& event) switch (eventId) { case CONTEXT_ABOUT: - { - AboutDlg* aboutDlg = new AboutDlg(NULL); - aboutDlg->ShowModal(); - aboutDlg->Destroy(); - } - break; + FreeFileSync::showAboutDialog(); + break; case CONTEXT_RESTORE: resumeFromTray(); } diff --git a/ui/trayIcon.h b/ui/trayIcon.h index 8c8797d4..b351dfc8 100644 --- a/ui/trayIcon.h +++ b/ui/trayIcon.h @@ -1,3 +1,9 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// #ifndef TRAYICON_H_INCLUDED #define TRAYICON_H_INCLUDED diff --git a/ui/util.cpp b/ui/util.cpp index 853bd91b..c611e252 100644 --- a/ui/util.cpp +++ b/ui/util.cpp @@ -1,3 +1,9 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// #include "util.h" #include <wx/scrolwin.h> #include <wx/textctrl.h> @@ -24,7 +30,7 @@ wxString FreeFileSync::formatFilesizeToShortString(const wxLongLong& filesize) wxString FreeFileSync::formatFilesizeToShortString(const wxULongLong& filesize) { return FreeFileSync::formatFilesizeToShortString(filesize.ToDouble()); -}; +} wxString FreeFileSync::formatFilesizeToShortString(const double filesize) @@ -85,9 +91,9 @@ wxString FreeFileSync::formatFilesizeToShortString(const double filesize) } -wxString FreeFileSync::fromatPercentage(const wxLongLong& dividend, const wxLongLong& divisor) +wxString FreeFileSync::formatPercentage(const wxLongLong& dividend, const wxLongLong& divisor) { - const double ratio = dividend.ToDouble() * 100 / divisor.ToDouble(); + const double ratio = divisor != 0 ? dividend.ToDouble() * 100 / divisor.ToDouble() : 0; wxString output = _("%x Percent"); output.Replace(wxT("%x"), wxString::Format(wxT("%3.2f"), ratio), false); return output; @@ -1,3 +1,9 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** +// #ifndef UTIL_H_INCLUDED #define UTIL_H_INCLUDED @@ -17,7 +23,7 @@ wxString formatFilesizeToShortString(const wxLongLong& filesize); wxString formatFilesizeToShortString(const wxULongLong& filesize); wxString formatFilesizeToShortString(const double filesize); -wxString fromatPercentage(const wxLongLong& dividend, const wxLongLong& divisor); +wxString formatPercentage(const wxLongLong& dividend, const wxLongLong& divisor); wxString includeNumberSeparator(const wxString& number); |