summaryrefslogtreecommitdiff
path: root/ui/MainDialog.cpp
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 16:47:21 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 16:47:21 +0200
commitca64896d49b70fc0ffec711a079167c972fe635e (patch)
tree0059c36336378c886b750860aa5343b847c3609a /ui/MainDialog.cpp
parent1.3 (diff)
downloadFreeFileSync-ca64896d49b70fc0ffec711a079167c972fe635e.tar.gz
FreeFileSync-ca64896d49b70fc0ffec711a079167c972fe635e.tar.bz2
FreeFileSync-ca64896d49b70fc0ffec711a079167c972fe635e.zip
1.4
Diffstat (limited to 'ui/MainDialog.cpp')
-rw-r--r--ui/MainDialog.cpp587
1 files changed, 315 insertions, 272 deletions
diff --git a/ui/MainDialog.cpp b/ui/MainDialog.cpp
index f063dfcb..1528f0c8 100644
--- a/ui/MainDialog.cpp
+++ b/ui/MainDialog.cpp
@@ -17,7 +17,7 @@
#include <cmath>
#include <wx/msgdlg.h>
-using namespace GlobalFunctions;
+using namespace globalFunctions;
int leadingPanel = 0;
@@ -35,6 +35,14 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName) :
//initialize sync configuration
readConfigurationFromHD(cfgFileName, true);
+ leftOnlyFilesActive = true;
+ leftNewerFilesActive = true;
+ differentFilesActive = true;
+ rightNewerFilesActive = true; //do not put these bool values into config.dat!
+ rightOnlyFilesActive = true; //it's more convenient to have them defaulted at startup
+ equalFilesActive = false;
+ updateViewFilterButtons();
+
//set icons for this dialog
m_bpButton11->SetBitmapLabel(*GlobalResources::bitmapAbout);
m_bpButton10->SetBitmapLabel(*GlobalResources::bitmapExit);
@@ -112,8 +120,6 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName) :
m_grid2->setGridDataTable(&currentUI_View);
m_grid3->setGridDataTable(&currentUI_View);
- updateViewFilterButtons();
-
//disable sync button as long as "compare" hasn't been triggered.
m_bpButtonSync->Disable();
@@ -129,11 +135,6 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName) :
//as the name says: disable them
m_grid3->deactivateScrollbars();
- //set status of filter button
- updateFilterButton();
- //set status of "hide filtered items" checkbox
- m_checkBoxHideFilt->SetValue(hideFiltered);
-
//mainly to update row label sizes...
writeGrid(currentGridData);
@@ -216,14 +217,7 @@ MainDialog::~MainDialog()
}
delete cfgFileHistory;
- try
- {
- writeConfigurationToHD(FreeFileSync::FFS_LastConfigFile); //don't trow exceptions in destructors
- }
- catch (std::runtime_error& theException)
- {
- wxMessageBox(_(theException.what()), _("An exception occured!"), wxOK | wxICON_ERROR);
- }
+ writeConfigurationToHD(FreeFileSync::FFS_LastConfigFile); //don't trow exceptions in destructors
}
@@ -265,15 +259,11 @@ void MainDialog::onGrid3access(wxEvent& event)
}
-void MainDialog::filterRangeManual(int begin, int end, int leadingRow)
+void MainDialog::filterRangeManual(const set<int>& rowsToFilterOnUI_View, int leadingRow)
{
- int currentUI_Size = currentUI_View.size();
-
- int topRow = max(begin, 0);
- int bottomRow = min(end, currentUI_Size - 1);
-
- if (topRow <= bottomRow) // bottomRow might be -1 ?
+ if (rowsToFilterOnUI_View.size() > 0)
{
+ int currentUI_Size = currentUI_View.size();
bool newSelection = false; //default: deselect range
@@ -287,12 +277,17 @@ void MainDialog::filterRangeManual(int begin, int end, int leadingRow)
//get all lines that need to be filtered (e.g. if a folder is marked, then its subelements should be marked as well)
set<int> rowsToFilterOnGridData; //rows to filter in backend
- for (int i = topRow; i <= bottomRow; ++i)
+
+
+ for (set<int>::iterator i = rowsToFilterOnUI_View.begin(); i != rowsToFilterOnUI_View.end(); ++i)
{
- unsigned int gridDataLine = currentUI_View[i].linkToCurrentGridData;
+ if (0 <= *i && *i < currentUI_Size)
+ {
+ unsigned int gridIndex = currentUI_View[*i].linkToCurrentGridData;
- rowsToFilterOnGridData.insert(gridDataLine);
- FreeFileSync::addSubElements(rowsToFilterOnGridData, currentGridData, currentGridData[gridDataLine]);
+ rowsToFilterOnGridData.insert(gridIndex);
+ FreeFileSync::addSubElements(rowsToFilterOnGridData, currentGridData, currentGridData[gridIndex]);
+ }
}
@@ -327,37 +322,7 @@ void MainDialog::filterRangeManual(int begin, int end, int leadingRow)
wxMilliSleep(400);
//delete rows, that are filtered out:
-
- //for (set<int>::reverse_iterator i = filteredOutRowsOnUI.rbegin(); i != filteredOutRowsOnUI.rend(); ++i)
- // currentUI_View.erase(currentUI_View.begin() + *i);
-
- //Note: the following lines are a performance optimization for deleting elements from a vector. It is incredibly faster to create a new
- //vector and leave specific elements out than to delete row by row and force recopying of most elements for each single deletion (linear vs quadratic runtime)
-
- //Note: This is the most time consuming part in this whole method!
-
- UI_Grid temp;
- int rowNr = 0;
- int rowToSkip = -1;
-
- set<int>::iterator rowToSkipIndex = filteredOutRowsOnUI.begin();
-
- if (rowToSkipIndex != filteredOutRowsOnUI.end())
- rowToSkip = *rowToSkipIndex;
-
- for (UI_Grid::iterator i = currentUI_View.begin(); i != currentUI_View.end(); ++i, ++rowNr)
- {
- if (rowNr != rowToSkip)
- temp.push_back(*i);
- else
- {
- rowToSkipIndex++;
- if (rowToSkipIndex != filteredOutRowsOnUI.end())
- rowToSkip = *rowToSkipIndex;
- }
- }
- currentUI_View.swap(temp);
-
+ removeRowsFromVector(currentUI_View, filteredOutRowsOnUI);
//redraw grid necessary to update new dimensions
writeGrid(currentGridData, true); //use UI buffer, no mapping from currentGridData to UI model again, just a re-dimensioning of grids
@@ -429,7 +394,11 @@ void MainDialog::OnIdleEvent(wxEvent& event)
{ //a mouse up event, but no mouse down! (e.g. when window is maximized and cursor is on grid3)
filteringInitialized = false;
- filterRangeManual(selectedRange3Begin, selectedRange3End, selectionLead);
+ set<int> filteredRows;
+ for (int i = selectedRange3Begin; i <= selectedRange3End; ++i)
+ filteredRows.insert(i);
+
+ filterRangeManual(filteredRows, selectionLead);
}
}
@@ -608,7 +577,7 @@ public:
if (suppressUI_Errormessages)
{
unsolvedErrors = true;
- return StatusUpdater::Continue;
+ return StatusUpdater::continueNext;
}
wxString errorMessage = text + _("\n\nInformation: If you skip the error and continue or abort a re-compare will be necessary!");
@@ -620,12 +589,12 @@ public:
switch (rv)
{
- case ErrorDlg::ContinueButtonPressed:
+ case ErrorDlg::continueButtonPressed:
unsolvedErrors = true;
- return StatusUpdater::Continue;
- case ErrorDlg::RetryButtonPressed:
- return StatusUpdater::Retry;
- case ErrorDlg::AbortButtonPressed:
+ return StatusUpdater::continueNext;
+ case ErrorDlg::retryButtonPressed:
+ return StatusUpdater::retry;
+ case ErrorDlg::abortButtonPressed:
{
unsolvedErrors = true;
throw AbortThisProcess();
@@ -634,10 +603,11 @@ public:
assert (false);
}
- return StatusUpdater::Continue; //dummy return value
+ return StatusUpdater::continueNext; //dummy return value
}
- void updateStatus(const wxString& text) {}
- void updateProgressIndicator(double number) {}
+ void updateStatusText(const wxString& text) {}
+ void initNewProcess(int objectsTotal, double dataTotal, int processID) {}
+ void updateProcessedData(int objectsProcessed, double dataProcessed) {}
private:
@@ -675,10 +645,10 @@ void MainDialog::deleteFilesOnGrid(wxGrid* grid)
{
const FileCompareLine& currentCmpLine = currentGridData[*i];
- if (currentCmpLine.fileDescrLeft.objType != IsNothing)
+ if (currentCmpLine.fileDescrLeft.objType != isNothing)
filesToDelete+= currentCmpLine.fileDescrLeft.filename + "\n";
- if (currentCmpLine.fileDescrRight.objType != IsNothing)
+ if (currentCmpLine.fileDescrRight.objType != isNothing)
filesToDelete+= currentCmpLine.fileDescrRight.filename + "\n";
filesToDelete+= "\n";
@@ -688,7 +658,7 @@ void MainDialog::deleteFilesOnGrid(wxGrid* grid)
switch (confirmDeletion->ShowModal())
{
- case DeleteDialog::OkayButtonPressed:
+ case DeleteDialog::okayButtonPressed:
{
bool unsolvedErrorOccured = false; //if an error is skipped a re-compare will be necessary!
@@ -709,10 +679,12 @@ void MainDialog::deleteFilesOnGrid(wxGrid* grid)
//redraw grid neccessary to update new dimensions and for UI-Backend data linkage
writeGrid(currentGridData); //do NOT use UI buffer here
+
+ grid->ClearSelection(); //clear selection on grid
}
break;
- case DeleteDialog::CancelButtonPressed:
+ case DeleteDialog::cancelButtonPressed:
default:
break;
@@ -837,27 +809,6 @@ void MainDialog::OnDirChangedPanel2(wxFileDirPickerEvent& event)
}
-void onFilesDropped(const wxString& elementName, wxTextCtrl* txtCtrl, wxDirPickerCtrl* dirPicker)
-{
- wxString fileName = elementName;
-
- if (wxDirExists(fileName))
- {
- txtCtrl->SetValue(fileName);
- dirPicker->SetPath(fileName);
- }
- else
- {
- fileName = wxFileName(fileName).GetPath();
- if (wxDirExists(fileName))
- {
- txtCtrl->SetValue(fileName);
- dirPicker->SetPath(fileName);
- }
- }
-}
-
-
void MainDialog::clearStatusBar()
{
stackObjects = 0; //prevent old stack objects from popping up
@@ -884,10 +835,10 @@ bool sameFileSpecified(const wxString& file1, const wxString& file2)
wxString file2Full = file2;
if (wxFileName(file1).GetPath() == wxEmptyString)
- file1Full = wxFileName::GetCwd() + FileNameSeparator + file1;
+ file1Full = wxFileName::GetCwd() + GlobalResources::fileNameSeparator + file1;
if (wxFileName(file2).GetPath() == wxEmptyString)
- file2Full = wxFileName::GetCwd() + FileNameSeparator + file2;
+ file2Full = wxFileName::GetCwd() + GlobalResources::fileNameSeparator + file2;
return (file1Full == file2Full);
}
@@ -932,6 +883,27 @@ void MainDialog::addCfgFileToHistory(const wxString& filename)
}
+void onFilesDropped(const wxString& elementName, wxTextCtrl* txtCtrl, wxDirPickerCtrl* dirPicker)
+{
+ wxString fileName = elementName;
+
+ if (wxDirExists(fileName))
+ {
+ txtCtrl->SetValue(fileName);
+ dirPicker->SetPath(fileName);
+ }
+ else
+ {
+ fileName = wxFileName(fileName).GetPath();
+ if (wxDirExists(fileName))
+ {
+ txtCtrl->SetValue(fileName);
+ dirPicker->SetPath(fileName);
+ }
+ }
+}
+
+
bool FileDropEvent::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames)
{
if (filenames.IsEmpty())
@@ -1033,14 +1005,16 @@ void MainDialog::OnLoadConfiguration(wxCommandEvent& event)
if (!newCfgFile.IsEmpty())
{
- if (wxFileExists(newCfgFile) && FreeFileSync::isFFS_ConfigFile(newCfgFile))
+ if (!wxFileExists(newCfgFile))
+ wxMessageBox(_("The selected file does not exist anymore!"), _("Warning"), wxOK);
+ else if (!FreeFileSync::isFFS_ConfigFile(newCfgFile))
+ wxMessageBox(_("The selected file does not contain a valid configuration!"), _("Warning"), wxOK);
+ else
{
readConfigurationFromHD(newCfgFile);
pushStatusInformation(_("Configuration loaded!"));
}
- else
- wxMessageBox(_("The selected file does not contain a valid configuration!"), _("Warning"), wxOK);
}
}
event.Skip();
@@ -1087,47 +1061,67 @@ void MainDialog::OnQuit(wxCommandEvent &event)
}
-void MainDialog::readConfigurationFromHD(const wxString& filename, bool programStartup)
+void MainDialog::loadDefaultConfiguration()
{
//default values
- syncConfiguration.exLeftSideOnly = SyncDirRight;
- syncConfiguration.exRightSideOnly = SyncDirRight;
- syncConfiguration.leftNewer = SyncDirRight;
- syncConfiguration.rightNewer = SyncDirRight;
- syncConfiguration.different = SyncDirRight;
+ syncConfiguration.exLeftSideOnly = syncDirRight;
+ syncConfiguration.exRightSideOnly = syncDirRight;
+ syncConfiguration.leftNewer = syncDirRight;
+ syncConfiguration.rightNewer = syncDirRight;
+ syncConfiguration.different = syncDirRight;
- leftOnlyFilesActive = true;
- leftNewerFilesActive = true;
- differentFilesActive = true;
- rightNewerFilesActive = true; //do not put these bool values into config.dat!
- rightOnlyFilesActive = true; //it's more convenient to have them defaulted for each execution
- equalFilesActive = false;
+ m_radioBtnSizeDate->SetValue(true); //compare algorithm
includeFilter = "*"; //include all files/folders
excludeFilter = ""; //exlude nothing
- hideFiltered = false; //show filtered items
+
+ //set status of filter button
filterIsActive = false; //do not filter by default
+ updateFilterButton();
+
+ //set status of "hide filtered items" checkbox
+ hideFiltered = false; //show filtered items
+ m_checkBoxHideFilt->SetValue(hideFiltered);
useRecycleBin = false; //do not use: in case OS doesn't support this, user will have to activate first and then get the error message
+ hideErrorMessages = false;
widthNotMaximized = wxDefaultCoord;
heightNotMaximized = wxDefaultCoord;
posXNotMaximized = wxDefaultCoord;
posYNotMaximized = wxDefaultCoord;
-//#####################################################
+}
+
+
+void MainDialog::readConfigurationFromHD(const wxString& filename, bool programStartup)
+{
+ char bigBuffer[10000];
ifstream config(filename.c_str());
if (!config)
+ {
+ if (programStartup)
+ loadDefaultConfiguration();
+ else
+ wxMessageBox(wxString(_("Could not read configuration file ")) + "\"" + filename + "\"", _("An exception occured!"), wxOK | wxICON_ERROR);
+
+ return;
+ }
+
+ //read FFS identifier
+ config.get(bigBuffer, FreeFileSync::FFS_ConfigFileID.Len() + 1);
+
+ if (wxString(bigBuffer) != FreeFileSync::FFS_ConfigFileID)
+ {
+ wxMessageBox(_("The selected file does not contain a valid configuration!"), _("Warning"), wxOK);
+ config.close();
return;
+ }
+
//put filename on list of last used config files
addCfgFileToHistory(filename);
- char bigBuffer[10000];
-
-
- //read FFS identifier
- config.get(bigBuffer, FreeFileSync::FFS_ConfigFileID.Len() + 1);
//read sync configuration
syncConfiguration.exLeftSideOnly = SyncDirection(config.get());
@@ -1136,13 +1130,13 @@ void MainDialog::readConfigurationFromHD(const wxString& filename, bool programS
syncConfiguration.rightNewer = SyncDirection(config.get());
syncConfiguration.different = SyncDirection(config.get());
- //read find method
+ //read compare algorithm
switch (int(config.get()))
{
- case CompareByTimeAndSize:
+ case compareByTimeAndSize:
m_radioBtnSizeDate->SetValue(true);
break;
- case CompareByMD5:
+ case compareByMD5:
m_radioBtnContent->SetValue(true);
break;
default:
@@ -1200,7 +1194,10 @@ void MainDialog::readConfigurationFromHD(const wxString& filename, bool programS
//read filter settings:
hideFiltered = bool(config.get());
+ m_checkBoxHideFilt->SetValue(hideFiltered);
+
filterIsActive = bool(config.get());
+ updateFilterButton();
//include
config.getline(bigBuffer, 10000, char(0));
@@ -1212,14 +1209,20 @@ void MainDialog::readConfigurationFromHD(const wxString& filename, bool programS
useRecycleBin = bool(config.get());
+ hideErrorMessages = bool(config.get());
+
config.close();
}
+
void MainDialog::writeConfigurationToHD(const wxString& filename)
{
ofstream config(filename.c_str());
if (!config)
- throw runtime_error(string(_("Could not write to ")) + filename.c_str());
+ {
+ wxMessageBox(wxString(_("Could not write to ")) + "\"" + filename + "\"", _("An exception occured!"), wxOK | wxICON_ERROR);
+ return;
+ }
//put filename on list of last used config files
addCfgFileToHistory(filename);
@@ -1236,9 +1239,9 @@ void MainDialog::writeConfigurationToHD(const wxString& filename)
//write find method
if (m_radioBtnSizeDate->GetValue())
- config<<char(CompareByTimeAndSize);
+ config<<char(compareByTimeAndSize);
else if (m_radioBtnContent->GetValue())
- config<<char(CompareByMD5);
+ config<<char(compareByMD5);
else assert (false);
@@ -1272,34 +1275,39 @@ void MainDialog::writeConfigurationToHD(const wxString& filename)
config<<char(useRecycleBin);
+ config<<char(hideErrorMessages);
+
config.close();
}
+
void MainDialog::OnAbout(wxCommandEvent &event)
{
AboutDlg* aboutDlg = new AboutDlg(this);
aboutDlg->ShowModal();
}
+
void MainDialog::OnShowHelpDialog(wxCommandEvent &event)
{
HelpDlg* helpDlg = new HelpDlg(this);
helpDlg->ShowModal();
}
+
void MainDialog::OnFilterButton(wxCommandEvent &event)
{ //toggle filter on/off
filterIsActive = !filterIsActive;
+ //make sure, button-appearance and "filterIsActive" are in sync.
+ updateFilterButton();
+
if (filterIsActive)
FreeFileSync::filterCurrentGridData(currentGridData, includeFilter, excludeFilter);
else
FreeFileSync::removeFilterOnCurrentGridData(currentGridData);
writeGrid(currentGridData);
-
- //make sure, button-appearance and "filterIsActive" are in sync.
- updateFilterButton();
}
@@ -1316,11 +1324,18 @@ void MainDialog::OnHideFilteredButton(wxCommandEvent &event)
void MainDialog::OnConfigureFilter(wxHyperlinkEvent &event)
{
+ wxString beforeImage = includeFilter + wxChar(0) + excludeFilter;
+
FilterDlg* filterDlg = new FilterDlg(this);
- if (filterDlg->ShowModal() == FilterDlg::OkayButtonPressed)
+ if (filterDlg->ShowModal() == FilterDlg::okayButtonPressed)
{
- if (filterIsActive)
+ wxString afterImage = includeFilter + wxChar(0) + excludeFilter;
+
+ if (beforeImage != afterImage) //if filter settings are changed: set filtering to "on"
{
+ filterIsActive = true;
+ updateFilterButton();
+
FreeFileSync::filterCurrentGridData(currentGridData, includeFilter, excludeFilter);
writeGrid(currentGridData);
@@ -1444,25 +1459,25 @@ void MainDialog::OnCompare(wxCommandEvent &event)
wxBeginBusyCursor();
- CompareVariant cmpVar = CompareByTimeAndSize; //assign a value to suppress compiler warning
+ CompareVariant cmpVar = compareByTimeAndSize; //assign a value to suppress compiler warning
if (m_radioBtnSizeDate->GetValue())
- cmpVar = CompareByTimeAndSize;
+ cmpVar = compareByTimeAndSize;
else if (m_radioBtnContent->GetValue())
- cmpVar = CompareByMD5;
+ cmpVar = compareByMD5;
else assert (false);
try
{ //class handling status display and error messages
- CompareStatusUpdater statusUpdater(this, m_statusBar1);
+ CompareStatusUpdater statusUpdater(this);
cmpStatusUpdaterTmp = &statusUpdater;
stackObjects = 0;
//unsigned int startTime3 = GetTickCount();
- FreeFileSync::getModelDiff(currentGridData,
- FreeFileSync::getFormattedDirectoryName(m_directoryPanel1->GetValue()),
- FreeFileSync::getFormattedDirectoryName(m_directoryPanel2->GetValue()),
- cmpVar,
- &statusUpdater);
+ FreeFileSync::startCompareProcess(currentGridData,
+ FreeFileSync::getFormattedDirectoryName(m_directoryPanel1->GetValue()),
+ FreeFileSync::getFormattedDirectoryName(m_directoryPanel2->GetValue()),
+ cmpVar,
+ &statusUpdater);
//wxMessageBox(numberToWxString(unsigned(GetTickCount()) - startTime3));
@@ -1470,12 +1485,12 @@ void MainDialog::OnCompare(wxCommandEvent &event)
if (filterIsActive)
FreeFileSync::filterCurrentGridData(currentGridData, includeFilter, excludeFilter);
- writeGrid(currentGridData);
-
//once compare is finished enable the sync button
- m_bpButtonSync->Enable(true);
+ m_bpButtonSync->Enable();
m_bpButtonSync->SetFocus();
+ writeGrid(currentGridData); //keep it in try/catch to not overwrite status information if compare is abortet
+
cmpStatusUpdaterTmp = 0;
}
catch (AbortThisProcess& theException)
@@ -1501,38 +1516,38 @@ wxString MainDialog::evaluateCmpResult(const CompareFilesResult result, const bo
if (selectedForSynchronization)
switch (result)
{
- case FileOnLeftSideOnly:
+ case fileOnLeftSideOnly:
return "<|";
break;
- case FileOnRightSideOnly:
+ case fileOnRightSideOnly:
return "|>";
break;
- case RightFileNewer:
+ case rightFileNewer:
return ">>";
break;
- case LeftFileNewer:
+ case leftFileNewer:
return "<<";
break;
- case FilesDifferent:
+ case filesDifferent:
return "!=";
break;
- case FilesEqual:
+ case filesEqual:
return "==";
break;
default:
assert (false);
}
- else return ConstFilteredOut;
+ else return constFilteredOut;
}
void MainDialog::writeGrid(const FileCompareResult& gridData, bool useUI_GridCache)
{
- //unsigned int startTime = GetTickCount();
-
if (!useUI_GridCache)
{
+ //unsigned int startTime = GetTickCount();
mapFileModelToUI(currentUI_View, gridData); //update currentUI_View
+ //wxMessageBox(wxString("Benchmark: ") + numberToWxString(unsigned(GetTickCount()) - startTime) + " ms");
updateStatusInformation(currentUI_View); //write status information for currentUI_View
}
@@ -1563,8 +1578,6 @@ void MainDialog::writeGrid(const FileCompareResult& gridData, bool useUI_GridCac
m_grid1->EndBatch();
m_grid2->EndBatch();
m_grid3->EndBatch();
-
- //wxMessageBox(wxString("Benchmark: ") + numberToWxString(unsigned(GetTickCount()) - startTime) + " ms");
}
@@ -1573,7 +1586,7 @@ void MainDialog::OnSync( wxCommandEvent& event )
//check if there are files/folders that can be synced
bool nothingToSync = true;
for (FileCompareResult::const_iterator i = currentGridData.begin(); i != currentGridData.end(); ++i)
- if (i->cmpResult != FilesEqual)
+ if (i->cmpResult != filesEqual)
{
nothingToSync = false;
break;
@@ -1592,9 +1605,33 @@ void MainDialog::OnSync( wxCommandEvent& event )
clearStatusBar();
- //unsigned int startTime = GetTickCount();
- synchronizeFolders(currentGridData, syncConfiguration);
- //wxMessageBox(numberToWxString(unsigned(GetTickCount()) - startTime));
+ try
+ {
+ //class handling status updates and error messages
+ SyncStatusUpdater statusUpdater(this, hideErrorMessages);
+
+ //start synchronization and return elements that were not sync'ed in currentGridData
+
+ //unsigned int startTime3 = GetTickCount();
+ FreeFileSync::startSynchronizationProcess(currentGridData, syncConfiguration, &statusUpdater, useRecycleBin);
+ //wxMessageBox(numberToWxString(unsigned(GetTickCount()) - startTime3));
+ }
+ catch (AbortThisProcess& theException)
+ { //do NOT disable the sync button: user might want to try to sync the REMAINING rows
+ } //m_bpButtonSync->Disable();
+
+
+ //display files that were not processed
+ writeGrid(currentGridData);
+
+ if (currentGridData.size() > 0)
+ pushStatusInformation(_("Not all items were synchronized! Have a look at the list."));
+ else
+ {
+ pushStatusInformation(_("All items have been synchronized!"));
+ m_bpButtonSync->Disable();
+ }
+
wxEndBusyCursor();
}
@@ -1649,26 +1686,12 @@ bool cmpString(const wxString& a, const wxString& b)
}
inline
-bool cmpLargeInt(const wxString& a, const wxString& b)
+bool cmpLargeInt(const wxULongLong& a, const wxULongLong& b)
{
- //if a and b not empty:
- bool result = true;
- wxString tmpString;
- mpz_t largeTempIntegerA;
- mpz_t largeTempIntegerB;
- mpz_init(largeTempIntegerA);
- mpz_init(largeTempIntegerB);
- mpz_set_str(largeTempIntegerA, a.c_str(), 10);
- //return value should be checked: if function fails, largeTempIntegerA is not changed: no issue here
- mpz_set_str(largeTempIntegerB, b.c_str(), 10);
- //return value should be checked: if function fails, largeTempIntegerA is not changed: no issue here
if (sortAscending)
- result = (mpz_cmp(largeTempIntegerA, largeTempIntegerB) < 0); // true if A < B
- else
- result = (mpz_cmp(largeTempIntegerA, largeTempIntegerB) > 0); // true if A > B
- mpz_clear(largeTempIntegerA);
- mpz_clear(largeTempIntegerB);
- return result;
+ return (a < b);
+
+ return (a > b);
}
@@ -1687,13 +1710,13 @@ bool sortGridLeft(const UI_GridLine& a, const UI_GridLine& b)
ObjectType typeB = (*currentGridDataPtr)[b.linkToCurrentGridData].fileDescrLeft.objType;
//presort types: first files, then directories then empty rows
- if (typeA == IsNothing)
+ if (typeA == isNothing)
return false; //empty rows always last
- else if (typeB == IsNothing)
+ else if (typeB == isNothing)
return true; //empty rows always last
- else if (typeA == IsDirectory)
+ else if (typeA == isDirectory)
return false;
- else if (typeB == IsDirectory)
+ else if (typeB == isDirectory)
return true;
else //use unformatted filesizes and sort by size
return cmpLargeInt((*currentGridDataPtr)[a.linkToCurrentGridData].fileDescrLeft.fileSize, (*currentGridDataPtr)[b.linkToCurrentGridData].fileDescrLeft.fileSize);
@@ -1723,13 +1746,13 @@ bool sortGridRight(const UI_GridLine& a, const UI_GridLine& b)
ObjectType typeB = (*currentGridDataPtr)[b.linkToCurrentGridData].fileDescrRight.objType;
//presort types: first files, then directories then empty rows
- if (typeA == IsNothing)
+ if (typeA == isNothing)
return false; //empty rows always last
- else if (typeB == IsNothing)
+ else if (typeB == isNothing)
return true; //empty rows always last
- else if (typeA == IsDirectory)
+ else if (typeA == isDirectory)
return false;
- else if (typeB == IsDirectory)
+ else if (typeB == isDirectory)
return true;
else //use unformatted filesizes and sort by size
return cmpLargeInt((*currentGridDataPtr)[a.linkToCurrentGridData].fileDescrRight.fileSize, (*currentGridDataPtr)[b.linkToCurrentGridData].fileDescrRight.fileSize);
@@ -1802,29 +1825,6 @@ void MainDialog::OnSwapDirs( wxCommandEvent& event )
}
-void MainDialog::synchronizeFolders(FileCompareResult& grid, const SyncConfiguration config)
-{
- try
- { //class handling status updates and error messages
- SyncStatusUpdater statusUpdater(this, FreeFileSync::calcTotalBytesToTransfer(grid, config).get_d());
-
- //start synchronization and return elements that were errorneous in "grid"
-
- //unsigned int startTime3 = GetTickCount();
- FreeFileSync::startSynchronizationProcess(grid, config, &statusUpdater, useRecycleBin);
- //wxMessageBox(numberToWxString(unsigned(GetTickCount()) - startTime3));
-
-
- //display files that couldn't be processed
- writeGrid(grid);
- }
- catch (AbortThisProcess& theException)
- {
- //disable the sync button
- m_bpButtonSync->Enable(false);
- }
-}
-
//this sorting method is currently NOT used
bool cmpGridSmallerThan(const UI_GridLine& a, const UI_GridLine& b)
{
@@ -1868,7 +1868,8 @@ bool cmpGridSmallerThan(const UI_GridLine& a, const UI_GridLine& b)
void MainDialog::updateStatusInformation(const UI_Grid& visibleGrid)
{
- stackObjects = 0;
+ clearStatusBar();
+
unsigned int objectsOnLeftView = 0;
unsigned int objectsOnRightView = 0;
mpz_t filesizeLeftView, filesizeRightView, tmpInt;
@@ -1876,29 +1877,24 @@ void MainDialog::updateStatusInformation(const UI_Grid& visibleGrid)
mpz_init(filesizeRightView);
mpz_init(tmpInt);
- int returnValue = 0;
-
for (UI_Grid::const_iterator i = visibleGrid.begin(); i != visibleGrid.end(); i++)
{
const FileCompareLine& refLine = currentGridData[i->linkToCurrentGridData];
//calculate total number of bytes for each sied
- if (refLine.fileDescrLeft.objType != IsNothing)
+ if (refLine.fileDescrLeft.objType != isNothing)
{
- mpz_set_ui(tmpInt, 0);
- returnValue = mpz_set_str(tmpInt, refLine.fileDescrLeft.fileSize.c_str(), 10);
+ FreeFileSync::wxULongLongToMpz(tmpInt, refLine.fileDescrLeft.fileSize);
mpz_add(filesizeLeftView, filesizeLeftView, tmpInt);
- assert (returnValue == 0);
objectsOnLeftView++;
}
- if (refLine.fileDescrRight.objType != IsNothing)
+ if (refLine.fileDescrRight.objType != isNothing)
{
- mpz_set_ui(tmpInt, 0);
- returnValue = mpz_set_str(tmpInt, refLine.fileDescrRight.fileSize.c_str(), 10);
+
+ FreeFileSync::wxULongLongToMpz(tmpInt, refLine.fileDescrRight.fileSize);
mpz_add(filesizeRightView, filesizeRightView, tmpInt);
- assert (returnValue == 0);
objectsOnRightView++;
}
@@ -1906,7 +1902,7 @@ void MainDialog::updateStatusInformation(const UI_Grid& visibleGrid)
//show status information on "root" level. This cannot be accomplished in writeGrid since filesizes are already formatted for display there
wxString objectsViewLeft = numberToWxString(objectsOnLeftView);
- GlobalFunctions::includeNumberSeparator(objectsViewLeft);
+ globalFunctions::includeNumberSeparator(objectsViewLeft);
if (objectsOnLeftView == 1)
m_statusBar1->SetStatusText(wxString(_("1 item on left, ")) + FreeFileSync::formatFilesizeToShortString(mpz_class(filesizeLeftView)), 0);
else
@@ -1914,9 +1910,9 @@ void MainDialog::updateStatusInformation(const UI_Grid& visibleGrid)
wxString objectsTotal = numberToWxString(currentGridData.size());
- GlobalFunctions::includeNumberSeparator(objectsTotal);
+ globalFunctions::includeNumberSeparator(objectsTotal);
wxString objectsView = numberToWxString(visibleGrid.size());
- GlobalFunctions::includeNumberSeparator(objectsView);
+ globalFunctions::includeNumberSeparator(objectsView);
if (currentGridData.size() == 1)
m_statusBar1->SetStatusText(objectsView + _(" of ") + objectsTotal + _(" row in view"), 1);
else
@@ -1924,7 +1920,7 @@ void MainDialog::updateStatusInformation(const UI_Grid& visibleGrid)
wxString objectsViewRight = numberToWxString(objectsOnRightView);
- GlobalFunctions::includeNumberSeparator(objectsViewRight);
+ globalFunctions::includeNumberSeparator(objectsViewRight);
if (objectsOnRightView == 1)
m_statusBar1->SetStatusText(wxString(_("1 item on right, ")) + FreeFileSync::formatFilesizeToShortString(mpz_class(filesizeRightView)), 2);
else
@@ -1949,22 +1945,22 @@ void MainDialog::mapFileModelToUI(UI_Grid& output, const FileCompareResult& file
//process UI filter settings
switch (i->cmpResult)
{
- case FileOnLeftSideOnly:
+ case fileOnLeftSideOnly:
if (!leftOnlyFilesActive) continue;
break;
- case FileOnRightSideOnly:
+ case fileOnRightSideOnly:
if (!rightOnlyFilesActive) continue;
break;
- case RightFileNewer:
+ case rightFileNewer:
if (!rightNewerFilesActive) continue;
break;
- case LeftFileNewer:
+ case leftFileNewer:
if (!leftNewerFilesActive) continue;
break;
- case FilesDifferent:
+ case filesDifferent:
if (!differentFilesActive) continue;
break;
- case FilesEqual:
+ case filesEqual:
if (!equalFilesActive) continue;
break;
default:
@@ -1975,7 +1971,7 @@ void MainDialog::mapFileModelToUI(UI_Grid& output, const FileCompareResult& file
if (hideFiltered && !i->selectedForSynchronization)
continue;
- if (i->fileDescrLeft.objType == IsDirectory)
+ if (i->fileDescrLeft.objType == isDirectory)
{
gridline.leftFilename = wxEmptyString;
gridline.leftRelativePath = i->fileDescrLeft.relFilename;
@@ -1983,16 +1979,19 @@ void MainDialog::mapFileModelToUI(UI_Grid& output, const FileCompareResult& file
}
else
{
- gridline.leftFilename = i->fileDescrLeft.relFilename.AfterLast(FileNameSeparator);
- gridline.leftRelativePath = i->fileDescrLeft.relFilename.BeforeLast(FileNameSeparator);
- gridline.leftSize = GlobalFunctions::includeNumberSeparator(fileSize = i->fileDescrLeft.fileSize);
+ gridline.leftFilename = i->fileDescrLeft.relFilename.AfterLast(GlobalResources::fileNameSeparator);
+ gridline.leftRelativePath = i->fileDescrLeft.relFilename.BeforeLast(GlobalResources::fileNameSeparator);
+ if (i->fileDescrLeft.fileSize != 0)
+ gridline.leftSize = globalFunctions::includeNumberSeparator(fileSize = i->fileDescrLeft.fileSize.ToString());
+ else
+ gridline.leftSize = "";
}
- gridline.leftDate = i->fileDescrLeft.lastWriteTime;
+ gridline.leftDate = i->fileDescrLeft.lastWriteTime;
- gridline.cmpResult = evaluateCmpResult(i->cmpResult, i->selectedForSynchronization);
+ gridline.cmpResult = evaluateCmpResult(i->cmpResult, i->selectedForSynchronization);
gridline.linkToCurrentGridData = currentRow;
- if (i->fileDescrRight.objType == IsDirectory)
+ if (i->fileDescrRight.objType == isDirectory)
{
gridline.rightFilename = wxEmptyString;
gridline.rightRelativePath = i->fileDescrRight.relFilename;
@@ -2000,11 +1999,14 @@ void MainDialog::mapFileModelToUI(UI_Grid& output, const FileCompareResult& file
}
else
{
- gridline.rightFilename = i->fileDescrRight.relFilename.AfterLast(FileNameSeparator);
- gridline.rightRelativePath = i->fileDescrRight.relFilename.BeforeLast(FileNameSeparator);
- gridline.rightSize = GlobalFunctions::includeNumberSeparator(fileSize = i->fileDescrRight.fileSize);
+ gridline.rightFilename = i->fileDescrRight.relFilename.AfterLast(GlobalResources::fileNameSeparator);
+ gridline.rightRelativePath = i->fileDescrRight.relFilename.BeforeLast(GlobalResources::fileNameSeparator);
+ if (i->fileDescrRight.fileSize != 0)
+ gridline.rightSize = globalFunctions::includeNumberSeparator(fileSize = i->fileDescrRight.fileSize.ToString());
+ else
+ gridline.rightSize = "";
}
- gridline.rightDate = i->fileDescrRight.lastWriteTime;
+ gridline.rightDate = i->fileDescrRight.lastWriteTime;
output.push_back(gridline);
}
@@ -2020,7 +2022,6 @@ void updateUI_Now()
//process UI events and prevent application from "not responding" -> NO performance issue!
wxTheApp->Yield();
-
// while (wxTheApp->Pending())
// wxTheApp->Dispatch();
}
@@ -2032,7 +2033,7 @@ bool updateUI_IsAllowed()
wxLongLong newExec = wxGetLocalTimeMillis();
- if (newExec - lastExec >= 100) //perform ui updates not more often than necessary, 100 seems to be a good value with only a minimal performance loss
+ if (newExec - lastExec >= uiUpdateInterval) //perform ui updates not more often than necessary
{
lastExec = newExec;
return true;
@@ -2043,11 +2044,10 @@ bool updateUI_IsAllowed()
//########################################################################################################
-CompareStatusUpdater::CompareStatusUpdater(MainDialog* dlg, wxStatusBar* mainWindowBar) :
+CompareStatusUpdater::CompareStatusUpdater(MainDialog* dlg) :
mainDialog(dlg),
- statusBar(mainWindowBar),
suppressUI_Errormessages(false),
- numberOfScannedObjects(0)
+ currentProcess(-1)
{
//prevent user input during "compare", do not disable maindialog since abort-button would also be disabled
//it's not nice, but works - even has the advantage that certain actions are still possible: exit, about..
@@ -2071,13 +2071,19 @@ CompareStatusUpdater::CompareStatusUpdater(MainDialog* dlg, wxStatusBar* mainWin
mainDialog->m_panel3->Disable();
mainDialog->m_bpButton201->Disable();
mainDialog->m_choiceLoad->Disable();
+ mainDialog->m_bpButton10->Disable();
//show abort button
mainDialog->m_buttonAbort->Show();
mainDialog->m_bpButtonCompare->Hide();
+ mainDialog->m_buttonAbort->SetFocus();
+
+ //display status panel during compare
+ statusPanel = new CompareStatus(mainDialog);
+ mainDialog->bSizer1->Insert(1, statusPanel, 0, wxEXPAND | wxALL, 5 );
+ updateUI_Now();
mainDialog->Layout();
mainDialog->Refresh();
- mainDialog->m_buttonAbort->SetFocus();
}
CompareStatusUpdater::~CompareStatusUpdater()
@@ -2103,31 +2109,56 @@ CompareStatusUpdater::~CompareStatusUpdater()
mainDialog->m_panel3->Enable();
mainDialog->m_bpButton201->Enable();
mainDialog->m_choiceLoad->Enable();
+ mainDialog->m_bpButton10->Enable();
if (abortionRequested)
mainDialog->pushStatusInformation(_("Operation aborted!"));
mainDialog->m_buttonAbort->Hide();
mainDialog->m_bpButtonCompare->Show();
+
+ //remove status panel from main window
+ mainDialog->bSizer1->Detach(statusPanel);
+ statusPanel->Destroy();
+ updateUI_Now();
mainDialog->Layout();
mainDialog->Refresh();
}
-void CompareStatusUpdater::updateStatus(const wxString& text)
+inline
+void CompareStatusUpdater::updateStatusText(const wxString& text)
+{
+ statusPanel->setStatusText_NoUpdate(text);
+}
+
+
+void CompareStatusUpdater::initNewProcess(int objectsTotal, double dataTotal, int processID)
{
- //not relevant for "compare"; it's sufficient to display the number of scanned files/folders
+ currentProcess = processID;
+
+ if (currentProcess == FreeFileSync::scanningFilesProcess)
+ ;
+ else if (currentProcess == FreeFileSync::calcMD5Process)
+ statusPanel->resetMD5Gauge(objectsTotal, dataTotal);
+ else assert(false);
}
+
inline
-void CompareStatusUpdater::updateProgressIndicator(double number)
+void CompareStatusUpdater::updateProcessedData(int objectsProcessed, double dataProcessed)
{
- numberOfScannedObjects+= int(number); //conversion is harmless, since number == 1 in case of "compare"
+ if (currentProcess == FreeFileSync::scanningFilesProcess)
+ statusPanel->incScannedFiles_NoUpdate(objectsProcessed);
+ else if (currentProcess == FreeFileSync::calcMD5Process)
+ statusPanel->incProcessedMD5Data_NoUpdate(objectsProcessed, dataProcessed);
+ else assert(false);
}
+
int CompareStatusUpdater::reportError(const wxString& text)
{
if (suppressUI_Errormessages)
- return StatusUpdater::Continue;
+ return StatusUpdater::continueNext;
wxString errorMessage = text + _("\n\nContinue with next object, retry or abort comparison?");
@@ -2138,11 +2169,11 @@ int CompareStatusUpdater::reportError(const wxString& text)
switch (rv)
{
- case ErrorDlg::ContinueButtonPressed:
- return StatusUpdater::Continue;
- case ErrorDlg::RetryButtonPressed:
- return StatusUpdater::Retry;
- case ErrorDlg::AbortButtonPressed:
+ case ErrorDlg::continueButtonPressed:
+ return StatusUpdater::continueNext;
+ case ErrorDlg::retryButtonPressed:
+ return StatusUpdater::retry;
+ case ErrorDlg::abortButtonPressed:
{
abortionRequested = true;
throw AbortThisProcess();
@@ -2151,7 +2182,7 @@ int CompareStatusUpdater::reportError(const wxString& text)
assert (false);
}
- return StatusUpdater::Continue; //dummy return value
+ return StatusUpdater::continueNext; //dummy return value
}
@@ -2161,22 +2192,20 @@ void CompareStatusUpdater::triggerUI_Refresh()
if (abortionRequested) throw AbortThisProcess(); //abort can be triggered by syncStatusFrame
if (updateUI_IsAllowed()) //test if specific time span between ui updates is over
- {
- statusBar->SetStatusText(wxString(_("Scanning files/folders: ")) + numberToWxString(numberOfScannedObjects), 1);
- updateUI_Now();
- }
+ statusPanel->updateStatusPanelNow();
}
//########################################################################################################
-SyncStatusUpdater::SyncStatusUpdater(wxWindow* dlg, double gaugeTotalElements) :
- suppressUI_Errormessages(false)
+SyncStatusUpdater::SyncStatusUpdater(wxWindow* dlg, bool hideErrorMessages) :
+ suppressUI_Errormessages(hideErrorMessages)
{
- syncStatusFrame = new SyncStatus(this, gaugeTotalElements, dlg);
+ syncStatusFrame = new SyncStatus(this, dlg);
syncStatusFrame->Show();
updateUI_Now();
}
+
SyncStatusUpdater::~SyncStatusUpdater()
{
if (abortionRequested)
@@ -2192,23 +2221,38 @@ SyncStatusUpdater::~SyncStatusUpdater()
result = wxString(_("Warning: Synchronization failed for ")) + numberToWxString(failedItems) + _(" item(s):\n\n");
for (unsigned int j = 0; j < failedItems; ++j)
result+= unhandledErrors[j] + "\n";
+ result+= "\n";
}
+
+ if (failedItems)
+ result+= _("Not all items have been synchronized! You may try to synchronize the remaining items again (WITHOUT having to re-compare)!");
+ else if (abortionRequested)
+ result+= _("Synchronization aborted: You may try to synchronize remaining items again (WITHOUT having to re-compare)!");
+
syncStatusFrame->setStatusText_NoUpdate(result);
syncStatusFrame->updateStatusDialogNow();
}
inline
-void SyncStatusUpdater::updateStatus(const wxString& text)
+void SyncStatusUpdater::updateStatusText(const wxString& text)
{
syncStatusFrame->setStatusText_NoUpdate(text);
}
+void SyncStatusUpdater::initNewProcess(int objectsTotal, double dataTotal, int processID)
+{
+ assert (processID == FreeFileSync::synchronizeFilesProcess);
+
+ syncStatusFrame->resetGauge(objectsTotal, dataTotal);
+}
+
+
inline
-void SyncStatusUpdater::updateProgressIndicator(double number)
+void SyncStatusUpdater::updateProcessedData(int objectsProcessed, double dataProcessed)
{
- syncStatusFrame->incProgressIndicator_NoUpdate(number);
+ syncStatusFrame->incProgressIndicator_NoUpdate(objectsProcessed, dataProcessed);
}
@@ -2217,7 +2261,7 @@ int SyncStatusUpdater::reportError(const wxString& text)
if (suppressUI_Errormessages)
{
unhandledErrors.Add(text);
- return StatusUpdater::Continue;
+ return StatusUpdater::continueNext;
}
wxString errorMessage = text + _("\n\nContinue with next object, retry or abort synchronization?");
@@ -2229,12 +2273,12 @@ int SyncStatusUpdater::reportError(const wxString& text)
switch (rv)
{
- case ErrorDlg::ContinueButtonPressed:
+ case ErrorDlg::continueButtonPressed:
unhandledErrors.Add(text);
- return StatusUpdater::Continue;
- case ErrorDlg::RetryButtonPressed:
- return StatusUpdater::Retry;
- case ErrorDlg::AbortButtonPressed:
+ return StatusUpdater::continueNext;
+ case ErrorDlg::retryButtonPressed:
+ return StatusUpdater::retry;
+ case ErrorDlg::abortButtonPressed:
{
unhandledErrors.Add(text);
abortionRequested = true;
@@ -2244,7 +2288,7 @@ int SyncStatusUpdater::reportError(const wxString& text)
assert (false);
}
- return StatusUpdater::Continue; //dummy return value
+ return StatusUpdater::continueNext; //dummy return value
}
@@ -2254,9 +2298,8 @@ void SyncStatusUpdater::triggerUI_Refresh()
throw AbortThisProcess(); //abort can be triggered by syncStatusFrame
if (updateUI_IsAllowed()) //test if specific time span between ui updates is over
- {
syncStatusFrame->updateStatusDialogNow();
- }
}
+
bgstack15