summaryrefslogtreecommitdiff
path: root/ui/main_dlg.cpp
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:12:46 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:12:46 +0200
commitb338e29fd3eaf700f8c8360aa0310048ba941d54 (patch)
tree122f8ef3790d12cd10275ef7453a9e8053322d78 /ui/main_dlg.cpp
parent3.18 (diff)
downloadFreeFileSync-b338e29fd3eaf700f8c8360aa0310048ba941d54.tar.gz
FreeFileSync-b338e29fd3eaf700f8c8360aa0310048ba941d54.tar.bz2
FreeFileSync-b338e29fd3eaf700f8c8360aa0310048ba941d54.zip
3.19
Diffstat (limited to 'ui/main_dlg.cpp')
-rw-r--r--ui/main_dlg.cpp907
1 files changed, 534 insertions, 373 deletions
diff --git a/ui/main_dlg.cpp b/ui/main_dlg.cpp
index c5e8ef72..2256329a 100644
--- a/ui/main_dlg.cpp
+++ b/ui/main_dlg.cpp
@@ -17,7 +17,6 @@
#include <wx/display.h>
#include <wx/app.h>
#include <boost/bind.hpp>
-#include "../shared/system_constants.h"
#include "../library/custom_grid.h"
#include "../shared/custom_button.h"
#include "../shared/custom_combo_box.h"
@@ -97,31 +96,8 @@ public:
case xmlAccess::MERGE_GUI:
case xmlAccess::MERGE_GUI_BATCH:
- if (droppedFiles.size() == 1)
- {
- mainDlg_.loadConfiguration(droppedFiles[0]);
- return false;
- }
- else
- {
- xmlAccess::XmlGuiConfig guiCfg;
- try
- {
- convertConfig(droppedFiles, guiCfg); //throw (xmlAccess::FfsXmlError)
- }
- catch (const xmlAccess::FfsXmlError& error)
- {
- if (error.getSeverity() == xmlAccess::FfsXmlError::WARNING)
- wxMessageBox(error.msg(), _("Warning"), wxOK | wxICON_WARNING);
- else
- {
- wxMessageBox(error.msg(), _("Error"), wxOK | wxICON_ERROR);
- return false;
- }
- }
- mainDlg_.setCurrentConfiguration(guiCfg);
- return false;
- }
+ mainDlg_.loadConfiguration(droppedFiles);
+ return false;
case xmlAccess::MERGE_OTHER:
//=> return true: change directory selection via drag and drop
@@ -177,7 +153,7 @@ private:
virtual MainConfiguration getMainConfig() const
{
- return mainDlg.getCurrentConfiguration().mainCfg;
+ return mainDlg.getConfig().mainCfg;
}
virtual void OnAltSyncCfgChange()
@@ -356,18 +332,30 @@ MainDialog::MainDialog(const wxString& cfgFileName, xmlAccess::XmlGlobalSettings
{
xmlAccess::XmlGuiConfig guiCfg; //structure to receive gui settings, already defaulted!!
- wxString currentConfigFile = cfgFileName; //this one has priority
- if (currentConfigFile.empty()) currentConfigFile = settings.gui.lastUsedConfigFile; //next: suggest name of last used selection
- if (currentConfigFile.empty() || !fileExists(wxToZ(currentConfigFile))) currentConfigFile = lastRunConfigName(); //if above fails...
+ std::vector<wxString> filenames;
+ if (!cfgFileName.empty()) //1. this one has priority
+ filenames.push_back(cfgFileName);
+ else //next: use last used selection
+ {
+ filenames = settings.gui.lastUsedConfigFiles; //2. now try last used files
+
+ //check if one of the files is not existing (this shall not be an error!)
+ if (std::find_if(filenames.begin(), filenames.end(),
+ [](const wxString& filename) { return !fileExists(toZ(filename)); }) != filenames.end())
+ filenames.clear();
+
+ if (filenames.empty())
+ {
+ if (fileExists(toZ(lastRunConfigName()))) //3. try to load auto-save config
+ filenames.push_back(lastRunConfigName());
+ }
+ }
bool loadCfgSuccess = false;
- if (!cfgFileName.empty() || fileExists(wxToZ(currentConfigFile)))
+ if (!filenames.empty())
try
{
//load XML
- std::vector<wxString> filenames;
- filenames.push_back(currentConfigFile);
-
xmlAccess::convertConfig(filenames, guiCfg); //throw (xmlAccess::FfsXmlError)
loadCfgSuccess = true;
@@ -385,7 +373,7 @@ MainDialog::MainDialog(const wxString& cfgFileName, xmlAccess::XmlGlobalSettings
settings,
startComparisonImmediately);
- setLastUsedConfig(currentConfigFile, loadCfgSuccess ? guiCfg : xmlAccess::XmlGuiConfig()); //simulate changed config on parsing errors
+ setLastUsedConfig(filenames, loadCfgSuccess ? guiCfg : xmlAccess::XmlGuiConfig()); //simulate changed config on parsing errors
}
@@ -397,6 +385,8 @@ MainDialog::MainDialog(const xmlAccess::XmlGuiConfig& guiCfg,
init(guiCfg,
settings,
startComparison);
+
+ setLastUsedConfig(std::vector<wxString>(), guiCfg);
}
@@ -479,6 +469,11 @@ void MainDialog::init(const xmlAccess::XmlGuiConfig guiCfg,
m_panelStatusBar ->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSetLayout), NULL, this);
//----------------------------------------------------------------------------------
+ //register context: quick variant selection
+ m_bpButtonCmpConfig ->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSelectCompVariant), NULL, this);
+ m_bpButtonSyncConfig->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSelectSyncVariant), NULL, this);
+
+
globalSettings = &settings;
gridDataView.reset(new zen::GridView);
contextMenu.reset(new wxMenu); //initialize right-click context menu; will be dynamically re-created on each R-mouse-click
@@ -496,8 +491,6 @@ void MainDialog::init(const xmlAccess::XmlGuiConfig guiCfg,
syncPreview.reset(new SyncPreview(this));
- SetTitle(wxString(wxT("FreeFileSync - ")) + _("Folder Comparison and Synchronization"));
-
SetIcon(*GlobalResources::instance().programIcon); //set application icon
//notify about (logical) application main window => program won't quit, but stay on this dialog
@@ -510,7 +503,7 @@ void MainDialog::init(const xmlAccess::XmlGuiConfig guiCfg,
//initialize and load configuration
readGlobalSettings();
- setCurrentConfiguration(guiCfg);
+ setConfig(guiCfg);
//set icons for this dialog
m_buttonCompare->setBitmapFront(GlobalResources::instance().getImage(wxT("compare")));
@@ -618,7 +611,7 @@ void MainDialog::init(const xmlAccess::XmlGuiConfig guiCfg,
//some convenience: if FFS is started with a *.ffs_gui file as commandline parameter AND all directories contained exist, comparison shall be started right off
if (startComparison)
{
- const zen::MainConfiguration currMainCfg = getCurrentConfiguration().mainCfg;
+ const zen::MainConfiguration currMainCfg = getConfig().mainCfg;
const bool allFoldersExist = !DirNotFound()(currMainCfg.firstPair) &&
std::find_if(currMainCfg.additionalPairs.begin(), currMainCfg.additionalPairs.end(),
DirNotFound()) == currMainCfg.additionalPairs.end();
@@ -629,8 +622,6 @@ void MainDialog::init(const xmlAccess::XmlGuiConfig guiCfg,
}
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------------
-
- addFileToCfgHistory(lastRunConfigName()); //make sure <Last session> is always part of history list
}
@@ -651,12 +642,12 @@ void MainDialog::cleanUp(bool saveLastUsedConfig)
m_gridMiddle->release();
m_gridRight ->release();
- writeGlobalSettings(); //set before saving last used config since this will reset "currentConfigFileName"
+ writeGlobalSettings(); //set before saving last used config since "activeConfigFiles" will be replaced
//save configuration
if (saveLastUsedConfig)
{
- const xmlAccess::XmlGuiConfig guiCfg = getCurrentConfiguration();
+ const xmlAccess::XmlGuiConfig guiCfg = getConfig();
try
{
xmlAccess::writeConfig(guiCfg, lastRunConfigName());
@@ -689,9 +680,10 @@ void MainDialog::readGlobalSettings()
m_gridLeft->setColumnAttributes(globalSettings->gui.columnAttribLeft);
m_gridRight->setColumnAttributes(globalSettings->gui.columnAttribRight);
- //load list of last used configuration files (in reverse order)
- std::for_each(globalSettings->gui.cfgFileHistory.rbegin(), globalSettings->gui.cfgFileHistory.rend(),
- boost::bind(&MainDialog::addFileToCfgHistory, this, _1));
+ //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
+ addFileToCfgHistory(cfgFileNames);
//load list of last used folders
std::for_each(globalSettings->gui.folderHistoryLeft.rbegin(),
@@ -738,8 +730,8 @@ void MainDialog::writeGlobalSettings()
if (m_listBoxHistory->GetClientObject(i))
cfgFileHistory.push_back(static_cast<wxClientDataString*>(m_listBoxHistory->GetClientObject(i))->name_);
- globalSettings->gui.cfgFileHistory = cfgFileHistory;
- globalSettings->gui.lastUsedConfigFile = currentConfigFileName;
+ globalSettings->gui.cfgFileHistory = cfgFileHistory;
+ globalSettings->gui.lastUsedConfigFiles = activeConfigFiles;
//write list of last used folders
globalSettings->gui.folderHistoryLeft.clear();
@@ -825,15 +817,18 @@ void MainDialog::OnIdleEvent(wxEvent& event)
event.Skip();
}
+namespace
+{
+//fast replacement for wxString modelling exponential growth
+typedef Zbase<wchar_t> zxString; //for use with UI texts
+}
+
void MainDialog::copySelectionToClipboard(CustomGrid& selectedGrid)
{
const std::set<size_t> selectedRows = getSelectedRows(&selectedGrid);
if (selectedRows.size() > 0)
{
- //fast replacement for wxString modelling exponential growth
- typedef Zbase<wchar_t> zxString;
-
zxString clipboardString; //perf: wxString doesn't model exponential growth and so is out
const int colCount = selectedGrid.GetNumberCols();
@@ -899,7 +894,7 @@ public:
mainDlg->clearStatusBar();
//register abort button
- mainDlg->m_buttonAbort->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ManualDeletionHandler::OnAbortCompare ), NULL, this );
+ mainDlg->m_buttonAbort->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ManualDeletionHandler::OnAbortDeletion), NULL, this );
mainDlg->Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(ManualDeletionHandler::OnKeyPressed), NULL, this);
}
@@ -907,7 +902,7 @@ public:
{
//de-register abort button
mainDlg->Disconnect(wxEVT_CHAR_HOOK, wxKeyEventHandler(ManualDeletionHandler::OnKeyPressed), NULL, this);
- mainDlg->m_buttonAbort->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ManualDeletionHandler::OnAbortCompare ), NULL, this );
+ mainDlg->m_buttonAbort->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ManualDeletionHandler::OnAbortDeletion ), NULL, this );
mainDlg->enableAllElements();
}
@@ -959,7 +954,7 @@ public:
}
private:
- void OnAbortCompare(wxCommandEvent& event) //handle abort button click
+ void OnAbortDeletion(wxCommandEvent& event) //handle abort button click
{
abortRequested = true; //don't throw exceptions in a GUI-Callback!!! (throw zen::AbortThisProcess())
}
@@ -968,7 +963,10 @@ private:
{
const int keyCode = event.GetKeyCode();
if (keyCode == WXK_ESCAPE)
+ {
abortRequested = true; //don't throw exceptions in a GUI-Callback!!! (throw zen::AbortThisProcess())
+ return;
+ }
event.Skip();
}
@@ -1001,12 +999,6 @@ void MainDialog::deleteSelectedFiles(const std::set<size_t>& viewSelectionLeft,
globalSettings->gui.deleteOnBothSides,
globalSettings->gui.useRecyclerForManualDeletion) == ReturnSmallDlg::BUTTON_OKAY)
{
- if (globalSettings->gui.useRecyclerForManualDeletion && !zen::recycleBinExists())
- {
- wxMessageBox(_("Recycle Bin not yet supported for this system!"));
- return;
- }
-
try
{
//handle errors when deleting files/folders
@@ -1048,17 +1040,17 @@ void exstractNames(const FileSystemObject& fsObj, wxString& name, wxString& dir)
GetNames(wxString& nameIn, wxString& dirIn) : name_(nameIn), dir_(dirIn) {}
virtual void visit(const FileMapping& fileObj)
{
- name_ = zToWx(fileObj.getFullName<side>());
- dir_ = zToWx(fileObj.getFullName<side>().BeforeLast(common::FILE_NAME_SEPARATOR));
+ name_ = toWx(fileObj.getFullName<side>());
+ dir_ = toWx(fileObj.getFullName<side>().BeforeLast(FILE_NAME_SEPARATOR));
}
virtual void visit(const SymLinkMapping& linkObj)
{
- name_ = zToWx(linkObj.getFullName<side>());
- dir_ = zToWx(linkObj.getFullName<side>().BeforeLast(common::FILE_NAME_SEPARATOR));
+ name_ = toWx(linkObj.getFullName<side>());
+ dir_ = toWx(linkObj.getFullName<side>().BeforeLast(FILE_NAME_SEPARATOR));
}
virtual void visit(const DirMapping& dirObj)
{
- dir_ = name_ = zToWx(dirObj.getFullName<side>());
+ dir_ = name_ = toWx(dirObj.getFullName<side>());
}
wxString& name_;
@@ -1119,10 +1111,10 @@ void MainDialog::openExternalApplication(size_t rowNumber, bool leftSide, const
if (name.empty())
{
if (leftSide)
- zen::shellExecute(wxString(L"\"") + zToWx(fsObj->getBaseDirPf<LEFT_SIDE>()) + L"\"");
+ zen::shellExecute(wxString(L"\"") + fsObj->getBaseDirPf<LEFT_SIDE>() + "\"");
//zen::shellExecute(wxString(wxT("explorer ")) + L"\"" + zToWx(fsObj->getBaseDirPf<LEFT_SIDE>()) + L"\"");
else
- zen::shellExecute(wxString(L"\"") + zToWx(fsObj->getBaseDirPf<RIGHT_SIDE>()) + L"\"");
+ zen::shellExecute(wxString(L"\"") + fsObj->getBaseDirPf<RIGHT_SIDE>() + "\"");
//zen::shellExecute(wxString(wxT("explorer ")) + L"\"" + zToWx(fsObj->getBaseDirPf<RIGHT_SIDE>()) + L"\"");
return;
}
@@ -1131,8 +1123,8 @@ void MainDialog::openExternalApplication(size_t rowNumber, bool leftSide, const
else
{
//fallback
- dir = zToWx(zen::getFormattedDirectoryName(wxToZ(firstFolderPair->getLeftDir())));
- dirCo = zToWx(zen::getFormattedDirectoryName(wxToZ(firstFolderPair->getRightDir())));
+ dir = toWx(zen::getFormattedDirectoryName(toZ(firstFolderPair->getLeftDir())));
+ dirCo = toWx(zen::getFormattedDirectoryName(toZ(firstFolderPair->getRightDir())));
if (!leftSide)
std::swap(dir, dirCo);
@@ -1177,6 +1169,10 @@ void MainDialog::clearStatusBar()
void MainDialog::disableAllElements(bool enableAbort)
{
+ //when changing consider: comparison, synchronization, manual deletion
+
+ EnableCloseButton(false); //not allowed for synchronization! progress indicator is top window!
+
//disables all elements (except abort button) that might receive user input during long-running processes: comparison, deletion
m_panelViewFilter ->Disable();
m_bpButtonCmpConfig ->Disable();
@@ -1211,6 +1207,8 @@ void MainDialog::disableAllElements(bool enableAbort)
void MainDialog::enableAllElements()
{
+ EnableCloseButton(true);
+
m_panelViewFilter ->Enable();
m_bpButtonCmpConfig ->Enable();
m_panelFilter ->Enable();
@@ -1798,13 +1796,13 @@ void MainDialog::OnContextRim(wxGridEvent& event)
//CONTEXT_EXCLUDE_EXT
if (exFilterCandidateObj.size() > 0 && !exFilterCandidateObj.begin()->second) //non empty && no directory
{
- const Zstring filename = exFilterCandidateObj.begin()->first.AfterLast(common::FILE_NAME_SEPARATOR);
+ const Zstring filename = exFilterCandidateObj.begin()->first.AfterLast(FILE_NAME_SEPARATOR);
if (filename.find(Zchar('.')) != Zstring::npos) //be careful: AfterLast would return the whole string if '.' were not found!
{
const Zstring extension = filename.AfterLast(Zchar('.'));
//add context menu item
- wxMenuItem* menuItemExclExt = new wxMenuItem(contextMenu.get(), wxID_ANY, wxString(_("Exclude via filter:")) + wxT(" ") + wxT("*.") + zToWx(extension));
+ wxMenuItem* menuItemExclExt = new wxMenuItem(contextMenu.get(), wxID_ANY, wxString(_("Exclude via filter:")) + " " + "*." + extension);
menuItemExclExt->SetBitmap(GlobalResources::instance().getImage(wxT("filterSmall")));
contextMenu->Append(menuItemExclExt);
@@ -1821,9 +1819,9 @@ void MainDialog::OnContextRim(wxGridEvent& event)
//CONTEXT_EXCLUDE_OBJ
wxMenuItem* menuItemExclObj = NULL;
if (exFilterCandidateObj.size() == 1)
- menuItemExclObj = new wxMenuItem(contextMenu.get(), wxID_ANY, wxString(_("Exclude via filter:")) + wxT(" ") + zToWx(exFilterCandidateObj.begin()->first.AfterLast(common::FILE_NAME_SEPARATOR)));
+ menuItemExclObj = new wxMenuItem(contextMenu.get(), wxID_ANY, wxString(_("Exclude via filter:")) + " " + exFilterCandidateObj.begin()->first.AfterLast(FILE_NAME_SEPARATOR));
else if (exFilterCandidateObj.size() > 1)
- menuItemExclObj = new wxMenuItem(contextMenu.get(), wxID_ANY, wxString(_("Exclude via filter:")) + wxT(" ") + _("<multiple selection>"));
+ menuItemExclObj = new wxMenuItem(contextMenu.get(), wxID_ANY, wxString(_("Exclude via filter:")) + " " + _("<multiple selection>"));
if (menuItemExclObj != NULL)
{
@@ -1853,7 +1851,7 @@ void MainDialog::OnContextRim(wxGridEvent& event)
{
//some trick to translate default external apps on the fly: 1. "open in explorer" 2. "start directly"
//wxString description = wxGetTranslation(i->first);
- wxString description = zen::translate(i->first);
+ wxString description = zen::translate(i->first.c_str());
if (description.empty())
description = wxT(" "); //wxWidgets doesn't like empty items
@@ -1909,8 +1907,10 @@ void MainDialog::OnContextExcludeExtension(wxCommandEvent& event)
updateFilterButtons();
//do not fully apply filter, just exclude new items
- addExcludeFiltering(gridDataView->getDataTentative(), newExclude);
- //applyFiltering(getCurrentConfiguration().mainCfg, gridDataView->getDataTentative());
+ std::for_each(gridDataView->getDataTentative().begin(), gridDataView->getDataTentative().end(),
+ [&](BaseDirMapping& baseMap) { addHardFiltering(baseMap, newExclude); });
+
+ //applyFiltering(getConfig().mainCfg, gridDataView->getDataTentative());
updateGuiGrid();
if (currentCfg.hideFilteredElements)
@@ -1936,9 +1936,9 @@ void MainDialog::OnContextExcludeObject(wxCommandEvent& event)
if (i != objCont->selectedObjects.begin())
newExclude += Zstr("\n");
- newExclude += common::FILE_NAME_SEPARATOR + i->first;
+ newExclude += FILE_NAME_SEPARATOR + i->first;
if (i->second) //is directory
- newExclude += common::FILE_NAME_SEPARATOR;
+ newExclude += FILE_NAME_SEPARATOR;
}
//add to filter config
@@ -1950,8 +1950,10 @@ void MainDialog::OnContextExcludeObject(wxCommandEvent& event)
updateFilterButtons();
//do not fully apply filter, just exclude new items
- addExcludeFiltering(gridDataView->getDataTentative(), newExclude);
- //applyFiltering(getCurrentConfiguration().mainCfg, gridDataView->getDataTentative());
+ std::for_each(gridDataView->getDataTentative().begin(), gridDataView->getDataTentative().end(),
+ [&](BaseDirMapping& baseMap) { addHardFiltering(baseMap, newExclude); });
+
+ //applyFiltering(getConfig().mainCfg, gridDataView->getDataTentative());
updateGuiGrid();
if (currentCfg.hideFilteredElements)
@@ -2009,18 +2011,18 @@ void MainDialog::OnContextSyncDirRight(wxCommandEvent& event)
void MainDialog::OnContextRimLabelLeft(wxGridEvent& event)
{
- int ctxtElementId = 1000;
-
contextMenu.reset(new wxMenu); //re-create context menu
- contextMenu->Append(++ctxtElementId, _("Customize..."));
- contextMenu->Connect(ctxtElementId, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextCustColumnLeft), NULL, this);
+
+ wxMenuItem* menuItemCustomize = new wxMenuItem(contextMenu.get(), wxID_ANY, _("Customize..."));
+ contextMenu->Append(menuItemCustomize);
+ contextMenu->Connect(menuItemCustomize->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextCustColumnLeft), NULL, this);
contextMenu->AppendSeparator();
- wxMenuItem* itemAutoAdjust = new wxMenuItem(contextMenu.get(), ++ctxtElementId, _("Auto-adjust columns"), wxEmptyString, wxITEM_CHECK);
+ wxMenuItem* itemAutoAdjust = new wxMenuItem(contextMenu.get(), wxID_ANY, _("Auto-adjust columns"), wxEmptyString, wxITEM_CHECK);
contextMenu->Append(itemAutoAdjust);
itemAutoAdjust->Check(globalSettings->gui.autoAdjustColumnsLeft);
- contextMenu->Connect(ctxtElementId, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextAutoAdjustLeft), NULL, this);
+ contextMenu->Connect(itemAutoAdjust->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextAutoAdjustLeft), NULL, this);
PopupMenu(contextMenu.get()); //show context menu
}
@@ -2028,19 +2030,18 @@ void MainDialog::OnContextRimLabelLeft(wxGridEvent& event)
void MainDialog::OnContextRimLabelRight(wxGridEvent& event)
{
- int ctxtElementId = 1000;
-
contextMenu.reset(new wxMenu); //re-create context menu
- contextMenu->Append(++ctxtElementId, _("Customize..."));
- contextMenu->Connect(ctxtElementId, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextCustColumnRight), NULL, this);
+ wxMenuItem* menuItemCustomize = new wxMenuItem(contextMenu.get(), wxID_ANY, _("Customize..."));
+ contextMenu->Append(menuItemCustomize);
+ contextMenu->Connect(menuItemCustomize->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextCustColumnRight), NULL, this);
contextMenu->AppendSeparator();
- wxMenuItem* itemAutoAdjust = new wxMenuItem(contextMenu.get(), ++ctxtElementId, _("Auto-adjust columns"), wxEmptyString, wxITEM_CHECK);
+ wxMenuItem* itemAutoAdjust = new wxMenuItem(contextMenu.get(), wxID_ANY, _("Auto-adjust columns"), wxEmptyString, wxITEM_CHECK);
contextMenu->Append(itemAutoAdjust);
itemAutoAdjust->Check(globalSettings->gui.autoAdjustColumnsRight);
- contextMenu->Connect(ctxtElementId, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextAutoAdjustRight), NULL, this);
+ contextMenu->Connect(itemAutoAdjust->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextAutoAdjustRight), NULL, this);
PopupMenu(contextMenu.get()); //show context menu
}
@@ -2092,20 +2093,19 @@ void MainDialog::OnContextAutoAdjustRight(wxCommandEvent& event)
void MainDialog::OnContextMiddle(wxGridEvent& event)
{
- int contextItemID = 2000;
-
contextMenu.reset(new wxMenu); //re-create context menu
- contextMenu->Append(++contextItemID, _("Include all rows"));
+ wxMenuItem* menuItemInclude = new wxMenuItem(contextMenu.get(), wxID_ANY, _("Include all rows"));
+ contextMenu->Append(menuItemInclude);
if (gridDataView->rowsTotal() == 0)
- contextMenu->Enable(contextItemID, false);
- contextMenu->Connect(contextItemID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextIncludeAll), NULL, this);
-
+ menuItemInclude->Enable(false);
+ contextMenu->Connect(menuItemInclude->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextIncludeAll), NULL, this);
- contextMenu->Append(++contextItemID, _("Exclude all rows"));
+ wxMenuItem* menuItemExclude = new wxMenuItem(contextMenu.get(), wxID_ANY, _("Exclude all rows"));
+ contextMenu->Append(menuItemExclude);
if (gridDataView->rowsTotal() == 0)
- contextMenu->Enable(contextItemID, false);
- contextMenu->Connect(contextItemID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextExcludeAll), NULL, this);
+ menuItemExclude->Enable(false);
+ contextMenu->Connect(menuItemExclude->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextExcludeAll), NULL, this);
PopupMenu(contextMenu.get()); //show context menu
}
@@ -2113,15 +2113,13 @@ void MainDialog::OnContextMiddle(wxGridEvent& event)
void MainDialog::OnContextMiddleLabel(wxGridEvent& event)
{
- int contextItemID = 2000;
-
contextMenu.reset(new wxMenu); //re-create context menu
- wxMenuItem* itemSyncPreview = new wxMenuItem(contextMenu.get(), ++contextItemID, _("Synchronization Preview"));
- contextMenu->Connect(contextItemID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextSyncView), NULL, this);
+ wxMenuItem* itemSyncPreview = new wxMenuItem(contextMenu.get(), wxID_ANY, _("Synchronization Preview"));
+ contextMenu->Connect(itemSyncPreview->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextSyncView), NULL, this);
- wxMenuItem* itemCmpResult = new wxMenuItem(contextMenu.get(), ++contextItemID, _("Comparison Result"));
- contextMenu->Connect(contextItemID, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextComparisonView), NULL, this);
+ wxMenuItem* itemCmpResult = new wxMenuItem(contextMenu.get(), wxID_ANY, _("Comparison Result"));
+ contextMenu->Connect(itemCmpResult->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextComparisonView), NULL, this);
if (syncPreview->previewIsEnabled())
itemSyncPreview->SetBitmap(GlobalResources::instance().getImage(wxT("syncViewSmall")));
@@ -2215,6 +2213,138 @@ void MainDialog::OnContextSyncView(wxCommandEvent& event)
}
+struct CtxtSelectionCmpVar : public wxObject
+{
+ CtxtSelectionCmpVar(CompareVariant var) : compareVar(var) {}
+ CompareVariant compareVar;
+};
+
+
+void MainDialog::OnContextSelectCompVariant(wxMouseEvent& event)
+{
+ contextMenu.reset(new wxMenu); //re-create context menu
+
+ wxMenuItem* itemSizeDate = new wxMenuItem(contextMenu.get(), wxID_ANY, _("File size and date"), L"", wxITEM_RADIO);
+ contextMenu->Append(itemSizeDate);
+ contextMenu->Connect(itemSizeDate->GetId(),
+ wxEVT_COMMAND_MENU_SELECTED,
+ wxCommandEventHandler(MainDialog::OnSetCompVariant),
+ new CtxtSelectionCmpVar(CMP_BY_TIME_SIZE), //ownership passed!
+ this);
+
+ wxMenuItem* itemContent = new wxMenuItem(contextMenu.get(), wxID_ANY, _("File content"), L"", wxITEM_RADIO);
+ contextMenu->Append(itemContent);
+ contextMenu->Connect(itemContent->GetId(),
+ wxEVT_COMMAND_MENU_SELECTED,
+ wxCommandEventHandler(MainDialog::OnSetCompVariant),
+ new CtxtSelectionCmpVar(CMP_BY_CONTENT), //ownership passed!
+ this);
+
+ //---------------------------------------------------------------
+ xmlAccess::XmlGuiConfig cfg = getConfig();
+
+ switch (cfg.mainCfg.compareVar)
+ {
+ case CMP_BY_TIME_SIZE:
+ itemSizeDate->Check();
+ break;
+ case CMP_BY_CONTENT:
+ itemContent->Check();
+ break;
+ }
+
+ PopupMenu(contextMenu.get()); //show context menu
+}
+
+
+struct CtxtSelectionSyncVar : public wxObject
+{
+ CtxtSelectionSyncVar(SyncConfig::Variant var) : syncVar(var) {}
+ SyncConfig::Variant syncVar;
+};
+
+
+void MainDialog::OnContextSelectSyncVariant(wxMouseEvent& event)
+{
+ contextMenu.reset(new wxMenu); //re-create context menu
+
+ wxMenuItem* itemAuto = new wxMenuItem(contextMenu.get(), wxID_ANY, _("<Automatic>"), L"", wxITEM_RADIO);
+ contextMenu->Append(itemAuto);
+ contextMenu->Connect(itemAuto->GetId(),
+ wxEVT_COMMAND_MENU_SELECTED,
+ wxCommandEventHandler(MainDialog::OnSetSyncVariant),
+ new CtxtSelectionSyncVar(SyncConfig::AUTOMATIC), //ownership passed!
+ this);
+
+ wxMenuItem* itemMirror = new wxMenuItem(contextMenu.get(), wxID_ANY, _("Mirror ->>"), L"", wxITEM_RADIO);
+ contextMenu->Append(itemMirror);
+ contextMenu->Connect(itemMirror->GetId(),
+ wxEVT_COMMAND_MENU_SELECTED,
+ wxCommandEventHandler(MainDialog::OnSetSyncVariant),
+ new CtxtSelectionSyncVar(SyncConfig::MIRROR), //ownership passed!
+ this);
+
+ wxMenuItem* itemUpdate = new wxMenuItem(contextMenu.get(), wxID_ANY, _("Update ->"), L"", wxITEM_RADIO);
+ contextMenu->Append(itemUpdate);
+ contextMenu->Connect(itemUpdate->GetId(),
+ wxEVT_COMMAND_MENU_SELECTED,
+ wxCommandEventHandler(MainDialog::OnSetSyncVariant),
+ new CtxtSelectionSyncVar(SyncConfig::UPDATE), //ownership passed!
+ this);
+
+ wxMenuItem* itemCustom = new wxMenuItem(contextMenu.get(), wxID_ANY, _("Custom"), L"", wxITEM_RADIO);
+ contextMenu->Append(itemCustom);
+ contextMenu->Connect(itemCustom->GetId(),
+ wxEVT_COMMAND_MENU_SELECTED,
+ wxCommandEventHandler(MainDialog::OnSetSyncVariant),
+ new CtxtSelectionSyncVar(SyncConfig::CUSTOM), //ownership passed!
+ this);
+
+ //---------------------------------------------------------------
+ xmlAccess::XmlGuiConfig cfg = getConfig();
+
+ switch (cfg.mainCfg.syncConfiguration.var)
+ {
+ case SyncConfig::AUTOMATIC:
+ itemAuto->Check();
+ break;
+ case SyncConfig::MIRROR:
+ itemMirror->Check();
+ break;
+ case SyncConfig::UPDATE:
+ itemUpdate->Check();
+ break;
+ case SyncConfig::CUSTOM:
+ itemCustom->Check();
+ break;
+ }
+
+ PopupMenu(contextMenu.get()); //show context menu
+}
+
+
+void MainDialog::OnSetCompVariant(wxCommandEvent& event)
+{
+ CtxtSelectionCmpVar* selection = dynamic_cast<CtxtSelectionCmpVar*>(event.m_callbackUserData);
+ if (selection)
+ {
+ currentCfg.mainCfg.compareVar = selection->compareVar;
+ applyCompareConfig();
+ }
+}
+
+
+void MainDialog::OnSetSyncVariant(wxCommandEvent& event)
+{
+ CtxtSelectionSyncVar* selection = dynamic_cast<CtxtSelectionSyncVar*>(event.m_callbackUserData);
+ if (selection)
+ {
+ currentCfg.mainCfg.syncConfiguration.var = selection->syncVar;
+ applySyncConfig();
+ }
+}
+
+
void MainDialog::OnDirSelected(wxFileDirPickerEvent& event)
{
//left and right directory text-control and dirpicker are synchronized by MainFolderDragDrop automatically
@@ -2232,58 +2362,69 @@ void MainDialog::OnDirSelected(wxFileDirPickerEvent& event)
wxString getFormattedHistoryElement(const wxString& filename)
{
- Zstring output = wxToZ(filename).AfterLast(common::FILE_NAME_SEPARATOR);
- if (output.EndsWith(Zstr(".ffs_gui")))
- output = output.BeforeLast(Zstr('.'));
- return zToWx(output);
+ wxString output = afterLast(filename, FILE_NAME_SEPARATOR);
+ if (endsWith(output, ".ffs_gui"))
+ output = beforeLast(output, '.');
+ return output;
}
-void MainDialog::addFileToCfgHistory(const wxString& cfgFile)
+void MainDialog::addFileToCfgHistory(const std::vector<wxString>& filenames)
{
- wxString filename = cfgFile;
- if (filename.empty())
- filename = lastRunConfigName();
+ std::deque<bool> selections(m_listBoxHistory->GetCount());
- //only (still) existing files should be included in the list
- if (util::fileExists(wxToZ(filename), 200) == util::EXISTING_FALSE) //potentially slow network access: wait 200ms
- return;
+ std::for_each(filenames.begin(), filenames.end(),
+ [&](wxString filename)
+ {
+ //only (still) existing files should be included in the list
+ if (util::fileExists(toZ(filename), 200) == util::EXISTING_FALSE) //potentially slow network access: wait 200ms
+ return;
- int posFound = -1;
+ int posFound = -1;
- for (int i = 0; i < static_cast<int>(m_listBoxHistory->GetCount()); ++i)
- if (m_listBoxHistory->GetClientObject(i))
+ for (int i = 0; i < static_cast<int>(m_listBoxHistory->GetCount()); ++i)
{
- const wxString& filenameTmp = static_cast<wxClientDataString*>(m_listBoxHistory->GetClientObject(i))->name_;
-
- //tests if the same filenames are specified, even if they are relative to the current working directory/include symlinks or \\?\ prefix
- if (util::sameFileSpecified(wxToZ(filename), wxToZ(filenameTmp)))
+ wxClientDataString* cData = dynamic_cast<wxClientDataString*>(m_listBoxHistory->GetClientObject(i));
+ if (cData)
{
- posFound = i;
- break;
+ const wxString& filenameTmp = cData->name_;
+
+ //tests if the same filenames are specified, even if they are relative to the current working directory/include symlinks or \\?\ prefix
+ if (util::sameFileSpecified(toZ(filename), toZ(filenameTmp)))
+ {
+ posFound = i;
+ break;
+ }
}
}
- if (posFound != -1)
- {
- //if entry is in the list, then jump to element
- m_listBoxHistory->SetSelection(posFound);
- }
- else
- {
- int newPos = -1;
- //the default config file should receive another name on GUI
- if (util::sameFileSpecified(wxToZ(lastRunConfigName()), wxToZ(filename)))
- newPos = m_listBoxHistory->Append(_("<Last session>"), new wxClientDataString(filename)); //insert at beginning of list
+ if (posFound != -1)
+ selections[posFound] = true;
else
- newPos = m_listBoxHistory->Append(getFormattedHistoryElement(filename), new wxClientDataString(filename)); //insert at beginning of list
+ {
+ int newPos = -1;
+ //the default config file should receive a different name on GUI
+ if (util::sameFileSpecified(toZ(lastRunConfigName()), toZ(filename)))
+ newPos = m_listBoxHistory->Append(_("<Last session>"), new wxClientDataString(filename));
+ else
+ newPos = m_listBoxHistory->Append(getFormattedHistoryElement(filename), new wxClientDataString(filename));
- m_listBoxHistory->SetSelection(newPos);
- }
+ selections.insert(selections.begin() + newPos, true);
+ }
+ });
+
+ assert(selections.size() == m_listBoxHistory->GetCount());
- //keep maximal size of history list
- //if (m_comboHistory->GetCount() > globalSettings->gui.cfgHistoryMax)
- // m_comboHistory->Delete(globalSettings->gui.cfgHistoryMax);
+ //do not apply selections immediately but only when needed!
+ //this prevents problems with m_listBoxHistory losing keyboard selection focus if identical selection is redundantly reapplied
+ for (int pos = 0; pos < static_cast<int>(selections.size()); ++pos)
+ if (m_listBoxHistory->IsSelected(pos) != selections[pos])
+ {
+ if (selections[pos])
+ m_listBoxHistory->SetSelection(pos);
+ else
+ m_listBoxHistory->Deselect(pos);
+ }
}
@@ -2307,33 +2448,35 @@ void MainDialog::OnSaveConfig(wxCommandEvent& event)
bool MainDialog::trySaveConfig() //return true if saved successfully
{
- wxString defaultFileName = currentConfigFileName.empty() ? wxT("SyncSettings.ffs_gui") : currentConfigFileName;
- //attention: currentConfigFileName may be an imported *.ffs_batch file! We don't want to overwrite it with a GUI config!
+ wxString defaultFileName = activeConfigFiles.size() == 1 && activeConfigFiles[0] != lastRunConfigName() ? activeConfigFiles[0] : wxT("SyncSettings.ffs_gui");
+ //attention: activeConfigFiles may be an imported *.ffs_batch file! We don't want to overwrite it with a GUI config!
if (defaultFileName.EndsWith(wxT(".ffs_batch")))
defaultFileName.Replace(wxT(".ffs_batch"), wxT(".ffs_gui"), false);
-
wxFileDialog filePicker(this,
wxEmptyString,
wxEmptyString,
defaultFileName,
- wxString(_("FreeFileSync configuration")) + wxT(" (*.ffs_gui)|*.ffs_gui"), wxFD_SAVE); //creating this on freestore leads to memleak!
+ wxString(_("FreeFileSync configuration")) + wxT(" (*.ffs_gui)|*.ffs_gui"),
+ wxFD_SAVE | wxFD_OVERWRITE_PROMPT); //creating this on freestore leads to memleak!
if (filePicker.ShowModal() == wxID_OK)
{
- const wxString newFileName = filePicker.GetPath();
+ const wxString filename = filePicker.GetPath();
+ const xmlAccess::XmlGuiConfig guiCfg = getConfig();
- if (zen::fileExists(wxToZ(newFileName)))
+ //write config to XML
+ try
{
- if (showQuestionDlg(ReturnQuestionDlg::BUTTON_YES | ReturnQuestionDlg::BUTTON_CANCEL,
- wxString(_("File already exists. Overwrite?")) + wxT(" \"") + newFileName + wxT("\"")) != ReturnQuestionDlg::BUTTON_YES)
- return trySaveConfig(); //retry
- }
+ xmlAccess::writeConfig(guiCfg, filename);
+ setLastUsedConfig(filename, guiCfg);
- if (writeConfigurationToXml(newFileName))
- {
pushStatusInformation(_("Configuration saved!"));
return true;
}
+ catch (const xmlAccess::FfsXmlError& error)
+ {
+ wxMessageBox(error.msg().c_str(), _("Error"), wxOK | wxICON_ERROR);
+ }
}
return false;
@@ -2344,12 +2487,19 @@ void MainDialog::OnLoadConfig(wxCommandEvent& event)
{
wxFileDialog filePicker(this,
wxEmptyString,
- beforeLast(currentConfigFileName, common::FILE_NAME_SEPARATOR), //set default dir: empty string if "currentConfigFileName" is empty or has no path separator
+ beforeLast(activeConfigFiles.size() == 1 && activeConfigFiles[0] != lastRunConfigName() ? activeConfigFiles[0] : wxString(), FILE_NAME_SEPARATOR), //set default dir: empty string if "activeConfigFiles" is empty or has no path separator
wxEmptyString,
- wxString(_("FreeFileSync configuration")) + wxT(" (*.ffs_gui;*.ffs_batch)|*.ffs_gui;*.ffs_batch"), wxFD_OPEN);
+ wxString(_("FreeFileSync configuration")) + wxT(" (*.ffs_gui;*.ffs_batch)|*.ffs_gui;*.ffs_batch"),
+ wxFD_OPEN | wxFD_MULTIPLE);
if (filePicker.ShowModal() == wxID_OK)
- loadConfiguration(filePicker.GetPath());
+ {
+ wxArrayString tmp;
+ filePicker.GetPaths(tmp);
+ std::vector<wxString> fileNames(tmp.begin(), tmp.end());
+
+ loadConfiguration(fileNames);
+ }
}
@@ -2358,21 +2508,33 @@ void MainDialog::OnNewConfig(wxCommandEvent& event)
if (!saveOldConfig()) //notify user about changed settings
return;
- setCurrentConfiguration(xmlAccess::XmlGuiConfig());
+ xmlAccess::XmlGuiConfig emptyCfg;
+ setConfig(emptyCfg);
- SetTitle(wxString(wxT("FreeFileSync - ")) + _("Folder Comparison and Synchronization"));
- currentConfigFileName.clear();
+ setLastUsedConfig(std::vector<wxString>(), emptyCfg);
}
void MainDialog::OnLoadFromHistory(wxCommandEvent& event)
{
- if (event.GetClientObject())
+ wxArrayInt selections;
+ m_listBoxHistory->GetSelections(selections);
+
+ std::vector<wxString> filenames;
+ std::for_each(selections.begin(), selections.end(),
+ [&](int pos)
{
- const wxString filename = static_cast<wxClientDataString*>(event.GetClientObject())->name_;
- loadConfiguration(filename);
+ wxClientDataString* cData = dynamic_cast<wxClientDataString*>(m_listBoxHistory->GetClientObject(pos));
+ if (cData)
+ filenames.push_back(cData->name_);
+ });
- addFileToCfgHistory(currentConfigFileName); //in case user cancelled saving old config: restore selection to currently active config file
+ if (!filenames.empty())
+ {
+ loadConfiguration(filenames);
+
+ //in case user cancelled saving old config, selection is wrong: so reapply it!
+ addFileToCfgHistory(activeConfigFiles);
}
}
@@ -2380,9 +2542,11 @@ void MainDialog::OnLoadFromHistory(wxCommandEvent& event)
bool MainDialog::saveOldConfig() //return false on user abort
{
//notify user about changed settings
- if (globalSettings->optDialogs.popupOnConfigChange && !currentConfigFileName.empty()) //only if check is active and non-default config file loaded
+ if (globalSettings->optDialogs.popupOnConfigChange &&
+ //only if check is active and non-default config file loaded
+ (activeConfigFiles.size() != 1 || activeConfigFiles[0] != lastRunConfigName()))
{
- if (lastConfigurationSaved != getCurrentConfiguration())
+ if (lastConfigurationSaved != getConfig())
{
bool dontShowAgain = !globalSettings->optDialogs.popupOnConfigChange;
@@ -2408,14 +2572,46 @@ bool MainDialog::saveOldConfig() //return false on user abort
void MainDialog::loadConfiguration(const wxString& filename)
{
- if (!filename.IsEmpty())
+ std::vector<wxString> filenames;
+ filenames.push_back(filename);
+
+ loadConfiguration(filenames);
+}
+
+
+void MainDialog::loadConfiguration(const std::vector<wxString>& filenames)
+{
+ if (filenames.empty())
+ return;
+
+ if (!saveOldConfig())
+ return;
+
+ //load XML
+ xmlAccess::XmlGuiConfig newGuiCfg; //structure to receive gui settings, already defaulted!!
+ try
{
- if (!saveOldConfig())
- return;
+ //allow reading batch configurations also
+ xmlAccess::convertConfig(filenames, newGuiCfg); //throw (xmlAccess::FfsXmlError)
- if (readConfigurationFromXml(filename))
- pushStatusInformation(_("Configuration loaded!"));
+ setLastUsedConfig(filenames, newGuiCfg);
+ pushStatusInformation(_("Configuration loaded!"));
}
+ catch (const xmlAccess::FfsXmlError& error)
+ {
+ if (error.getSeverity() == xmlAccess::FfsXmlError::WARNING)
+ {
+ setLastUsedConfig(filenames, xmlAccess::XmlGuiConfig()); //simulate changed config on parsing errors
+ wxMessageBox(error.msg(), _("Warning"), wxOK | wxICON_WARNING);
+ }
+ else
+ {
+ wxMessageBox(error.msg(), _("Error"), wxOK | wxICON_ERROR);
+ return;
+ }
+ }
+
+ setConfig(newGuiCfg);
}
@@ -2424,21 +2620,27 @@ void MainDialog::OnCfgHistoryKeyEvent(wxKeyEvent& event)
const int keyCode = event.GetKeyCode();
if (keyCode == WXK_DELETE || keyCode == WXK_NUMPAD_DELETE)
{
- //try to delete the currently selected config history item
- //const int selectedItem = m_listBoxHistory->GetCurrentSelection();
- const int selectedItem = m_listBoxHistory->GetSelection();
- if (selectedItem != wxNOT_FOUND)
+ //delete currently selected config history items
+ wxArrayInt tmp;
+ m_listBoxHistory->GetSelections(tmp);
+
+ std::set<int> selections(tmp.begin(), tmp.end()); //sort ascending!
+
+ int shift = 0;
+ std::for_each(selections.begin(), selections.end(),
+ [&](int pos)
{
- m_listBoxHistory->Delete(selectedItem);
+ m_listBoxHistory->Delete(pos + shift);
+ --shift;
+ });
- //set selection on next element
- if (m_listBoxHistory->GetCount() > 0)
- {
- int newSelection = selectedItem;
- if (newSelection >= static_cast<int>(m_listBoxHistory->GetCount()))
- newSelection = m_listBoxHistory->GetCount() - 1;
- m_listBoxHistory->SetSelection(newSelection);
- }
+ //set active selection on next element to allow "batch-deletion" by holding down DEL key
+ if (!selections.empty() && m_listBoxHistory->GetCount() > 0)
+ {
+ int newSelection = *selections.begin();
+ if (newSelection >= static_cast<int>(m_listBoxHistory->GetCount()))
+ newSelection = m_listBoxHistory->GetCount() - 1;
+ m_listBoxHistory->SetSelection(newSelection);
}
return; //"swallow" event
@@ -2450,6 +2652,7 @@ void MainDialog::OnCfgHistoryKeyEvent(wxKeyEvent& event)
void MainDialog::OnClose(wxCloseEvent& event)
{
+ /*
if (m_buttonAbort->IsShown()) //delegate to "abort" button if available
{
wxCommandEvent dummy(wxEVT_COMMAND_BUTTON_CLICKED); //simulate button click
@@ -2461,18 +2664,21 @@ void MainDialog::OnClose(wxCloseEvent& event)
return;
}
}
- else //regular destruction handling
+ */
+
+ //regular destruction handling
+ if (event.CanVeto())
{
- if (event.CanVeto())
+ const bool cancelled = !saveOldConfig(); //notify user about changed settings
+ if (cancelled)
{
- const bool cancelled = !saveOldConfig(); //notify user about changed settings
- if (cancelled)
- {
- event.Veto();
- return;
- }
+ //attention: this Veto() does NOT cancel system shutdown: application will block
+ //in saveOldConfig() within a modal dialog, so system will just kill the app
+ event.Veto();
+ return;
}
}
+
Destroy();
}
@@ -2516,80 +2722,30 @@ void MainDialog::OnSetSyncDirection(FFSSyncDirectionEvent& event)
}
-bool MainDialog::readConfigurationFromXml(const wxString& filename)
+void MainDialog::setLastUsedConfig(const wxString& filename, const xmlAccess::XmlGuiConfig& guiConfig)
{
- //load XML
- xmlAccess::XmlGuiConfig newGuiCfg; //structure to receive gui settings, already defaulted!!
- bool parsingError = true;
- try
- {
- //allow reading batch configurations also
- std::vector<wxString> filenames;
- filenames.push_back(filename);
-
- xmlAccess::convertConfig(filenames, newGuiCfg); //throw (xmlAccess::FfsXmlError)
-
- parsingError = false;
- }
- catch (const xmlAccess::FfsXmlError& error)
- {
- if (error.getSeverity() == xmlAccess::FfsXmlError::WARNING)
- wxMessageBox(error.msg(), _("Warning"), wxOK | wxICON_WARNING);
- else
- {
- wxMessageBox(error.msg(), _("Error"), wxOK | wxICON_ERROR);
- return false;
- }
- }
-
- setCurrentConfiguration(newGuiCfg);
-
- setLastUsedConfig(filename, parsingError ? xmlAccess::XmlGuiConfig() : newGuiCfg); //simulate changed config on parsing errors
-
- return !parsingError;
+ std::vector<wxString> filenames;
+ filenames.push_back(filename);
+ setLastUsedConfig(filenames, guiConfig);
}
-void MainDialog::setLastUsedConfig(const wxString& filename, const xmlAccess::XmlGuiConfig& guiConfig)
+void MainDialog::setLastUsedConfig(const std::vector<wxString>& filenames, const xmlAccess::XmlGuiConfig& guiConfig)
{
- addFileToCfgHistory(filename); //put filename on list of last used config files
-
- //set title
- if (filename.empty() || filename == lastRunConfigName())
- {
- SetTitle(wxString(wxT("FreeFileSync - ")) + _("Folder Comparison and Synchronization"));
- currentConfigFileName.clear();
- }
- else
- {
- SetTitle(filename);
- currentConfigFileName = filename;
- }
-
+ activeConfigFiles = filenames;
lastConfigurationSaved = guiConfig;
-}
+ addFileToCfgHistory(activeConfigFiles); //put filename on list of last used config files
-bool MainDialog::writeConfigurationToXml(const wxString& filename)
-{
- const xmlAccess::XmlGuiConfig guiCfg = getCurrentConfiguration();
-
- //write config to XML
- try
- {
- xmlAccess::writeConfig(guiCfg, filename);
- setLastUsedConfig(filename, guiCfg);
- return true;
- }
- catch (const xmlAccess::FfsXmlError& error)
- {
- wxMessageBox(error.msg().c_str(), _("Error"), wxOK | wxICON_ERROR);
- return false;
- }
+ //set title
+ if (activeConfigFiles.size() == 1 && activeConfigFiles[0] != lastRunConfigName())
+ SetTitle(activeConfigFiles[0]);
+ else
+ SetTitle(wxString(wxT("FreeFileSync - ")) + _("Folder Comparison and Synchronization"));
}
-void MainDialog::setCurrentConfiguration(const xmlAccess::XmlGuiConfig& newGuiCfg)
+void MainDialog::setConfig(const xmlAccess::XmlGuiConfig& newGuiCfg)
{
currentCfg = newGuiCfg;
@@ -2608,13 +2764,13 @@ void MainDialog::setCurrentConfiguration(const xmlAccess::XmlGuiConfig& newGuiCf
updateFilterButtons();
//set first folder pair
- firstFolderPair->setValues(zToWx(currentCfg.mainCfg.firstPair.leftDirectory),
- zToWx(currentCfg.mainCfg.firstPair.rightDirectory),
+ firstFolderPair->setValues(toWx(currentCfg.mainCfg.firstPair.leftDirectory),
+ toWx(currentCfg.mainCfg.firstPair.rightDirectory),
currentCfg.mainCfg.firstPair.altSyncConfig,
currentCfg.mainCfg.firstPair.localFilter);
- addLeftFolderToHistory( zToWx(currentCfg.mainCfg.firstPair.leftDirectory)); //another hack: wxCombobox::Insert() asynchronously sends message
- addRightFolderToHistory(zToWx(currentCfg.mainCfg.firstPair.rightDirectory)); //overwriting a later wxCombobox::SetValue()!!! :(
+ addLeftFolderToHistory( toWx(currentCfg.mainCfg.firstPair.leftDirectory)); //another hack: wxCombobox::Insert() asynchronously sends message
+ addRightFolderToHistory(toWx(currentCfg.mainCfg.firstPair.rightDirectory)); //overwriting a later wxCombobox::SetValue()!!! :(
//clear existing additional folder pairs
clearAddFolderPairs();
@@ -2641,22 +2797,22 @@ void MainDialog::setCurrentConfiguration(const xmlAccess::XmlGuiConfig& newGuiCf
inline
FolderPairEnh getEnhancedPair(const DirectoryPair* panel)
{
- return FolderPairEnh(wxToZ(panel->getLeftDir()),
- wxToZ(panel->getRightDir()),
+ return FolderPairEnh(toZ(panel->getLeftDir()),
+ toZ(panel->getRightDir()),
panel->getAltSyncConfig(),
panel->getAltFilterConfig());
}
-xmlAccess::XmlGuiConfig MainDialog::getCurrentConfiguration() const
+xmlAccess::XmlGuiConfig MainDialog::getConfig() const
{
xmlAccess::XmlGuiConfig guiCfg = currentCfg;
//load settings whose ownership lies not in currentCfg:
//first folder pair
- guiCfg.mainCfg.firstPair = FolderPairEnh(wxToZ(firstFolderPair->getLeftDir()),
- wxToZ(firstFolderPair->getRightDir()),
+ guiCfg.mainCfg.firstPair = FolderPairEnh(toZ(firstFolderPair->getLeftDir()),
+ toZ(firstFolderPair->getRightDir()),
firstFolderPair->getAltSyncConfig(),
firstFolderPair->getAltFilterConfig());
@@ -2679,15 +2835,15 @@ const wxString& MainDialog::lastRunConfigName()
}
-void MainDialog::refreshGridAfterFilterChange(const int delay)
+void MainDialog::refreshGridAfterFilterChange(int delay)
{
//signal UI that grids need to be refreshed on next Update()
m_gridLeft ->ForceRefresh();
m_gridMiddle->ForceRefresh();
m_gridRight ->ForceRefresh();
- m_gridLeft ->Update(); //
- m_gridMiddle->Update(); //show changes resulting from ForceRefresh()
- m_gridRight ->Update(); //
+ //m_gridLeft ->Update(); //
+ //m_gridMiddle->Update(); //show changes resulting from ForceRefresh()
+ //m_gridRight ->Update(); //
if (currentCfg.hideFilteredElements)
{
@@ -2732,13 +2888,14 @@ void MainDialog::OnConfigureFilter(wxCommandEvent& event)
void MainDialog::OnGlobalFilterOpenContext(wxCommandEvent& event)
{
- const int menuId = 1234;
contextMenu.reset(new wxMenu); //re-create context menu
- contextMenu->Append(menuId, _("Clear filter settings"));
- contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnGlobalFilterRemConfirm), NULL, this);
+
+ wxMenuItem* itemClear = new wxMenuItem(contextMenu.get(), wxID_ANY, _("Clear filter settings"));
+ contextMenu->Append(itemClear);
+ contextMenu->Connect(itemClear->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnGlobalFilterRemConfirm), NULL, this);
if (isNullFilter(currentCfg.mainCfg.globalFilter))
- contextMenu->Enable(menuId, false); //disable menu item, if clicking wouldn't make sense anyway
+ contextMenu->Enable(itemClear->GetId(), false); //disable menu item, if clicking wouldn't make sense anyway
PopupMenu(contextMenu.get()); //show context menu
}
@@ -2950,12 +3107,12 @@ void MainDialog::updateFilterButtons()
//global filter: test for Null-filter
if (isNullFilter(currentCfg.mainCfg.globalFilter))
{
- m_bpButtonFilter->SetBitmapLabel(GlobalResources::instance().getImage(wxT("filterOff")));
+ setBitmapLabel(*m_bpButtonFilter, GlobalResources::instance().getImage(wxT("filterOff")));
m_bpButtonFilter->SetToolTip(_("No filter selected"));
}
else
{
- m_bpButtonFilter->SetBitmapLabel(GlobalResources::instance().getImage(wxT("filterOn")));
+ setBitmapLabel(*m_bpButtonFilter, GlobalResources::instance().getImage(wxT("filterOn")));
m_bpButtonFilter->SetToolTip(_("Filter is active"));
}
@@ -2987,7 +3144,7 @@ void MainDialog::OnCompare(wxCommandEvent& event)
//class handling status display and error messages
CompareStatusHandler statusHandler(*this);
- const std::vector<zen::FolderPairCfg> cmpConfig = zen::extractCompareCfg(getCurrentConfiguration().mainCfg);
+ const std::vector<zen::FolderPairCfg> cmpConfig = zen::extractCompareCfg(getConfig().mainCfg);
//GUI mode: place directory locks on directories isolated(!) during both comparison and synchronization
LockHolder dummy2;
@@ -2998,8 +3155,7 @@ void MainDialog::OnCompare(wxCommandEvent& event)
}
//begin comparison
- zen::CompareProcess comparison(currentCfg.mainCfg.handleSymlinks,
- globalSettings->fileTimeTolerance,
+ zen::CompareProcess comparison(globalSettings->fileTimeTolerance,
globalSettings->optDialogs,
statusHandler);
@@ -3013,7 +3169,7 @@ void MainDialog::OnCompare(wxCommandEvent& event)
//play (optional) sound notification after sync has completed (GUI and batch mode)
const wxString soundFile = zen::getResourceDir() + wxT("Compare_Complete.wav");
- if (fileExists(wxToZ(soundFile)))
+ if (fileExists(toZ(soundFile)))
wxSound::Play(soundFile, wxSOUND_ASYNC);
}
catch (GuiAbortProcess&)
@@ -3120,45 +3276,53 @@ void MainDialog::OnSyncSettings(wxCommandEvent& event)
}
-void MainDialog::OnCmpSettings(wxCommandEvent& event)
+void MainDialog::applyCompareConfig()
{
- //show window right next to the compare-config button
- wxPoint windowPos = m_bpButtonCmpConfig->GetScreenPosition();
- windowPos.x += m_bpButtonCmpConfig->GetSize().GetWidth() + 5;
+ //update compare variant name
+ m_staticTextCmpVariant->SetLabel(wxString(wxT("(")) + getVariantName(currentCfg.mainCfg.compareVar) + wxT(")"));
+ m_panelTopButtons->Layout(); //adapt layout for variant text
- const CompareVariant compareVarOld = currentCfg.mainCfg.compareVar;
- const SymLinkHandling handleSymlinksOld = currentCfg.mainCfg.handleSymlinks;
+ //disable the sync button
+ syncPreview->enableSynchronization(false);
- if (zen::showCompareCfgDialog(windowPos,
- currentCfg.mainCfg.compareVar,
- currentCfg.mainCfg.handleSymlinks) == ReturnSmallDlg::BUTTON_OKAY &&
- //check if settings were changed at all
- (compareVarOld != currentCfg.mainCfg.compareVar ||
- handleSymlinksOld != currentCfg.mainCfg.handleSymlinks))
+ //clear grids
+ gridDataView->clearAllRows();
+ updateGuiGrid();
+
+ //convenience: change sync view
+ switch (currentCfg.mainCfg.compareVar)
{
- //update compare variant name
- m_staticTextCmpVariant->SetLabel(wxString(wxT("(")) + getVariantName(currentCfg.mainCfg.compareVar) + wxT(")"));
- m_panelTopButtons->Layout(); //adapt layout for variant text
+ case CMP_BY_TIME_SIZE:
+ syncPreview->enablePreview(true);
+ break;
+ case CMP_BY_CONTENT:
+ syncPreview->enablePreview(false);
+ break;
+ }
- //disable the sync button
- syncPreview->enableSynchronization(false);
+ m_buttonCompare->SetFocus();
+}
- //clear grids
- gridDataView->clearAllRows();
- updateGuiGrid();
- //convenience: change sync view
- switch (currentCfg.mainCfg.compareVar)
- {
- case CMP_BY_TIME_SIZE:
- syncPreview->enablePreview(true);
- break;
- case CMP_BY_CONTENT:
- syncPreview->enablePreview(false);
- break;
- }
+void MainDialog::OnCmpSettings(wxCommandEvent& event)
+{
+ //show window right next to the compare-config button
+ //wxPoint windowPos = m_bpButtonCmpConfig->GetScreenPosition();
+ //windowPos.x += m_bpButtonCmpConfig->GetSize().GetWidth() + 5;
- m_buttonCompare->SetFocus();
+ CompareVariant compareVarNew = currentCfg.mainCfg.compareVar;
+ SymLinkHandling handleSymlinkNew = currentCfg.mainCfg.handleSymlinks;
+
+ if (zen::showCompareCfgDialog(compareVarNew,
+ handleSymlinkNew) == ReturnSmallDlg::BUTTON_OKAY &&
+ //check if settings were changed at all
+ (compareVarNew != currentCfg.mainCfg.compareVar ||
+ handleSymlinkNew != currentCfg.mainCfg.handleSymlinks))
+ {
+ currentCfg.mainCfg.compareVar = compareVarNew;
+ currentCfg.mainCfg.handleSymlinks = handleSymlinkNew;
+
+ applyCompareConfig();
}
}
@@ -3183,7 +3347,7 @@ void MainDialog::OnStartSync(wxCommandEvent& event)
bool dontShowAgain = false;
if (zen::showSyncPreviewDlg(
- getCurrentConfiguration().mainCfg.getSyncVariantName(),
+ getConfig().mainCfg.getSyncVariantName(),
zen::SyncStatistics(gridDataView->getDataTentative()),
dontShowAgain) != ReturnSmallDlg::BUTTON_OKAY)
return;
@@ -3198,8 +3362,10 @@ void MainDialog::OnStartSync(wxCommandEvent& event)
{
//PERF_START;
+ wxString activeFileName = activeConfigFiles.size() == 1 && activeConfigFiles[0] != lastRunConfigName() ? activeConfigFiles[0] : wxString();
+
//class handling status updates and error messages
- SyncStatusHandler statusHandler(this, currentCfg.handleError, zen::extractJobName(currentConfigFileName));
+ SyncStatusHandler statusHandler(this, currentCfg.handleError, zen::extractJobName(activeFileName));
FolderComparison& dataToSync = gridDataView->getDataTentative();
@@ -3219,7 +3385,7 @@ void MainDialog::OnStartSync(wxCommandEvent& event)
globalSettings->copyFilePermissions,
statusHandler);
- const std::vector<zen::FolderPairSyncCfg> syncProcessCfg = zen::extractSyncCfg(getCurrentConfiguration().mainCfg);
+ const std::vector<zen::FolderPairSyncCfg> syncProcessCfg = zen::extractSyncCfg(getConfig().mainCfg);
//make sure syncProcessCfg and dataToSync have same size and correspond!
if (syncProcessCfg.size() != dataToSync.size())
@@ -3229,7 +3395,7 @@ void MainDialog::OnStartSync(wxCommandEvent& event)
//play (optional) sound notification after sync has completed (GUI and batch mode)
const wxString soundFile = zen::getResourceDir() + wxT("Sync_Complete.wav");
- if (fileExists(wxToZ(soundFile)))
+ if (fileExists(toZ(soundFile)))
wxSound::Play(soundFile, wxSOUND_ASYNC);
}
catch (GuiAbortProcess&)
@@ -3452,7 +3618,7 @@ void MainDialog::OnSwapSides(wxCommandEvent& event)
m_bpButtonSyncDirOverwRight->setActive(tmp);
//swap grid information
- zen::swapGrids(getCurrentConfiguration().mainCfg, gridDataView->getDataTentative());
+ zen::swapGrids(getConfig().mainCfg, gridDataView->getDataTentative());
updateGuiGrid();
}
@@ -3651,14 +3817,14 @@ void MainDialog::OnAddFolderPair(wxCommandEvent& event)
wxWindowUpdateLocker dummy(this); //avoid display distortion
std::vector<FolderPairEnh> newPairs;
- newPairs.push_back(getCurrentConfiguration().mainCfg.firstPair);
+ newPairs.push_back(getConfig().mainCfg.firstPair);
addFolderPair(newPairs, true); //add pair in front of additonal pairs
//clear first pair
const FolderPairEnh cfgEmpty;
- firstFolderPair->setValues(zToWx(cfgEmpty.leftDirectory),
- zToWx(cfgEmpty.rightDirectory),
+ firstFolderPair->setValues(toWx(cfgEmpty.leftDirectory),
+ toWx(cfgEmpty.rightDirectory),
cfgEmpty.altSyncConfig,
cfgEmpty.localFilter);
@@ -3673,7 +3839,7 @@ void MainDialog::OnAddFolderPair(wxCommandEvent& event)
void MainDialog::updateFilterConfig()
{
- applyFiltering(gridDataView->getDataTentative(), getCurrentConfiguration().mainCfg);
+ applyFiltering(gridDataView->getDataTentative(), getConfig().mainCfg);
refreshGridAfterFilterChange(400);
}
@@ -3681,7 +3847,7 @@ void MainDialog::updateFilterConfig()
void MainDialog::applySyncConfig()
{
//update sync variant name
- m_staticTextSyncVariant->SetLabel(wxString(wxT("(")) + getCurrentConfiguration().mainCfg.getSyncVariantName() + wxT(")"));
+ m_staticTextSyncVariant->SetLabel(wxString(wxT("(")) + getConfig().mainCfg.getSyncVariantName() + wxT(")"));
m_panelTopButtons->Layout(); //adapt layout for variant text
@@ -3708,7 +3874,7 @@ void MainDialog::applySyncConfig()
wxWindow* parent_;
} redetCallback(globalSettings->optDialogs.warningSyncDatabase, this);
- zen::redetermineSyncDirection(getCurrentConfiguration().mainCfg, gridDataView->getDataTentative(), &redetCallback);
+ zen::redetermineSyncDirection(getConfig().mainCfg, gridDataView->getDataTentative(), &redetCallback);
updateGuiGrid();
}
@@ -3723,8 +3889,8 @@ void MainDialog::OnRemoveTopFolderPair(wxCommandEvent& event)
const FolderPairEnh cfgSecond = getEnhancedPair(additionalFolderPairs[0]);
//reset first pair
- firstFolderPair->setValues(zToWx(cfgSecond.leftDirectory),
- zToWx(cfgSecond.rightDirectory),
+ firstFolderPair->setValues(toWx(cfgSecond.leftDirectory),
+ toWx(cfgSecond.rightDirectory),
cfgSecond.altSyncConfig,
cfgSecond.localFilter);
@@ -3780,43 +3946,55 @@ void MainDialog::updateGuiForFolderPair()
m_bpButtonLocalFilter->Hide();
m_bpButtonAltSyncCfg->Hide();
- m_bpButtonSwapSides->SetBitmapLabel(GlobalResources::instance().getImage(wxT("swap")));
+ setBitmapLabel(*m_bpButtonSwapSides, GlobalResources::instance().getImage(wxT("swap")));
}
else
{
m_bpButtonLocalFilter->Show();
m_bpButtonAltSyncCfg->Show();
- m_bpButtonSwapSides->SetBitmapLabel(GlobalResources::instance().getImage(wxT("swapSlim")));
+ setBitmapLabel(*m_bpButtonSwapSides, GlobalResources::instance().getImage(wxT("swapSlim")));
}
m_panelTopMiddle->Layout();
-
- int addPairHeight = 0;
+ int addPairMinimalHeight = 0;
+ int addPairOptimalHeight = 0;
if (additionalFolderPairs.size() > 0)
- addPairHeight = std::min<double>(1.5, additionalFolderPairs.size()) * //have 0.5 * height indicate that more folders are there
- additionalFolderPairs[0]->GetSize().GetHeight();
+ {
+ 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
+ addPairOptimalHeight = std::min<double>(globalSettings->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"
+ }
+
+ //########################################################################################################################
+ //wxAUI hack: set minimum height to desired value, then call wxAuiPaneInfo::Fixed() to apply it
+ auiMgr.GetPane(m_panelDirectoryPairs).MinSize(-1, m_panelTopLeft->GetSize().GetHeight() + addPairOptimalHeight);
+ auiMgr.GetPane(m_panelDirectoryPairs).Fixed();
+ auiMgr.Update();
+
+ //now make resizable again
+ auiMgr.GetPane(m_panelDirectoryPairs).Resizable();
+ auiMgr.Update();
+ //########################################################################################################################
//ensure additional folder pairs are at least partially visible
- auiMgr.GetPane(m_panelDirectoryPairs).MinSize(-1, m_panelTopLeft->GetSize().GetHeight() + addPairHeight);
+ auiMgr.GetPane(m_panelDirectoryPairs).MinSize(-1, m_panelTopLeft->GetSize().GetHeight() + addPairMinimalHeight);
auiMgr.Update();
m_scrolledWindowFolderPairs->Fit(); //adjust scrolled window size
//m_scrolledWindowFolderPairs->Layout(); //adjust stuff inside scrolled window
m_panelDirectoryPairs->Layout();
-
- /*
- #warning test
- auiMgr.GetPane(m_panelDirectoryPairs).MaxSize(20, 20);
- auiMgr.Update();
- */
}
void MainDialog::addFolderPair(const std::vector<FolderPairEnh>& newPairs, bool addFront)
{
wxWindowUpdateLocker dummy(m_panelDirectoryPairs); //avoid display distortion
+ wxWindowUpdateLocker dummy2(m_panelGrids); //
if (!newPairs.empty())
{
@@ -3845,8 +4023,8 @@ void MainDialog::addFolderPair(const std::vector<FolderPairEnh>& newPairs, bool
newPair->m_bpButtonRemovePair->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainDialog::OnRemoveFolderPair), NULL, this);
//set alternate configuration
- newPair->setValues(zToWx(i->leftDirectory),
- zToWx(i->rightDirectory),
+ newPair->setValues(toWx(i->leftDirectory),
+ toWx(i->rightDirectory),
i->altSyncConfig,
i->localFilter);
}
@@ -3867,6 +4045,7 @@ void MainDialog::addFolderPair(const std::vector<FolderPairEnh>& newPairs, bool
void MainDialog::removeAddFolderPair(size_t pos)
{
wxWindowUpdateLocker dummy(m_panelDirectoryPairs); //avoid display distortion
+ wxWindowUpdateLocker dummy2(m_panelGrids); //
if (pos < additionalFolderPairs.size())
{
@@ -3896,6 +4075,7 @@ void MainDialog::removeAddFolderPair(size_t pos)
void MainDialog::clearAddFolderPairs()
{
wxWindowUpdateLocker dummy(m_panelDirectoryPairs); //avoid display distortion
+ wxWindowUpdateLocker dummy2(m_panelGrids); //
additionalFolderPairs.clear();
bSizerAddFolderPairs->Clear(true);
@@ -3917,8 +4097,6 @@ void MainDialog::OnMenuGlobalSettings(wxCommandEvent& event)
namespace
{
-typedef Zbase<wchar_t> zxString;
-
inline
void addCellValue(zxString& exportString, const wxString& cellVal)
{
@@ -3934,20 +4112,16 @@ void MainDialog::OnMenuExportFileList(wxCommandEvent& event)
{
//get a filename
const wxString defaultFileName = wxT("FileList.csv"); //proposal
- wxFileDialog filePicker(this, wxEmptyString, wxEmptyString, defaultFileName, wxString(_("Comma separated list")) + wxT(" (*.csv)|*.csv"), wxFD_SAVE); //creating this on freestore leads to memleak!
+ wxFileDialog filePicker(this,
+ wxEmptyString,
+ wxEmptyString,
+ defaultFileName,
+ wxString(_("Comma separated list")) + wxT(" (*.csv)|*.csv"),
+ wxFD_SAVE | wxFD_OVERWRITE_PROMPT); //creating this on freestore leads to memleak!
if (filePicker.ShowModal() == wxID_OK)
{
const wxString newFileName = filePicker.GetPath();
- if (zen::fileExists(wxToZ(newFileName)))
- {
- if (showQuestionDlg(ReturnQuestionDlg::BUTTON_YES | ReturnQuestionDlg::BUTTON_CANCEL,
- wxString(_("File already exists. Overwrite?")) + wxT(" \"") + newFileName + wxT("\"")) != ReturnQuestionDlg::BUTTON_YES)
- {
- OnMenuExportFileList(event); //retry
- return;
- }
- }
zxString exportString; //perf: wxString doesn't model exponential growth and so is out
@@ -4034,7 +4208,7 @@ void MainDialog::OnMenuExportFileList(wxCommandEvent& event)
size_t bufferSize = 0;
const wxCharBuffer utf8buffer = wxConvUTF8.cWC2MB(exportString.c_str(), exportString.size(), &bufferSize);
- output.Write(common::BYTE_ORDER_MARK_UTF8, sizeof(common::BYTE_ORDER_MARK_UTF8) - 1);
+ output.Write(BYTE_ORDER_MARK_UTF8, sizeof(BYTE_ORDER_MARK_UTF8) - 1);
output.Write(utf8buffer, bufferSize);
pushStatusInformation(_("File list exported!"));
}
@@ -4049,7 +4223,7 @@ void MainDialog::OnMenuExportFileList(wxCommandEvent& event)
void MainDialog::OnMenuBatchJob(wxCommandEvent& event)
{
//fill batch config structure
- const xmlAccess::XmlGuiConfig currCfg = getCurrentConfiguration(); //get UP TO DATE config, with updated values for main and additional folders!
+ const xmlAccess::XmlGuiConfig currCfg = getConfig(); //get UP TO DATE config, with updated values for main and additional folders!
const xmlAccess::XmlBatchConfig batchCfg = convertGuiToBatch(currCfg);
@@ -4115,7 +4289,7 @@ void MainDialog::switchProgramLanguage(const int langID)
//create new dialog with respect to new language
zen::setLanguage(langID); //language is a global attribute
- const xmlAccess::XmlGuiConfig currentGuiCfg = getCurrentConfiguration();
+ const xmlAccess::XmlGuiConfig currentGuiCfg = getConfig();
cleanUp(false); //destructor's code: includes updating global settings
@@ -4151,24 +4325,11 @@ bool MainDialog::SyncPreview::previewIsEnabled() const
void MainDialog::SyncPreview::enablePreview(bool value)
{
- if (value)
- {
- syncPreviewEnabled = true;
+ syncPreviewEnabled = value;
- //toggle display of sync preview in middle grid
- mainDlg_->m_gridMiddle->enableSyncPreview(true);
-
- mainDlg_->Refresh();
- }
- else
- {
- syncPreviewEnabled = false;
-
- //toggle display of sync preview in middle grid
- mainDlg_->m_gridMiddle->enableSyncPreview(false);
-
- mainDlg_->Refresh();
- }
+ //toggle display of sync preview in middle grid
+ mainDlg_->m_gridMiddle->enableSyncPreview(value);
+ // mainDlg_->Refresh();
mainDlg_->updateGuiGrid();
}
@@ -4176,15 +4337,15 @@ void MainDialog::SyncPreview::enablePreview(bool value)
void MainDialog::SyncPreview::enableSynchronization(bool value)
{
+ synchronizationEnabled = value;
+
if (value)
{
- synchronizationEnabled = true;
mainDlg_->m_buttonStartSync->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT));
mainDlg_->m_buttonStartSync->setBitmapFront(GlobalResources::instance().getImage(wxT("sync")));
}
else
{
- synchronizationEnabled = false;
mainDlg_->m_buttonStartSync->SetForegroundColour(wxColor(128, 128, 128)); //Some colors seem to have problems with 16Bit color depth, well this one hasn't!
mainDlg_->m_buttonStartSync->setBitmapFront(GlobalResources::instance().getImage(wxT("syncDisabled")));
}
bgstack15