summaryrefslogtreecommitdiff
path: root/ui/main_dlg.cpp
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:21:16 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:21:16 +0200
commit6d15812d7d93370d47e63f6bf9f70be40f5a9c5d (patch)
tree8e7bde205084ca23e1766d42305824c927c2ee5f /ui/main_dlg.cpp
parent5.6 (diff)
downloadFreeFileSync-6d15812d7d93370d47e63f6bf9f70be40f5a9c5d.tar.gz
FreeFileSync-6d15812d7d93370d47e63f6bf9f70be40f5a9c5d.tar.bz2
FreeFileSync-6d15812d7d93370d47e63f6bf9f70be40f5a9c5d.zip
5.7
Diffstat (limited to 'ui/main_dlg.cpp')
-rw-r--r--ui/main_dlg.cpp316
1 files changed, 165 insertions, 151 deletions
diff --git a/ui/main_dlg.cpp b/ui/main_dlg.cpp
index 7681cde2..894b0b11 100644
--- a/ui/main_dlg.cpp
+++ b/ui/main_dlg.cpp
@@ -1,7 +1,7 @@
// **************************************************************************
// * 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) ZenJu (zhnmju123 AT gmx DOT de) - All Rights Reserved *
+// * Copyright (C) ZenJu (zenju AT gmx DOT de) - All Rights Reserved *
// **************************************************************************
#include "main_dlg.h"
@@ -16,10 +16,10 @@
#include <wx/display.h>
#include <wx/app.h>
#include <wx/dcmemory.h>
+#include <wx/filedlg.h>
#include <wx+/context_menu.h>
#include "folder_history_box.h"
#include <wx+/button.h>
-#include <wx+/dir_picker.h>
#include "../comparison.h"
#include "../synchronization.h"
#include "../algorithm.h"
@@ -62,11 +62,12 @@ using namespace std::rel_ops;
namespace
{
-struct wxClientDataString : public wxClientData //we need a wxClientData derived class to tell wxWidgets to take object ownership!
+struct wxClientHistoryData: public wxClientData //we need a wxClientData derived class to tell wxWidgets to take object ownership!
{
- wxClientDataString(const wxString& name) : name_(name) {}
+ wxClientHistoryData(const wxString& cfgFile, int lastUseIndex) : cfgFile_(cfgFile), lastUseIndex_(lastUseIndex) {}
- wxString name_;
+ wxString cfgFile_;
+ int lastUseIndex_; //support sorting history by last usage, the higher the index the more recent the usage
};
IconBuffer::IconSize convert(xmlAccess::FileIconSize isize)
@@ -92,12 +93,11 @@ public:
DirectoryNameMainImpl(MainDialog& mainDlg,
wxWindow& dropWindow1,
Grid& dropGrid,
- wxDirPickerCtrl& dirPicker,
+ wxButton& dirSelectButton,
FolderHistoryBox& dirName,
wxStaticText& staticText) :
- DirectoryName(dropWindow1, dirPicker, dirName, &staticText, &dropGrid.getMainWin()),
- mainDlg_(mainDlg),
- dropGrid_(dropGrid) {}
+ DirectoryName(dropWindow1, dirSelectButton, dirName, &staticText, &dropGrid.getMainWin()),
+ mainDlg_(mainDlg) {}
virtual bool acceptDrop(const std::vector<wxString>& droppedFiles, const wxPoint& clientPos, const wxWindow& wnd)
{
@@ -117,7 +117,7 @@ public:
break;
}
- mainDlg_.clearGrid();
+ //mainDlg_.clearGrid();
return true;
}
@@ -126,7 +126,6 @@ private:
DirectoryNameMainImpl& operator=(const DirectoryNameMainImpl&);
MainDialog& mainDlg_;
- Grid& dropGrid_;
};
//------------------------------------------------------------------
@@ -194,8 +193,12 @@ public:
DirectoryPair(wxWindow* parent, MainDialog& mainDialog) :
FolderPairGenerated(parent),
FolderPairCallback<FolderPairGenerated>(static_cast<FolderPairGenerated&>(*this), mainDialog), //pass FolderPairGenerated part...
- dirNameLeft (*m_panelLeft, *m_dirPickerLeft, *m_directoryLeft),
- dirNameRight(*m_panelRight, *m_dirPickerRight, *m_directoryRight) {}
+ dirNameLeft (*m_panelLeft, *m_buttonSelectDirLeft, *m_directoryLeft),
+ dirNameRight(*m_panelRight, *m_buttonSelectDirRight, *m_directoryRight)
+ {
+ dirNameLeft .Connect(EVENT_ON_DIR_SELECTED, wxCommandEventHandler(MainDialog::OnDirSelected), nullptr, &mainDialog);
+ dirNameRight.Connect(EVENT_ON_DIR_SELECTED, wxCommandEventHandler(MainDialog::OnDirSelected), nullptr, &mainDialog);
+ }
void setValues(const wxString& leftDir,
const wxString& rightDir,
@@ -227,15 +230,19 @@ public:
dirNameLeft(mainDialog,
*mainDialog.m_panelTopLeft,
*mainDialog.m_gridMainL,
- *mainDialog.m_dirPickerLeft,
+ *mainDialog.m_buttonSelectDirLeft,
*mainDialog.m_directoryLeft,
*mainDialog.m_staticTextFinalPathLeft),
dirNameRight(mainDialog,
*mainDialog.m_panelTopRight,
*mainDialog.m_gridMainR,
- *mainDialog.m_dirPickerRight,
+ *mainDialog.m_buttonSelectDirRight,
*mainDialog.m_directoryRight,
- *mainDialog.m_staticTextFinalPathRight) {}
+ *mainDialog.m_staticTextFinalPathRight)
+ {
+ dirNameLeft .Connect(EVENT_ON_DIR_SELECTED, wxCommandEventHandler(MainDialog::OnDirSelected), nullptr, &mainDialog);
+ dirNameRight.Connect(EVENT_ON_DIR_SELECTED, wxCommandEventHandler(MainDialog::OnDirSelected), nullptr, &mainDialog);
+ }
void setValues(const wxString& leftDir,
const wxString& rightDir,
@@ -493,7 +500,7 @@ void MainDialog::init(const xmlAccess::XmlGuiConfig& guiCfg,
wxAuiPaneInfo().Name(wxT("Panel3")).CenterPane().PaneBorder(false));
auiMgr.AddPane(m_gridNavi,
- wxAuiPaneInfo().Name(L"Panel10").Left().Layer(3).Caption(_("Overview")).MinSize(350, m_gridNavi->GetSize().GetHeight())); //MinSize(): just default size, see comment below
+ wxAuiPaneInfo().Name(L"Panel10").Left().Layer(3).Caption(_("Overview")).MinSize(230, m_gridNavi->GetSize().GetHeight())); //MinSize(): just default size, see comment below
auiMgr.AddPane(m_panelConfig,
wxAuiPaneInfo().Name(wxT("Panel4")).Layer(4).Bottom().Row(1).Position(0).Caption(_("Configuration")).MinSize(m_listBoxHistory->GetSize().GetWidth(), m_panelConfig->GetSize().GetHeight()));
@@ -664,7 +671,7 @@ void MainDialog::init(const xmlAccess::XmlGuiConfig& guiCfg,
//Connect(wxEVT_MOVE, wxSizeEventHandler(MainDialog::OnResize), nullptr, this);
//calculate witdh of folder pair manually (if scrollbars are visible)
- m_panelTopLeft->Connect(wxEVT_SIZE, wxEventHandler(MainDialog::OnResizeFolderPairs), nullptr, this);
+ m_panelTopLeft->Connect(wxEVT_SIZE, wxEventHandler(MainDialog::OnResizeLeftFolderWidth), nullptr, this);
//dynamically change sizer direction depending on size
m_panelConfig ->Connect(wxEVT_SIZE, wxEventHandler(MainDialog::OnResizeConfigPanel), nullptr, this);
@@ -688,7 +695,7 @@ void MainDialog::init(const xmlAccess::XmlGuiConfig& guiCfg,
//asynchronous call to wxWindow::Layout(): fix superfluous frame on right and bottom when FFS is started in fullscreen mode
Connect(wxEVT_IDLE, wxIdleEventHandler(MainDialog::OnLayoutWindowAsync), nullptr, this);
wxCommandEvent evtDummy; //call once before OnLayoutWindowAsync()
- OnResizeFolderPairs(evtDummy); //
+ OnResizeLeftFolderWidth(evtDummy); //
//----------------------------------------------------------------------------------------------------------------------------------------------------------------
//some convenience: if FFS is started with a *.ffs_gui file as commandline parameter AND all directories contained exist, comparison shall be started right away
@@ -771,10 +778,14 @@ void MainDialog::setGlobalCfgOnInit(const xmlAccess::XmlGlobalSettings& globalSe
treeDataView->setSortDirection(globalSettings.gui.naviLastSortColumn, globalSettings.gui.naviLastSortAscending);
+ //--------------------------------------------------------------------------------
//load list of last used configuration files
std::vector<wxString> cfgFileNames = globalSettings.gui.cfgFileHistory;
- cfgFileNames.push_back(lastRunConfigName()); //make sure <Last session> is always part of history list
+ std::reverse(cfgFileNames.begin(), cfgFileNames.end()); //list is stored with last used files first in xml, however addFileToCfgHistory() needs them last!!!
+
+ cfgFileNames.push_back(lastRunConfigName()); //make sure <Last session> is always part of history list (if existing)
addFileToCfgHistory(cfgFileNames);
+ //--------------------------------------------------------------------------------
//load list of last used folders
*folderHistoryLeft = FolderHistory(globalSettings.gui.folderHistoryLeft, globalSettings.gui.folderHistMax);
@@ -794,8 +805,12 @@ void MainDialog::setGlobalCfgOnInit(const xmlAccess::XmlGlobalSettings& globalSe
auiMgr.LoadPerspective(globalSettings.gui.guiPerspectiveLast);
//restore original captions
- for (CaptionNameMapping::const_iterator i = captionNameMap.begin(); i != captionNameMap.end(); ++i)
- auiMgr.GetPane(i->second).Caption(i->first);
+ for (auto iter = captionNameMap.begin(); iter != captionNameMap.end(); ++iter)
+ auiMgr.GetPane(iter->second).Caption(iter->first);
+
+ //if MainDialog::onQueryEndSession() is called while comparison is active, this panel is saved and restored as "visible"
+ auiMgr.GetPane(compareStatus->getAsWindow()).Hide();
+
auiMgr.Update();
}
@@ -809,18 +824,6 @@ xmlAccess::XmlGlobalSettings MainDialog::getGlobalCfgBeforeExit()
globalSettings.programLanguage = getLanguage();
- //write global settings to (global) variable stored in application instance
- if (IsIconized()) //we need to (reliably) retrieve non-iconized, non-maximized size and position
- Iconize(false);
-
- globalSettings.gui.isMaximized = IsMaximized(); //evaluate AFTER uniconizing!
-
- if (IsMaximized())
- Maximize(false);
-
- globalSettings.gui.dlgSize = GetSize();
- globalSettings.gui.dlgPos = GetPosition();
-
//retrieve column attributes
globalSettings.gui.columnAttribLeft = gridview::convertConfig(m_gridMainL->getColumnConfig());
globalSettings.gui.columnAttribRight = gridview::convertConfig(m_gridMainR->getColumnConfig());
@@ -833,13 +836,24 @@ xmlAccess::XmlGlobalSettings MainDialog::getGlobalCfgBeforeExit()
globalSettings.gui.naviLastSortColumn = sortInfo.first;
globalSettings.gui.naviLastSortAscending = sortInfo.second;
+ //--------------------------------------------------------------------------------
//write list of last used configuration files
- std::vector<wxString> cfgFileHistory;
+ typedef std::pair<wxString, int> HistItem; //(cfg-file/last use index)
+ std::vector<HistItem> historyDetail;
for (unsigned int i = 0; i < m_listBoxHistory->GetCount(); ++i)
- if (auto clientString = dynamic_cast<wxClientDataString*>(m_listBoxHistory->GetClientObject(i)))
- cfgFileHistory.push_back(clientString->name_);
+ if (auto clientString = dynamic_cast<const wxClientHistoryData*>(m_listBoxHistory->GetClientObject(i)))
+ historyDetail.push_back(std::make_pair(clientString->cfgFile_, clientString->lastUseIndex_));
+ //sort by last use, most recent items *first* (looks better in xml than the reverse)
+ std::sort(historyDetail.begin(), historyDetail.end(), [](const HistItem& lhs, const HistItem& rhs) { return lhs.second > rhs.second; });
+
+ std::vector<wxString> history;
+ std::transform(historyDetail.begin(), historyDetail.end(), std::back_inserter(history), [](const HistItem& item) { return item.first; });
+
+ if (history.size() > globalSettings.gui.cfgFileHistMax) //erase oldest elements
+ history.resize(globalSettings.gui.cfgFileHistMax);
- globalSettings.gui.cfgFileHistory = cfgFileHistory;
+ globalSettings.gui.cfgFileHistory = history;
+ //--------------------------------------------------------------------------------
globalSettings.gui.lastUsedConfigFiles = activeConfigFiles;
//write list of last used folders
@@ -848,6 +862,19 @@ xmlAccess::XmlGlobalSettings MainDialog::getGlobalCfgBeforeExit()
globalSettings.gui.guiPerspectiveLast = auiMgr.SavePerspective();
+ //we need to portably retrieve non-iconized, non-maximized size and position (non-portable: GetWindowPlacement())
+ //call *after* wxAuiManager::SavePerspective()!
+ if (IsIconized())
+ Iconize(false);
+
+ globalSettings.gui.isMaximized = IsMaximized(); //evaluate AFTER uniconizing!
+
+ if (IsMaximized())
+ Maximize(false);
+
+ globalSettings.gui.dlgSize = GetSize();
+ globalSettings.gui.dlgPos = GetPosition();
+
return globalSettings;
}
@@ -871,7 +898,7 @@ void MainDialog::setSyncDirManually(const std::vector<FileSystemObject*>& select
void MainDialog::setManualFilter(const std::vector<FileSystemObject*>& selection, bool setIncluded)
{
//if hidefiltered is active, there should be no filtered elements on screen => current element was filtered out
- assert(!currentCfg.hideFilteredElements || !setIncluded);
+ assert(currentCfg.showFilteredElements || !setIncluded);
if (!selection.empty())
{
@@ -1184,11 +1211,15 @@ void MainDialog::openExternalApplication(const wxString& commandline, const zen:
wxString command = commandline;
- auto tryReplace = [&](const wxString& phrase, const wxString& replacement) -> bool
+ auto tryReplace = [&](wxString phrase, const wxString& replacement) -> bool
{
- if (command.find(phrase) != wxString::npos)
+ wxString cmdTmp = command.Upper(); //case insensitive search
+ phrase.MakeUpper(); //
+
+ size_t pos = cmdTmp.find(phrase);
+ if (pos != wxString::npos)
{
- replace(command, phrase, replacement);
+ command.replace(pos, phrase.size(), replacement);
if (replacement.empty())
return false;
}
@@ -1196,10 +1227,10 @@ void MainDialog::openExternalApplication(const wxString& commandline, const zen:
};
bool expandSuccess =
- /**/ tryReplace(L"%nameCo", nameCo); //attention: replace %nameCo, %dirCo BEFORE %name, %dir to handle dependency
- expandSuccess = tryReplace(L"%dirCo", dirCo ) && expandSuccess; //
- expandSuccess = tryReplace(L"%name", name ) && expandSuccess; //prevent short-cut behavior!
- expandSuccess = tryReplace(L"%dir", dir ) && expandSuccess; //
+ /**/ tryReplace(L"%item_path%" , name ); //prevent short-cut behavior!
+ expandSuccess = tryReplace(L"%item_folder%" , dir ) && expandSuccess; //
+ expandSuccess = tryReplace(L"%item2_path%" , nameCo) && expandSuccess; //
+ expandSuccess = tryReplace(L"%item2_folder%", dirCo ) && expandSuccess; //
const bool openFileBrowser = [&]() -> bool
{
@@ -1208,8 +1239,11 @@ void MainDialog::openExternalApplication(const wxString& commandline, const zen:
}();
if (!openFileBrowser || expandSuccess)
- zen::shellExecute(command); //just execute, show error message if command is malformed
- else //support built-in fallback!
+ {
+ auto cmdExp = utfCvrtTo<wxString>(expandMacros(utfCvrtTo<Zstring>(command)));
+ zen::shellExecute(cmdExp); //just execute, show error message if command is malformed
+ }
+ else //failed to expand file browser command: support built-in fallback instead of an error!
{
wxString fallbackDir;
if (fsObj)
@@ -1410,7 +1444,7 @@ void MainDialog::OnResizeStatisticsPanel(wxEvent& event)
}
-void MainDialog::OnResizeFolderPairs(wxEvent& event)
+void MainDialog::OnResizeLeftFolderWidth(wxEvent& event)
{
//adapt left-shift display distortion caused by scrollbars for multiple folder pairs
const int width = m_panelTopLeft->GetSize().GetWidth();
@@ -1418,7 +1452,6 @@ void MainDialog::OnResizeFolderPairs(wxEvent& event)
[&](DirectoryPair* dirPair)
{
dirPair->m_panelLeft->SetMinSize(wxSize(width, -1));
-
});
event.Skip();
@@ -2186,19 +2219,17 @@ void MainDialog::OnSyncSettingsContext(wxMouseEvent& event)
}
-void MainDialog::OnDirSelected(wxFileDirPickerEvent& event)
+void MainDialog::onNaviPanelFilesDropped(FileDropEvent& event)
{
- //left and right directory text-control and dirpicker are synchronized by MainFolderDragDrop automatically
-
- clearGrid(); //disable the sync button
-
+ loadConfiguration(event.getFiles());
event.Skip();
}
-void MainDialog::onNaviPanelFilesDropped(FileDropEvent& event)
+void MainDialog::OnDirSelected(wxCommandEvent& event)
{
- loadConfiguration(event.getFiles());
+ //left and right directory text-control and dirpicker are synchronized by MainFolderDragDrop automatically
+ clearGrid(); //disable the sync button
event.Skip();
}
@@ -2225,10 +2256,17 @@ void MainDialog::addFileToCfgHistory(const std::vector<wxString>& filenames)
//potentially slow network access: give all checks 500ms to finish
wait_for_all_timed(fileEx.begin(), fileEx.end(), boost::posix_time::milliseconds(500));
+
//------------------------------------------------------------------------------------------
+ //determine highest "last use" index number of m_listBoxHistory
+ int lastUseIndexMax = 0;
+ for (int i = 0; i < static_cast<int>(m_listBoxHistory->GetCount()); ++i)
+ if (auto histData = dynamic_cast<const wxClientHistoryData*>(m_listBoxHistory->GetClientObject(i)))
+ if (histData->lastUseIndex_ > lastUseIndexMax)
+ lastUseIndexMax = histData->lastUseIndex_;
- std::deque<bool> selections(m_listBoxHistory->GetCount());
+ std::deque<bool> selections(m_listBoxHistory->GetCount()); //items to select after update of history list
auto futIter = fileEx.begin();
for (auto iter = filenames.begin(); iter != filenames.end(); ++iter, ++futIter)
@@ -2238,37 +2276,28 @@ void MainDialog::addFileToCfgHistory(const std::vector<wxString>& filenames)
continue;
const wxString& filename = *iter;
- const Zstring file = toZ(filename);
-
- int posFound = -1;
- for (int i = 0; i < static_cast<int>(m_listBoxHistory->GetCount()); ++i)
+ auto findItem = [&]() -> int
{
- wxClientDataString* cData = dynamic_cast<wxClientDataString*>(m_listBoxHistory->GetClientObject(i));
- if (cData)
- {
- const wxString& filenameTmp = cData->name_;
+ for (int i = 0; i < static_cast<int>(m_listBoxHistory->GetCount()); ++i)
+ if (auto histData = dynamic_cast<const wxClientHistoryData*>(m_listBoxHistory->GetClientObject(i)))
+ if (samePhysicalFile(toZ(filename), toZ(histData->cfgFile_)))
+ return i;
+ return -1;
+ };
- //tests if the same filenames are specified, even if they are relative to the current working directory/include symlinks or \\?\ prefix
- if (zen::samePhysicalFile(toZ(filename), toZ(filenameTmp)))
- {
- posFound = i;
- break;
- }
- }
+ const int itemPos = findItem();
+ if (itemPos >= 0) //update
+ {
+ if (auto histData = dynamic_cast<wxClientHistoryData*>(m_listBoxHistory->GetClientObject(itemPos)))
+ histData->lastUseIndex_ = ++lastUseIndexMax;
+ selections[itemPos] = true;
}
-
- if (posFound != -1)
- selections[posFound] = true;
- else
+ else //insert
{
- int newPos = -1;
- //the default config file should receive a different name on GUI
- if (zen::samePhysicalFile(toZ(lastRunConfigName()), toZ(filename)))
- newPos = m_listBoxHistory->Append(_("<Last session>"), new wxClientDataString(filename));
- else
- newPos = m_listBoxHistory->Append(getFormattedHistoryElement(filename), new wxClientDataString(filename));
-
+ const wxString label = samePhysicalFile(toZ(lastRunConfigName()), toZ(filename)) ? //give default config file a different name
+ _("<Last session>") : getFormattedHistoryElement(filename);
+ const int newPos = m_listBoxHistory->Append(label, new wxClientHistoryData(filename, ++lastUseIndexMax)); //*insert* into sorted list
selections.insert(selections.begin() + newPos, true);
}
}
@@ -2376,7 +2405,7 @@ bool MainDialog::saveOldConfig() //return false on user abort
ReturnQuestionDlg::BUTTON_YES | ReturnQuestionDlg::BUTTON_NO | ReturnQuestionDlg::BUTTON_CANCEL,
replaceCpy(_("Do you want to save changes to %x?"), L"%x", fmtFileName(afterLast(utfCvrtTo<Zstring>(filename), FILE_NAME_SEPARATOR))),
filename, //caption
- _("Save"), _("Don't Save"),
+ _("&Save"), _("Do&n't save"),
&cb))
{
case ReturnQuestionDlg::BUTTON_YES:
@@ -2443,8 +2472,8 @@ void MainDialog::OnLoadFromHistory(wxCommandEvent& event)
std::for_each(selections.begin(), selections.end(),
[&](int pos)
{
- if (auto cData = dynamic_cast<wxClientDataString*>(m_listBoxHistory->GetClientObject(pos)))
- filenames.push_back(cData->name_);
+ if (auto histData = dynamic_cast<const wxClientHistoryData*>(m_listBoxHistory->GetClientObject(pos)))
+ filenames.push_back(histData->cfgFile_);
});
if (!filenames.empty())
@@ -2649,7 +2678,7 @@ void MainDialog::setConfig(const xmlAccess::XmlGuiConfig& newGuiCfg)
//read GUI layout
- m_checkBoxHideFilt->SetValue(currentCfg.hideFilteredElements);
+ m_checkBoxShowExcluded->SetValue(currentCfg.showFilteredElements);
showSyncAction(currentCfg.showSyncAction);
@@ -2710,7 +2739,7 @@ void MainDialog::updateGuiAfterFilterChange(int delay)
{
//signal UI that grids need to be refreshed on next Update()
- if (currentCfg.hideFilteredElements)
+ if (!currentCfg.showFilteredElements)
{
gridview::refresh(*m_gridMainL, *m_gridMainC, *m_gridMainR);
m_gridMainL->Update();
@@ -2724,12 +2753,12 @@ void MainDialog::updateGuiAfterFilterChange(int delay)
}
-void MainDialog::OnHideFilteredButton(wxCommandEvent& event)
+void MainDialog::OnShowExcluded(wxCommandEvent& event)
{
//toggle showing filtered rows
- currentCfg.hideFilteredElements = !currentCfg.hideFilteredElements;
- //make sure, checkbox and "hideFiltered" are in sync
- m_checkBoxHideFilt->SetValue(currentCfg.hideFilteredElements);
+ currentCfg.showFilteredElements = !currentCfg.showFilteredElements;
+ //make sure, checkbox and value are in sync
+ m_checkBoxShowExcluded->SetValue(currentCfg.showFilteredElements);
updateGui();
}
@@ -3043,15 +3072,14 @@ void MainDialog::OnCompare(wxCommandEvent& event)
}
}
- //begin comparison
- zen::CompareProcess compProc(globalCfg.fileTimeTolerance,
- globalCfg.optDialogs,
- true, //allow pw prompt
- globalCfg.runWithBackgroundPriority,
- statusHandler);
-
- //technical representation of comparison data
- compProc.startCompareProcess(cmpConfig, folderCmp); //throw GuiAbortProcess
+ //COMPARE DIRECTORIES
+ compare(globalCfg.fileTimeTolerance,
+ globalCfg.optDialogs,
+ true, //allow pw prompt
+ globalCfg.runWithBackgroundPriority,
+ cmpConfig,
+ folderCmp,
+ statusHandler); //throw GuiAbortProcess
}
catch (GuiAbortProcess&)
{
@@ -3082,7 +3110,7 @@ void MainDialog::OnCompare(wxCommandEvent& event)
//prepare status information
if (allElementsEqual(folderCmp))
- flashStatusInformation(_("All directories in sync!"));
+ flashStatusInformation(_("All folders are in sync!"));
}
@@ -3265,24 +3293,21 @@ void MainDialog::OnStartSync(wxCommandEvent& event)
}
}
- //start synchronization and mark all elements processed
- zen::SyncProcess syncProc(xmlAccess::extractJobName(activeFileName),
- formatTime<std::wstring>(L"%Y-%m-%d %H%M%S"),
- globalCfg.optDialogs,
- globalCfg.verifyFileCopy,
- globalCfg.copyLockedFiles,
- globalCfg.copyFilePermissions,
- globalCfg.transactionalFileCopy,
- globalCfg.runWithBackgroundPriority,
- statusHandler);
-
+ //START SYNCHRONIZATION
const std::vector<zen::FolderPairSyncCfg> syncProcessCfg = zen::extractSyncCfg(guiCfg.mainCfg);
-
- //make sure syncProcessCfg and dataToSync have same size and correspond!
if (syncProcessCfg.size() != folderCmp.size())
throw std::logic_error("Programming Error: Contract violation!"); //should never happen: sync button is deactivated if they are not in sync
- syncProc.startSynchronizationProcess(syncProcessCfg, folderCmp);
+ synchronize(localTime(),
+ globalCfg.optDialogs,
+ globalCfg.verifyFileCopy,
+ globalCfg.copyLockedFiles,
+ globalCfg.copyFilePermissions,
+ globalCfg.transactionalFileCopy,
+ globalCfg.runWithBackgroundPriority,
+ syncProcessCfg,
+ folderCmp,
+ statusHandler);
//play (optional) sound notification after sync has completed (GUI and batch mode)
const wxString soundFile = toWx(zen::getResourceDir()) + L"Sync_Complete.wav";
@@ -3379,6 +3404,7 @@ void MainDialog::OnSwapSides(wxCommandEvent& event)
m_bpButtonLeftNewer->setActive(m_bpButtonRightNewer->isActive());
m_bpButtonRightNewer->setActive(tmp);
+ /* for sync preview and "mirror" variant swapping may create strange effect:
tmp = m_bpButtonSyncCreateLeft->isActive();
m_bpButtonSyncCreateLeft->setActive(m_bpButtonSyncCreateRight->isActive());
m_bpButtonSyncCreateRight->setActive(tmp);
@@ -3390,6 +3416,7 @@ void MainDialog::OnSwapSides(wxCommandEvent& event)
tmp = m_bpButtonSyncDirOverwLeft->isActive();
m_bpButtonSyncDirOverwLeft->setActive(m_bpButtonSyncDirOverwRight->isActive());
m_bpButtonSyncDirOverwRight->setActive(tmp);
+ */
//swap grid information
zen::swapGrids(getConfig().mainCfg, folderCmp);
@@ -3427,7 +3454,7 @@ void MainDialog::updateGridViewData()
if (showSyncAction_)
{
- const GridView::StatusSyncPreview result = gridDataView->updateSyncPreview(currentCfg.hideFilteredElements,
+ const GridView::StatusSyncPreview result = gridDataView->updateSyncPreview(!currentCfg.showFilteredElements,
m_bpButtonSyncCreateLeft-> isActive(),
m_bpButtonSyncCreateRight-> isActive(),
m_bpButtonSyncDeleteLeft-> isActive(),
@@ -3475,7 +3502,7 @@ void MainDialog::updateGridViewData()
}
else
{
- const GridView::StatusCmpResult result = gridDataView->updateCmpResult(currentCfg.hideFilteredElements,
+ const GridView::StatusCmpResult result = gridDataView->updateCmpResult(!currentCfg.showFilteredElements,
m_bpButtonLeftOnly-> isActive(),
m_bpButtonRightOnly-> isActive(),
m_bpButtonLeftNewer-> isActive(),
@@ -3518,7 +3545,7 @@ void MainDialog::updateGridViewData()
//navigation tree
if (showSyncAction_)
- treeDataView->updateSyncPreview(currentCfg.hideFilteredElements,
+ treeDataView->updateSyncPreview(!currentCfg.showFilteredElements,
m_bpButtonSyncCreateLeft-> isActive(),
m_bpButtonSyncCreateRight-> isActive(),
m_bpButtonSyncDeleteLeft-> isActive(),
@@ -3529,7 +3556,7 @@ void MainDialog::updateGridViewData()
m_bpButtonEqual-> isActive(),
m_bpButtonConflict-> isActive());
else
- treeDataView->updateCmpResult(currentCfg.hideFilteredElements,
+ treeDataView->updateCmpResult(!currentCfg.showFilteredElements,
m_bpButtonLeftOnly-> isActive(),
m_bpButtonRightOnly-> isActive(),
m_bpButtonLeftNewer-> isActive(),
@@ -3664,51 +3691,38 @@ void MainDialog::updateGuiForFolderPair()
wxWindowUpdateLocker dummy(this);
//adapt delete top folder pair button
- if (additionalFolderPairs.empty())
- m_bpButtonRemovePair->Hide();
- else
- m_bpButtonRemovePair->Show();
+ m_bpButtonRemovePair->Show(!additionalFolderPairs.empty());
m_panelTopLeft->Layout();
//adapt local filter and sync cfg for first folder pair
- if (additionalFolderPairs.empty() &&
- firstFolderPair->getAltCompConfig().get() == nullptr &&
- firstFolderPair->getAltSyncConfig().get() == nullptr &&
- isNullFilter(firstFolderPair->getAltFilterConfig()))
- {
- m_bpButtonAltCompCfg ->Hide();
- m_bpButtonAltSyncCfg ->Hide();
- m_bpButtonLocalFilter->Hide();
-
- setImage(*m_bpButtonSwapSides, GlobalResources::getImage(L"swap"));
- }
- else
- {
- m_bpButtonAltCompCfg ->Show();
- m_bpButtonAltSyncCfg ->Show();
- m_bpButtonLocalFilter->Show();
-
- setImage(*m_bpButtonSwapSides, GlobalResources::getImage(L"swapSlim"));
- }
+ const bool showLocalCfgFirstPair = !additionalFolderPairs.empty() ||
+ firstFolderPair->getAltCompConfig().get() != nullptr ||
+ firstFolderPair->getAltSyncConfig().get() != nullptr ||
+ !isNullFilter(firstFolderPair->getAltFilterConfig());
+
+ m_bpButtonAltCompCfg ->Show(showLocalCfgFirstPair);
+ m_bpButtonAltSyncCfg ->Show(showLocalCfgFirstPair);
+ m_bpButtonLocalFilter->Show(showLocalCfgFirstPair);
+ setImage(*m_bpButtonSwapSides, GlobalResources::getImage(showLocalCfgFirstPair ? L"swapSlim" : L"swap"));
m_panelTopMiddle->Layout();
int addPairMinimalHeight = 0;
int addPairOptimalHeight = 0;
if (!additionalFolderPairs.empty())
{
- int pairHeight = additionalFolderPairs[0]->GetSize().GetHeight();
- addPairMinimalHeight = std::min<double>(1.5, additionalFolderPairs.size()) * pairHeight; //have 0.5 * height indicate that more folders are there
+ const int pairHeight = additionalFolderPairs[0]->GetSize().GetHeight();
+ addPairMinimalHeight = std::min<double>(1.5, additionalFolderPairs.size()) * pairHeight; //have 1.5 * height indicate that more folders are there
addPairOptimalHeight = std::min<double>(globalCfg.gui.maxFolderPairsVisible - 1 + 0.5, //subtract first/main folder pair and add 0.5 to indicate additional folders
additionalFolderPairs.size()) * pairHeight;
addPairOptimalHeight = std::max(addPairOptimalHeight, addPairMinimalHeight); //implicitly handle corrupted values for "maxFolderPairsVisible"
}
+ const int firstPairHeight = m_panelDirectoryPairs->ClientToWindowSize(m_panelTopLeft->GetSize()).GetHeight(); //include m_panelDirectoryPairs window borders!
+
//########################################################################################################################
//wxAUI hack: set minimum height to desired value, then call wxAuiPaneInfo::Fixed() to apply it
- const int panelNewHeight = m_panelDirectoryPairs->ClientToWindowSize(m_panelTopLeft->GetSize()).GetHeight(); //respect m_panelDirectoryPairs window borders!
-
- auiMgr.GetPane(m_panelDirectoryPairs).MinSize(-1, panelNewHeight + addPairOptimalHeight);
+ auiMgr.GetPane(m_panelDirectoryPairs).MinSize(-1, firstPairHeight + addPairOptimalHeight);
auiMgr.GetPane(m_panelDirectoryPairs).Fixed();
auiMgr.Update();
@@ -3717,8 +3731,8 @@ void MainDialog::updateGuiForFolderPair()
auiMgr.Update();
//########################################################################################################################
- //ensure additional folder pairs are at least partially visible
- auiMgr.GetPane(m_panelDirectoryPairs).MinSize(-1, m_panelTopLeft->GetSize().GetHeight() + addPairMinimalHeight);
+ //make sure user cannot fully shrink additional folder pairs
+ auiMgr.GetPane(m_panelDirectoryPairs).MinSize(-1, firstPairHeight + addPairMinimalHeight);
auiMgr.Update();
m_scrolledWindowFolderPairs->Fit(); //adjust scrolled window size
bgstack15