diff options
author | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 16:50:45 +0200 |
---|---|---|
committer | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 16:50:45 +0200 |
commit | eca5f1c8831fd0776e57a174362b0515104174c2 (patch) | |
tree | 5cba4e6c74d1f5c78018eff1b09b1973c5b7604f | |
parent | 1.6 (diff) | |
download | FreeFileSync-eca5f1c8831fd0776e57a174362b0515104174c2.tar.gz FreeFileSync-eca5f1c8831fd0776e57a174362b0515104174c2.tar.bz2 FreeFileSync-eca5f1c8831fd0776e57a174362b0515104174c2.zip |
1.7
-rw-r--r-- | Application.cpp | 210 | ||||
-rw-r--r-- | Application.h | 8 | ||||
-rw-r--r-- | Changelog.txt | 11 | ||||
-rw-r--r-- | FreeFileSync.cpp | 426 | ||||
-rw-r--r-- | FreeFileSync.h | 42 | ||||
-rw-r--r-- | Readme.txt | 17 | ||||
-rw-r--r-- | Resources.dat | bin | 113625 -> 113488 bytes | |||
-rw-r--r-- | german.lng | 62 | ||||
-rw-r--r-- | library/CustomGrid.cpp | 37 | ||||
-rw-r--r-- | library/globalFunctions.cpp | 4 | ||||
-rw-r--r-- | library/globalFunctions.h | 17 | ||||
-rw-r--r-- | library/misc.cpp | 59 | ||||
-rw-r--r-- | library/multithreading.cpp | 2 | ||||
-rw-r--r-- | library/multithreading.h | 2 | ||||
-rw-r--r-- | library/resources.cpp | 132 | ||||
-rw-r--r-- | library/wxWidgets.h | 5 | ||||
-rw-r--r-- | ui/MainDialog.cpp | 388 | ||||
-rw-r--r-- | ui/MainDialog.h | 9 | ||||
-rw-r--r-- | ui/SmallDialogs.cpp | 30 | ||||
-rw-r--r-- | ui/SmallDialogs.h | 16 | ||||
-rw-r--r-- | ui/SyncDialog.cpp | 164 | ||||
-rw-r--r-- | ui/guiGenerated.cpp | 128 | ||||
-rw-r--r-- | ui/guiGenerated.h | 20 |
23 files changed, 971 insertions, 818 deletions
diff --git a/Application.cpp b/Application.cpp index 81c4ac87..775fac65 100644 --- a/Application.cpp +++ b/Application.cpp @@ -42,7 +42,7 @@ void Application::initialize() { //set working directory to current executable directory if (!wxSetWorkingDirectory(wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath())) - throw runtime_error(_("Could not set working directory to directory containing executable file!")); + throw RuntimeException(_("Could not set working directory to directory containing executable file!")); //set program language programLanguage.loadLanguageFromCfg(); @@ -54,7 +54,7 @@ void Application::initialize() GlobalResources::loadResourceFiles(); //test if ffs is to be started on UI with config file passed as commandline parameter - wxString configFileForUI = FreeFileSync::FFS_LastConfigFile; + wxString configFileForUI = FreeFileSync::FfsLastConfigFile; if (argc > 1 && wxFileExists(argv[1]) && FreeFileSync::isFFS_ConfigFile(argv[1])) configFileForUI = argv[1]; @@ -74,7 +74,7 @@ void Application::initialize() else //no parameters passed: continue with UI { //show UI dialog - MainDialog* frame = new MainDialog(0L, configFileForUI, &programLanguage); + MainDialog* frame = new MainDialog(NULL, configFileForUI, &programLanguage); frame->SetIcon(*GlobalResources::programIcon); //set application icon frame->Show(); } @@ -87,9 +87,9 @@ int Application::OnRun() { wxApp::OnRun(); } - catch (std::runtime_error& theException) //catch runtime errors during main event loop + catch (const RuntimeException& theException) //catch runtime errors during main event loop { - wxMessageBox(_(theException.what()), _("An exception occured!"), wxOK | wxICON_ERROR); + wxMessageBox(theException.show(), _("An exception occured!"), wxOK | wxICON_ERROR); return -1; } return returnValue; @@ -111,14 +111,14 @@ SyncDirection convertCmdlineCfg(const wxString& cfg, const int i) switch (cfg[i]) { case 'L': - return syncDirLeft; + return SYNC_DIR_LEFT; case 'R': - return syncDirRight; + return SYNC_DIR_RIGHT; case 'N': - return syncDirNone; + return SYNC_DIR_NONE; default: assert(false); - return syncDirNone; + return SYNC_DIR_NONE; } } @@ -126,36 +126,38 @@ SyncDirection convertCmdlineCfg(const wxString& cfg, const int i) void Application::logInit() { wxString tmp = wxDateTime::Now().FormatISOTime(); - tmp.Replace(":", ""); - wxString logfileName = wxString("FFS_") + wxDateTime::Now().FormatISODate() + '_' + tmp + ".log"; - - logFile.open(logfileName.c_str()); - if (!logFile) - throw std::runtime_error(_("Unable to create logfile!")); - logFile<<_("FreeFileSync (Date: ") + wxDateTime::Now().FormatDate() + _(" Time: ") + wxDateTime::Now().FormatTime() + ")"<<endl; - logFile<<_("-------------------------------------------------")<<endl; - logFile<<endl; - logFile<<_("Log-messages:")<<endl; - logFile<<endl; + tmp.Replace(wxT(":"), wxEmptyString); + wxString logfileName = wxString(wxT("FFS_")) + wxDateTime::Now().FormatISODate() + '_' + tmp + wxT(".log"); + + logFile.Open(logfileName.c_str(), wxT("wb")); + if (!logFile.IsOpened()) + throw RuntimeException(_("Unable to create logfile!")); + logFile.Write(wxString(_("FreeFileSync (Date: ")) + wxDateTime::Now().FormatDate() + _(" Time: ") + wxDateTime::Now().FormatTime() + wxT(")") + wxChar('\n')); + logFile.Write(wxString(_("-------------------------------------------------")) + '\n'); + logFile.Write(wxChar('\n')); + logFile.Write(_("Log-messages:\n-------------")); + logFile.Write(wxChar('\n')); logWrite(_("Start")); + logFile.Write(wxChar('\n')); } void Application::logWrite(const wxString& logText, const wxString& problemType) { - logFile<<"["<<wxDateTime::Now().FormatTime()<<"] "; + logFile.Write(wxString(wxT("[")) + wxDateTime::Now().FormatTime() + wxT("] ")); if (problemType != wxEmptyString) - logFile<<problemType<<": "; + logFile.Write(problemType + wxT(": ")); - logFile<<logText<<endl; + logFile.Write(logText + wxChar('\n')); } void Application::logClose(const wxString& finalText) { + logFile.Write(wxChar('\n')); logWrite(finalText, _("Stop")); - logFile.close(); + //logFile.close(); <- not needed } @@ -167,7 +169,7 @@ void Application::parseCommandline() { wxCMD_LINE_SWITCH, wxT("h"), wxT("help"), - wxT(_("Displays help on the command line parameters\n")), + _("Displays help on the command line parameters\n"), wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP }, @@ -287,12 +289,12 @@ void Application::parseCommandline() if (parser.Found(GlobalResources::paramInclude, &included)) filteringEnabled = true; else - included = "*"; + included = wxT("*"); if (parser.Found(GlobalResources::paramExclude, &excluded)) filteringEnabled = true; else - excluded = ""; + excluded = wxEmptyString; //until here all options and parameters have been set //-------------------------------------------------------------------- @@ -318,28 +320,28 @@ void Application::parseCommandline() //check if directories exist if (!wxDirExists(leftDir)) { - wxString errorMessage = wxString(_("Directory ")) + leftDir + _(" does not exist."); + wxString errorMessage = wxString(_("Directory ")) + wxT("\"") + leftDir + wxT("\"") + _(" does not exist."); wxString statusMessage = wxString(_("Synchronization aborted!")); if (silent) { logWrite(errorMessage, _("Warning")); logClose(statusMessage); } - else wxMessageBox(errorMessage + "\n\n" + statusMessage, _("Warning"), wxICON_WARNING); + else wxMessageBox(errorMessage + wxT("\n\n") + statusMessage, _("Warning"), wxICON_WARNING); returnValue = -2; return; } else if (!wxDirExists(rightDir)) { - wxString errorMessage = wxString(_("Directory ")) + rightDir + _(" does not exist."); + wxString errorMessage = wxString(_("Directory ")) + wxT("\"") + rightDir + wxT("\"") + _(" does not exist."); wxString statusMessage = wxString(_("Synchronization aborted!")); if (silent) { logWrite(errorMessage, _("Warning")); logClose(statusMessage); } - else wxMessageBox(errorMessage + "\n\n" + statusMessage, _("Warning"), wxICON_WARNING); + else wxMessageBox(errorMessage + wxT("\n\n") + statusMessage, _("Warning"), wxICON_WARNING); returnValue = -2; return; @@ -357,7 +359,7 @@ void Application::parseCommandline() logWrite(errorMessage, _("Error")); logClose(statusMessage); } - else wxMessageBox(errorMessage + "\n\n" + statusMessage, _("Error"), wxICON_WARNING); + else wxMessageBox(errorMessage + wxT("\n\n") + statusMessage, _("Error"), wxICON_WARNING); returnValue = -2; return; @@ -367,14 +369,14 @@ void Application::parseCommandline() //until here all options and parameters are consistent //-------------------------------------------------------------------- - CompareVariant cmpVar = compareByContent; //dummy value to suppress compiler warning + CompareVariant cmpVar = CMP_BY_CONTENT; //dummy value to suppress compiler warning SyncConfiguration syncConfiguration; FileCompareResult currentGridData; if (cmp == GlobalResources::valueSizeDate) - cmpVar = compareByTimeAndSize; + cmpVar = CMP_BY_TIME_SIZE; else if (cmp == GlobalResources::valueContent) - cmpVar = compareByContent; + cmpVar = CMP_BY_CONTENT; else assert (false); @@ -384,12 +386,12 @@ void Application::parseCommandline() syncConfiguration.rightNewer = convertCmdlineCfg(cfg, 3); syncConfiguration.different = convertCmdlineCfg(cfg, 4); - //class handling status updates and error messages - CommandLineStatusUpdater statusUpdater(this, continueOnError, silent); - //begin of synchronization process (all in one try-catch block) try { + //class handling status updates and error messages + CommandLineStatusUpdater statusUpdater(this, continueOnError, silent); + //COMPARE DIRECTORIES //unsigned int startTime = GetTickCount(); FreeFileSync::startCompareProcess(currentGridData, @@ -399,48 +401,36 @@ void Application::parseCommandline() &statusUpdater); //wxMessageBox(wxString::Format(wxT("%i"), unsigned(GetTickCount()) - startTime)); - //check if folders are already in sync - bool nothingToSync = true; - for (FileCompareResult::const_iterator i = currentGridData.begin(); i != currentGridData.end(); ++i) - if (i->cmpResult != filesEqual) - { - nothingToSync = false; - break; - } +//APPLY FILTERS + if (filteringEnabled) + FreeFileSync::filterCurrentGridData(currentGridData, included, excluded); - if (nothingToSync) +//check if there are files/folders to be sync'ed at all + int objectsToCreate = 0; + int objectsToOverwrite = 0; + int objectsToDelete = 0; + double dataToProcess = 0; + FreeFileSync::calcTotalBytesToSync(objectsToCreate, + objectsToOverwrite, + objectsToDelete, + dataToProcess, + currentGridData, + syncConfiguration); + if (objectsToCreate + objectsToOverwrite + objectsToDelete == 0) { - wxString errorMessage = _("Nothing to synchronize. Both directories seem to contain the same data!"); - if (silent) - logClose(errorMessage); - else - statusUpdater.updateFinalStatus(errorMessage); + statusUpdater.noSynchronizationNeeded(); //inform about this special case returnValue = -3; return; } -//APPLY FILTERS - if (filteringEnabled) - FreeFileSync::filterCurrentGridData(currentGridData, included, excluded); - //START SYNCHRONIZATION //unsigned int startTime = GetTickCount(); FreeFileSync::startSynchronizationProcess(currentGridData, syncConfiguration, &statusUpdater, useRecycler); //default: do not use recycle bin since it's not sure if its possible //wxMessageBox(wxString::Format(wxT("%i"), unsigned(GetTickCount()) - startTime)); - -//show success message - wxString successMessage = _("Synchronization completed."); - if (silent) - logClose(successMessage); - else - statusUpdater.updateFinalStatus(successMessage); } catch (AbortThisProcess& theException) //exit used by statusUpdater { - if (silent) - logClose(_("Synchronization aborted!")); - returnValue = -4; return; } @@ -454,45 +444,82 @@ CommandLineStatusUpdater::CommandLineStatusUpdater(Application* application, boo app(application), continueErrors(continueOnError), silentMode(silent), - currentProcess(-1) + currentProcess(-1), + synchronizationNeeded(true) { if (!silentMode) { - syncStatusFrame = new SyncStatus(this, 0); + syncStatusFrame = new SyncStatus(this, NULL); syncStatusFrame->Show(); } } + CommandLineStatusUpdater::~CommandLineStatusUpdater() { - if (!silentMode) + unsigned int failedItems = unhandledErrors.GetCount(); + + //output the result + if (silentMode) + { + if (abortionRequested) + app->logClose(_("Synchronization aborted!")); + else if (failedItems) + app->logClose(_("Synchronization completed with errors!")); + else + { + if (!synchronizationNeeded) + app->logWrite(_("Nothing to synchronize. Both directories adhere to the sync-configuration!"), _("Info")); + app->logClose(_("Synchronization completed successfully.")); + } + } + else { - //print the results list - unsigned int failedItems = unhandledErrors.GetCount(); - wxString errorMessages; + wxString finalMessage; if (failedItems) { - errorMessages = wxString(_("Warning: Synchronization failed for ")) + globalFunctions::numberToWxString(failedItems) + _(" item(s):\n\n"); + finalMessage = wxString(_("Warning: Synchronization failed for ")) + globalFunctions::numberToWxString(failedItems) + _(" item(s):\n\n"); for (unsigned int j = 0; j < failedItems; ++j) - errorMessages+= unhandledErrors[j] + "\n"; - - syncStatusFrame->setStatusText_NoUpdate(errorMessages); + finalMessage+= unhandledErrors[j] + wxT("\n"); + finalMessage+= wxT("\n"); } //notify to syncStatusFrame that current process has ended if (abortionRequested) - syncStatusFrame->processHasFinished(SyncStatus::statusAborted); //enable okay and close events + { + finalMessage+= _("Synchronization aborted!"); + syncStatusFrame->setStatusText_NoUpdate(finalMessage); + syncStatusFrame->processHasFinished(SyncStatus::ABORTED); //enable okay and close events + } else if (failedItems) - syncStatusFrame->processHasFinished(SyncStatus::statusCompletedWithErrors); + { + finalMessage+= _("Synchronization completed with errors!"); + syncStatusFrame->setStatusText_NoUpdate(finalMessage); + syncStatusFrame->processHasFinished(SyncStatus::FINISHED_WITH_ERROR); + } else - syncStatusFrame->processHasFinished(SyncStatus::statusCompletedWithSuccess); + { + if (synchronizationNeeded) + finalMessage+= _("Synchronization completed successfully."); + else + finalMessage+= _("Nothing to synchronize. Both directories adhere to the sync-configuration!"); + + syncStatusFrame->setStatusText_NoUpdate(finalMessage); + syncStatusFrame->processHasFinished(SyncStatus::FINISHED_WITH_SUCCESS); + } } } + inline void CommandLineStatusUpdater::updateStatusText(const wxString& text) { - if (!silentMode) + if (silentMode) + { + if (currentProcess == FreeFileSync::synchronizeFilesProcess) + app->logWrite(text, _("Info")); + } + else syncStatusFrame->setStatusText_NoUpdate(text); } @@ -504,18 +531,18 @@ void CommandLineStatusUpdater::initNewProcess(int objectsTotal, double dataTotal if (!silentMode) { if (currentProcess == FreeFileSync::scanningFilesProcess) - syncStatusFrame->setCurrentStatus(SyncStatus::statusScanning); + syncStatusFrame->setCurrentStatus(SyncStatus::SCANNING); else if (currentProcess == FreeFileSync::compareFileContentProcess) { syncStatusFrame->resetGauge(objectsTotal, dataTotal); - syncStatusFrame->setCurrentStatus(SyncStatus::statusComparing); + syncStatusFrame->setCurrentStatus(SyncStatus::COMPARING); } else if (currentProcess == FreeFileSync::synchronizeFilesProcess) { syncStatusFrame->resetGauge(objectsTotal, dataTotal); - syncStatusFrame->setCurrentStatus(SyncStatus::statusSynchronizing); + syncStatusFrame->setCurrentStatus(SyncStatus::SYNCHRONIZING); } else assert(false); } @@ -542,6 +569,7 @@ int CommandLineStatusUpdater::reportError(const wxString& text) { if (silentMode) //write error message log and abort the complete session if necessary { + unhandledErrors.Add(text); app->logWrite(text, _("Error")); if (continueErrors) // <- /|\ before return, the logfile is written!!! @@ -560,12 +588,10 @@ int CommandLineStatusUpdater::reportError(const wxString& text) return StatusUpdater::continueNext; } - syncStatusFrame->updateStatusDialogNow(); - wxString errorMessage = text + _("\n\nContinue with next object, retry or abort synchronization?"); - ErrorDlg* errorDlg = new ErrorDlg(errorMessage, continueErrors); + syncStatusFrame->updateStatusDialogNow(); int rv = errorDlg->ShowModal(); errorDlg->Destroy(); @@ -584,17 +610,17 @@ int CommandLineStatusUpdater::reportError(const wxString& text) } default: assert (false); + return StatusUpdater::continueNext; } } - - return StatusUpdater::continueNext; //dummy return value } inline void CommandLineStatusUpdater::triggerUI_Refresh() { - if (abortionRequested) throw AbortThisProcess(); + if (abortionRequested) + throw AbortThisProcess(); //may be triggered by the SyncStatusDialog if (!silentMode) if (updateUI_IsAllowed()) //test if specific time span between ui updates is over @@ -602,9 +628,7 @@ void CommandLineStatusUpdater::triggerUI_Refresh() } -inline -void CommandLineStatusUpdater::updateFinalStatus(const wxString& text) //set by parsedCommandline() to communicate e.g. the final "success message" +void CommandLineStatusUpdater::noSynchronizationNeeded() { - if (!silentMode) - syncStatusFrame->setStatusText_NoUpdate(text); + synchronizationNeeded = false;; } diff --git a/Application.h b/Application.h index 56298898..4e6a4ef2 100644 --- a/Application.h +++ b/Application.h @@ -12,7 +12,7 @@ #include <wx/app.h> #include <wx/cmdline.h> -#include <fstream> +#include <wx/ffile.h> #include "FreeFileSync.h" #include "ui/smallDialogs.h" #include "library/misc.h" @@ -36,8 +36,7 @@ private: void parseCommandline(); bool applicationRunsOnCommandLineWithoutWindows; - - ofstream logFile; + wxFFile logFile; CustomLocale programLanguage; int returnValue; @@ -56,7 +55,7 @@ public: int reportError(const wxString& text); void triggerUI_Refresh(); - void updateFinalStatus(const wxString& text); + void noSynchronizationNeeded(); private: Application* app; @@ -66,6 +65,7 @@ private: wxArrayString unhandledErrors; //list of non-resolved errors int currentProcess; + bool synchronizationNeeded; }; diff --git a/Changelog.txt b/Changelog.txt index fa049ca7..9a1e967a 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,6 +1,16 @@ FreeFileSync ------------ +Changelog v1.7 +-------------- +Display only those view filter buttons that are actually needed +Compare by size and date: last write time may differ by up to 2 seconds (NTFS vs FAT32) +Fixed minor issue with trailing path separator when creating batch jobs +Fixed minor issue with window sizes not being remembered in some special situation +Further improved Unicode compliance +Updated German translation + + Changelog v1.6 -------------- Significantly improved speed of filtering files and view (< 10 ms for > 200.000 rows(!)) @@ -14,6 +24,7 @@ Recycle Bin usage as commandline parameter New menu bar Program language selectable from menu UI-option to create sync jobs (batch files) for automated synchronization +Updated German translation Changelog v1.5 diff --git a/FreeFileSync.cpp b/FreeFileSync.cpp index 9781e102..a994aab8 100644 --- a/FreeFileSync.cpp +++ b/FreeFileSync.cpp @@ -4,9 +4,9 @@ #include "FreeFileSync.h" #include "library/globalFunctions.h" #include <wx/filename.h> -#include <fstream> #include "library/resources.h" #include <sys/stat.h> +#include <wx/ffile.h> #ifdef FFS_WIN #include <windows.h> @@ -19,8 +19,8 @@ using namespace globalFunctions; -const wxString FreeFileSync::FFS_ConfigFileID = "FFS_CONFIG"; -const wxString FreeFileSync::FFS_LastConfigFile = "LastRun.ffs"; +const string FreeFileSync::FfsConfigFileID = "FFS_CONFIG"; +const wxString FreeFileSync::FfsLastConfigFile = wxT("LastRun.ffs"); inline wxString formatTime(unsigned int number) @@ -41,7 +41,7 @@ wxString formatTime(unsigned int number) { wxString result; if (result.Printf(wxT("%d"), number) < 0) - throw std::runtime_error("Error when converting int to wxString"); + throw RuntimeException(_("Error when converting int to wxString")); return result; } } @@ -56,7 +56,7 @@ void FreeFileSync::getFileInformation(FileInfo& output, const wxString& filename HANDLE fileHandle; if ((fileHandle = FindFirstFile(filename.c_str(), &winFileInfo)) == INVALID_HANDLE_VALUE) - throw FileError(wxString(_("Could not retrieve file info for: ")) + "\"" + filename + "\""); + throw FileError(wxString(_("Could not retrieve file info for: ")) + wxT("\"") + filename + wxT("\"")); FindClose(fileHandle); @@ -64,20 +64,19 @@ void FreeFileSync::getFileInformation(FileInfo& output, const wxString& filename &winFileInfo.ftLastWriteTime, // pointer to UTC file time to convert &localFileTime // pointer to converted file time ) == 0) - throw std::runtime_error(_("Error converting FILETIME to local FILETIME")); - + throw RuntimeException(_("Error converting FILETIME to local FILETIME")); if (FileTimeToSystemTime( &localFileTime, // pointer to file time to convert &time // pointer to structure to receive system time ) == 0) - throw std::runtime_error(_("Error converting FILETIME to SYSTEMTIME")); + throw RuntimeException(_("Error converting FILETIME to SYSTEMTIME")); - output.lastWriteTime = numberToWxString(time.wYear) + "-" + - formatTime(time.wMonth) + "-" + - formatTime(time.wDay) + " " + - formatTime(time.wHour) + ":" + - formatTime(time.wMinute) + ":" + + output.lastWriteTime = numberToWxString(time.wYear) + wxT("-") + + formatTime(time.wMonth) + wxT("-") + + formatTime(time.wDay) + wxT(" ") + + formatTime(time.wHour) + wxT(":") + + formatTime(time.wMinute) + wxT(":") + formatTime(time.wSecond); //UTC time @@ -122,7 +121,7 @@ struct MemoryAllocator delete [] buffer2; } - static const unsigned int bufferSize = 1024*256; //256 kb seems to be the perfect buffer size + static const unsigned int bufferSize = 1024 * 256; //256 kb seems to be the perfect buffer size unsigned char* buffer1; unsigned char* buffer2; }; @@ -132,41 +131,31 @@ bool filesHaveSameContent(const wxString& filename1, const wxString& filename2) { static MemoryAllocator memory; - FILE* file1 = fopen(filename1.c_str(), "rb"); - if (!file1) - throw FileError(wxString(_("Could not open file: ")) + "\"" + filename1 + "\""); + wxFFile file1(filename1.c_str(), wxT("rb")); + if (!file1.IsOpened()) + throw FileError(wxString(_("Could not open file: ")) + wxT("\"") + filename1 + wxT("\"")); - FILE* file2 = fopen(filename2.c_str(), "rb"); - if (!file2) - { - fclose(file1); //NEVER forget clean-up - throw FileError(wxString(_("Could not open file: ")) + "\"" + filename2 + "\""); - } + wxFFile file2(filename2.c_str(), wxT("rb")); + if (!file2.IsOpened()) //NO cleanup necessary for wxFFile + throw FileError(wxString(_("Could not open file: ")) + wxT("\"") + filename2 + wxT("\"")); - bool returnValue = true; do { - unsigned int length1 = fread(memory.buffer1, 1, memory.bufferSize, file1); - if (ferror(file1)) throw FileError(wxString(_("Error reading file: ")) + "\"" + filename1 + "\""); + size_t length1 = file1.Read(memory.buffer1, memory.bufferSize); + if (file1.Error()) throw FileError(wxString(_("Error reading file: ")) + wxT("\"") + filename1 + wxT("\"")); - unsigned int length2 = fread(memory.buffer2, 1, memory.bufferSize, file2); - if (ferror(file2)) throw FileError(wxString(_("Error reading file: ")) + "\"" + filename2 + "\""); + size_t length2 = file2.Read(memory.buffer2, memory.bufferSize); + if (file2.Error()) throw FileError(wxString(_("Error reading file: ")) + wxT("\"") + filename2 + wxT("\"")); if (length1 != length2 || memcmp(memory.buffer1, memory.buffer2, length1) != 0) - { - returnValue = false; - break; - } + return false; } - while (!feof(file1)); - - if (!feof(file2)) - returnValue = false; + while (!file1.Eof()); - fclose(file1); - fclose(file2); + if (!file2.Eof()) + return false; - return returnValue; + return true; } @@ -174,12 +163,27 @@ void FreeFileSync::generateFileAndFolderDescriptions(DirectoryDescrType& output, { assert (updateClass); - output.clear(); + while (true) + { + output.clear(); + + //get all files and folders from directory (and subdirectories) + information + GetAllFilesFull traverser(output, getFormattedDirectoryName(directory), updateClass); + wxDir dir(directory); - //get all files and folders from directory (and subdirectories) + information - GetAllFilesFull traverser(output, getFormattedDirectoryName(directory), updateClass); - wxDir dir(directory); - dir.Traverse(traverser); + if (dir.Traverse(traverser) != (size_t)-1) + break; //traversed successfully + else + { + int rv = updateClass->reportError(wxString(_("Error traversing directory ")) + wxT("\"") + directory + wxT("\"")); + if (rv == StatusUpdater::continueNext) + break; + else if (rv == StatusUpdater::retry) + ; //continue with loop + else + assert (false); + } + } } @@ -251,6 +255,8 @@ void calcTotalDataForCompare(int& objectsTotal, double& dataTotal, const FileCom void FreeFileSync::startCompareProcess(FileCompareResult& output, const wxString& dirLeft, const wxString& dirRight, CompareVariant cmpVar, StatusUpdater* statusUpdater) { + wxLogNull dummy; //hide wxWidgets log messages + assert (statusUpdater); //################################################################################################################################################ @@ -274,7 +280,7 @@ void FreeFileSync::startCompareProcess(FileCompareResult& output, const wxString FileCompareLine newline; set<int> delayedContentCompare; //compare of file content happens AFTER finding corresponding files - //in order to separate into two processe (needed by progress indicators) + //in order to separate into two processes (needed by progress indicators) //find files/folders that exist in left file model but not in right model for (DirectoryDescrType::iterator i = directoryLeft.begin(); i != directoryLeft.end(); ++i) @@ -283,7 +289,7 @@ void FreeFileSync::startCompareProcess(FileCompareResult& output, const wxString newline.fileDescrLeft = *i; newline.fileDescrRight = FileDescrLine(); newline.fileDescrRight.directory = dirRight; - newline.cmpResult = fileOnLeftSideOnly; + newline.cmpResult = FILE_LEFT_SIDE_ONLY; output_tmp.push_back(newline); } @@ -295,19 +301,19 @@ void FreeFileSync::startCompareProcess(FileCompareResult& output, const wxString if ((i = directoryLeft.find(*j)) == directoryLeft.end()) { newline.fileDescrLeft = FileDescrLine(); - newline.fileDescrLeft.directory = dirLeft; + newline.fileDescrLeft.directory = dirLeft; //directory info is needed when creating new directories newline.fileDescrRight = *j; - newline.cmpResult = fileOnRightSideOnly; + newline.cmpResult = FILE_RIGHT_SIDE_ONLY; output_tmp.push_back(newline); } //find files that exist in left and right file model else - { //objType != isNothing - if (i->objType == isDirectory && j->objType == isDirectory) + { //objType != TYPE_NOTHING + if (i->objType == TYPE_DIRECTORY && j->objType == TYPE_DIRECTORY) { newline.fileDescrLeft = *i; newline.fileDescrRight = *j; - newline.cmpResult = filesEqual; + newline.cmpResult = FILE_EQUAL; output_tmp.push_back(newline); } //if we have a nameclash between a file and a directory: split into separate rows @@ -316,40 +322,44 @@ void FreeFileSync::startCompareProcess(FileCompareResult& output, const wxString newline.fileDescrLeft = *i; newline.fileDescrRight = FileDescrLine(); newline.fileDescrRight.directory = dirRight; - newline.cmpResult = fileOnLeftSideOnly; + newline.cmpResult = FILE_LEFT_SIDE_ONLY; output_tmp.push_back(newline); newline.fileDescrLeft = FileDescrLine(); newline.fileDescrLeft.directory = dirLeft; newline.fileDescrRight = *j; - newline.cmpResult = fileOnRightSideOnly; + newline.cmpResult = FILE_RIGHT_SIDE_ONLY; output_tmp.push_back(newline); } - else if (cmpVar == compareByTimeAndSize) + else if (cmpVar == CMP_BY_TIME_SIZE) { //check files that exist in left and right model but have different properties - if (i->lastWriteTimeRaw != j->lastWriteTimeRaw || - i->fileSize != j->fileSize) - { - newline.fileDescrLeft = *i; - newline.fileDescrRight = *j; - if (i->lastWriteTimeRaw == j->lastWriteTimeRaw) - newline.cmpResult = filesDifferent; - else if (i->lastWriteTimeRaw < j->lastWriteTimeRaw) - newline.cmpResult = rightFileNewer; + //last write time may differ up to 2 seconds (NTFS vs FAT32) + bool sameWriteTime; + if (i->lastWriteTimeRaw < j->lastWriteTimeRaw) + sameWriteTime = (j->lastWriteTimeRaw - i->lastWriteTimeRaw <= 2); + else + sameWriteTime = (i->lastWriteTimeRaw - j->lastWriteTimeRaw <= 2); + + newline.fileDescrLeft = *i; + newline.fileDescrRight = *j; + if (sameWriteTime) + { + if (i->fileSize == j->fileSize) + newline.cmpResult = FILE_EQUAL; else - newline.cmpResult = leftFileNewer; - output_tmp.push_back(newline); + newline.cmpResult = FILE_DIFFERENT; } else { - newline.fileDescrLeft = *i; - newline.fileDescrRight = *j; - newline.cmpResult = filesEqual; - output_tmp.push_back(newline); + if (i->lastWriteTimeRaw < j->lastWriteTimeRaw) + newline.cmpResult = FILE_RIGHT_NEWER; + else + newline.cmpResult = FILE_LEFT_NEWER; } + output_tmp.push_back(newline); } - else if (cmpVar == compareByContent) + else if (cmpVar == CMP_BY_CONTENT) { //check files that exist in left and right model but have different content //check filesize first! @@ -367,7 +377,7 @@ void FreeFileSync::startCompareProcess(FileCompareResult& output, const wxString { newline.fileDescrLeft = *i; newline.fileDescrRight = *j; - newline.cmpResult = filesDifferent; + newline.cmpResult = FILE_DIFFERENT; output_tmp.push_back(newline); } } @@ -380,7 +390,7 @@ void FreeFileSync::startCompareProcess(FileCompareResult& output, const wxString //compare file contents and set value "cmpResult" //unsigned int startTime3 = GetTickCount(); - if (cmpVar == compareByContent) + if (cmpVar == CMP_BY_CONTENT) { int objectsTotal = 0; double dataTotal = 0; @@ -394,7 +404,7 @@ void FreeFileSync::startCompareProcess(FileCompareResult& output, const wxString { FileCompareLine& gridline = output_tmp[*i]; - statusUpdater->updateStatusText(wxString(_("Comparing content of files ")) + "\"" + gridline.fileDescrLeft.relFilename + "\""); + statusUpdater->updateStatusText(wxString(_("Comparing content of files ")) + wxT("\"") + gridline.fileDescrLeft.relFilename + wxT("\"")); //check files that exist in left and right model but have different content while (true) @@ -405,9 +415,9 @@ void FreeFileSync::startCompareProcess(FileCompareResult& output, const wxString try { if (filesHaveSameContentMultithreaded(gridline.fileDescrLeft.filename, gridline.fileDescrRight.filename, statusUpdater)) - gridline.cmpResult = filesEqual; + gridline.cmpResult = FILE_EQUAL; else - gridline.cmpResult = filesDifferent; + gridline.cmpResult = FILE_DIFFERENT; statusUpdater->updateProcessedData(2, (gridline.fileDescrLeft.fileSize + gridline.fileDescrRight.fileSize).ToDouble()); break; @@ -416,7 +426,7 @@ void FreeFileSync::startCompareProcess(FileCompareResult& output, const wxString { //if (updateClass) -> is mandatory int rv = statusUpdater->reportError(error.show()); - if ( rv == StatusUpdater::continueNext) + if (rv == StatusUpdater::continueNext) { rowsToDelete.insert(*i); break; @@ -437,9 +447,9 @@ void FreeFileSync::startCompareProcess(FileCompareResult& output, const wxString statusUpdater->triggerUI_Refresh(); } - catch (std::runtime_error& theException) + catch (const RuntimeException& theException) { - wxMessageBox(_(theException.what()), _("An exception occured!"), wxOK | wxICON_ERROR); + wxMessageBox(theException.show(), _("An exception occured!"), wxOK | wxICON_ERROR); return; } @@ -455,14 +465,14 @@ void FreeFileSync::swapGrids(FileCompareResult& grid) for (FileCompareResult::iterator i = grid.begin(); i != grid.end(); ++i) { //swap compare result - if (i->cmpResult == fileOnLeftSideOnly) - i->cmpResult = fileOnRightSideOnly; - else if (i->cmpResult == fileOnRightSideOnly) - i->cmpResult = fileOnLeftSideOnly; - else if (i->cmpResult == rightFileNewer) - i->cmpResult = leftFileNewer; - else if (i->cmpResult == leftFileNewer) - i->cmpResult = rightFileNewer; + if (i->cmpResult == FILE_LEFT_SIDE_ONLY) + i->cmpResult = FILE_RIGHT_SIDE_ONLY; + else if (i->cmpResult == FILE_RIGHT_SIDE_ONLY) + i->cmpResult = FILE_LEFT_SIDE_ONLY; + else if (i->cmpResult == FILE_RIGHT_NEWER) + i->cmpResult = FILE_LEFT_NEWER; + else if (i->cmpResult == FILE_LEFT_NEWER) + i->cmpResult = FILE_RIGHT_NEWER; //swap file descriptors tmp = i->fileDescrLeft; @@ -508,11 +518,11 @@ wxDirTraverseResult GetAllFilesFull::OnFile(const wxString& filename) fileDescr.lastWriteTime = currentFileInfo.lastWriteTime; fileDescr.lastWriteTimeRaw = currentFileInfo.lastWriteTimeRaw; fileDescr.fileSize = currentFileInfo.fileSize; - fileDescr.objType = isFile; + fileDescr.objType = TYPE_FILE; m_output.insert(fileDescr); //update UI/commandline status information - statusUpdater->updateStatusText(wxString(_("Scanning ")) + "\"" + filename + "\""); // NO performance issue at all + statusUpdater->updateStatusText(wxString(_("Scanning ")) + wxT("\"") + filename + wxT("\"")); // NO performance issue at all //add 1 element to the progress indicator statusUpdater->updateProcessedData(1, 0); // NO performance issue at all //trigger display refresh @@ -524,8 +534,8 @@ wxDirTraverseResult GetAllFilesFull::OnFile(const wxString& filename) wxDirTraverseResult GetAllFilesFull::OnDir(const wxString& dirname) { - if (dirname.EndsWith("\\RECYCLER") || - dirname.EndsWith("\\System Volume Information")) + if (dirname.EndsWith(wxT("\\RECYCLER")) || + dirname.EndsWith(wxT("\\System Volume Information"))) return wxDIR_IGNORE; fileDescr.filename = dirname; @@ -553,11 +563,11 @@ wxDirTraverseResult GetAllFilesFull::OnDir(const wxString& dirname) fileDescr.lastWriteTime = currentFileInfo.lastWriteTime; fileDescr.lastWriteTimeRaw = currentFileInfo.lastWriteTimeRaw; fileDescr.fileSize = wxULongLong(0); //currentFileInfo.fileSize should be "0" as well, but just to be sure... currently used by getBytesToTransfer - fileDescr.objType = isDirectory; + fileDescr.objType = TYPE_DIRECTORY; m_output.insert(fileDescr); //update UI/commandline status information - statusUpdater->updateStatusText(wxString(_("Scanning ")) + "\"" + dirname + "\""); // NO performance issue at all + statusUpdater->updateStatusText(wxString(_("Scanning ")) + wxT("\"") + dirname + wxT("\"")); // NO performance issue at all //add 1 element to the progress indicator statusUpdater->updateProcessedData(1, 0); // NO performance issue at all //trigger display refresh @@ -622,7 +632,7 @@ public: { #ifdef FFS_WIN // Get a handle to the DLL module containing Recycle Bin functionality - hinstShell = LoadLibrary("shell32.dll"); + hinstShell = LoadLibrary(wxT("shell32.dll")); if (hinstShell != NULL) { fileOperation = (DllFileOP)GetProcAddress(hinstShell, "SHFileOperation"); @@ -653,12 +663,12 @@ public: void moveToRecycleBin(const wxString& filename) { if (!recycleBinAvailable) //this method should ONLY be called if recycle bin is available - throw std::runtime_error("Initialization of Recycle Bin failed! It cannot be used!"); + throw RuntimeException(_("Initialization of Recycle Bin failed! It cannot be used!")); #ifdef FFS_WIN SHFILEOPSTRUCT fileOp; - wxString filenameDoubleNull = filename + char(0); + wxString filenameDoubleNull = filename + wxChar(0); fileOp.hwnd = NULL; fileOp.wFunc = FO_DELETE; @@ -670,7 +680,7 @@ public: fileOp.lpszProgressTitle = NULL; if (fileOperation(&fileOp //pointer to an SHFILEOPSTRUCT structure that contains information the function needs to carry out - ) != 0 || fileOp.fAnyOperationsAborted) throw FileError(wxString(_("Error moving file ")) + "\"" + filename + "\"" + _(" to recycle bin!")); + ) != 0 || fileOp.fAnyOperationsAborted) throw FileError(wxString(_("Error moving file ")) + wxT("\"") + filename + wxT("\"") + _(" to recycle bin!")); #endif // FFS_WIN } @@ -702,11 +712,11 @@ void FreeFileSync::removeFile(const wxString& filename) if (!SetFileAttributes( filename.c_str(), // address of filename FILE_ATTRIBUTE_NORMAL // attributes to set - )) throw FileError(wxString(_("Error deleting file ")) + "\"" + filename + "\""); + )) throw FileError(wxString(_("Error deleting file ")) + wxT("\"") + filename + wxT("\"")); #endif // FFS_WIN if (!wxRemoveFile(filename)) - throw FileError(wxString(_("Error deleting file ")) + "\"" + filename + "\""); + throw FileError(wxString(_("Error deleting file ")) + wxT("\"") + filename + wxT("\"")); } @@ -728,7 +738,8 @@ void FreeFileSync::removeDirectory(const wxString& directory) //get all files and directories from current directory (and subdirectories) GetAllFilesSimple traverser(fileList, dirList); - dir.Traverse(traverser); + if (dir.Traverse(traverser) == (size_t)-1) + throw FileError(wxString(_("Error deleting directory ")) + wxT("\"") + directory + wxT("\"")); } for (unsigned int j = 0; j < fileList.GetCount(); ++j) @@ -742,11 +753,11 @@ void FreeFileSync::removeDirectory(const wxString& directory) if (!SetFileAttributes( dirList[j].c_str(), // address of directory name FILE_ATTRIBUTE_NORMAL // attributes to set - )) throw FileError(wxString(_("Error deleting directory ")) + "\"" + dirList[j] + "\""); + )) throw FileError(wxString(_("Error deleting directory ")) + wxT("\"") + dirList[j] + wxT("\"")); #endif // FFS_WIN if (!wxRmdir(dirList[j])) - throw FileError(wxString(_("Error deleting directory ")) + "\"" + dirList[j] + "\""); + throw FileError(wxString(_("Error deleting directory ")) + wxT("\"") + dirList[j] + wxT("\"")); } } @@ -774,7 +785,7 @@ void FreeFileSync::createDirectory(const wxString& directory, int level) if (!wxMkdir(directory)) { if (level == 0) - throw FileError(wxString(_("Error creating directory ")) + "\"" + directory + "\""); + throw FileError(wxString(_("Error creating directory ")) + wxT("\"") + directory + wxT("\"")); } } @@ -814,7 +825,7 @@ private: if (!wxCopyFile(source, target, false)) //abort if file exists { success = false; - errorMessage = wxString(_("Error copying file ")) + "\"" + source + "\"" + _(" to ") + "\"" + target + "\""; + errorMessage = wxString(_("Error copying file ")) + wxT("\"") + source + wxT("\"") + _(" to ") + wxT("\"") + target + wxT("\""); return; } @@ -823,7 +834,7 @@ private: if (stat(source.c_str(), &fileInfo) != 0) //read modification time from source file { success = false; - errorMessage = wxString(_("Could not retrieve file info for: ")) + "\"" + source + "\""; + errorMessage = wxString(_("Could not retrieve file info for: ")) + wxT("\"") + source + wxT("\""); return; } @@ -834,7 +845,7 @@ private: if (utime(target.c_str(), &newTimes) != 0) { success = false; - errorMessage = wxString(_("Error adapting modification time of file ")) + "\"" + target + "\""; + errorMessage = wxString(_("Error adapting modification time of file ")) + wxT("\"") + target + wxT("\""); return; } #endif // FFS_LINUX @@ -889,30 +900,30 @@ SyncDirection getSyncDirection(const CompareFilesResult cmpResult, const SyncCon { switch (cmpResult) { - case fileOnLeftSideOnly: + case FILE_LEFT_SIDE_ONLY: return config.exLeftSideOnly; break; - case fileOnRightSideOnly: + case FILE_RIGHT_SIDE_ONLY: return config.exRightSideOnly; break; - case rightFileNewer: + case FILE_RIGHT_NEWER: return config.rightNewer; break; - case leftFileNewer: + case FILE_LEFT_NEWER: return config.leftNewer; break; - case filesDifferent: + case FILE_DIFFERENT: return config.different; break; default: assert (false); } - return syncDirNone; + return SYNC_DIR_NONE; } @@ -936,59 +947,59 @@ bool getBytesToTransfer(int& objectsToCreate, switch (fileCmpLine.cmpResult) { - case fileOnLeftSideOnly: + case FILE_LEFT_SIDE_ONLY: //get data to process switch (getSyncDirection(fileCmpLine.cmpResult, config)) { - case syncDirLeft: //delete file on left + case SYNC_DIR_LEFT: //delete file on left dataToProcess = 0; objectsToDelete = 1; break; - case syncDirRight: //copy from left to right + case SYNC_DIR_RIGHT: //copy from left to right dataToProcess = fileCmpLine.fileDescrLeft.fileSize.ToDouble(); objectsToCreate = 1; break; - case syncDirNone: + case SYNC_DIR_NONE: return false; } break; - case fileOnRightSideOnly: + case FILE_RIGHT_SIDE_ONLY: switch (getSyncDirection(fileCmpLine.cmpResult, config)) { - case syncDirLeft: //copy from right to left + case SYNC_DIR_LEFT: //copy from right to left dataToProcess = fileCmpLine.fileDescrRight.fileSize.ToDouble();; objectsToCreate = 1; break; - case syncDirRight: //delete file on right + case SYNC_DIR_RIGHT: //delete file on right dataToProcess = 0; objectsToDelete = 1; break; - case syncDirNone: + case SYNC_DIR_NONE: return false; } break; - case leftFileNewer: - case rightFileNewer: - case filesDifferent: + case FILE_LEFT_NEWER: + case FILE_RIGHT_NEWER: + case FILE_DIFFERENT: //get data to process switch (getSyncDirection(fileCmpLine.cmpResult, config)) { - case syncDirLeft: //copy from right to left + case SYNC_DIR_LEFT: //copy from right to left dataToProcess = fileCmpLine.fileDescrRight.fileSize.ToDouble(); objectsToOverwrite = 1; break; - case syncDirRight: //copy from left to right + case SYNC_DIR_RIGHT: //copy from left to right dataToProcess = fileCmpLine.fileDescrLeft.fileSize.ToDouble(); objectsToOverwrite = 1; break; - case syncDirNone: + case SYNC_DIR_NONE: return false; } break; - case filesEqual: + case FILE_EQUAL: return false; }; @@ -1037,75 +1048,75 @@ bool FreeFileSync::synchronizeFile(const FileCompareLine& filename, const SyncCo //synchronize file: switch (filename.cmpResult) { - case fileOnLeftSideOnly: + case FILE_LEFT_SIDE_ONLY: switch (config.exLeftSideOnly) { - case syncDirLeft: //delete files on left - statusUpdater->updateStatusText(wxString(_("Deleting file ")) + "\"" + filename.fileDescrLeft.filename + "\""); + case SYNC_DIR_LEFT: //delete files on left + statusUpdater->updateStatusText(wxString(_("Deleting file ")) + wxT("\"") + filename.fileDescrLeft.filename + wxT("\"")); removeFile(filename.fileDescrLeft.filename); break; - case syncDirRight: //copy files to right + case SYNC_DIR_RIGHT: //copy files to right target = filename.fileDescrRight.directory + filename.fileDescrLeft.relFilename; - statusUpdater->updateStatusText(wxString(_("Copying file ")) + "\"" + filename.fileDescrLeft.filename + "\"" + - _(" to ") + "\"" + target + "\""); + statusUpdater->updateStatusText(wxString(_("Copying file ")) + wxT("\"") + filename.fileDescrLeft.filename + wxT("\"") + + _(" to ") + wxT("\"") + target + wxT("\"")); copyfileMultithreaded(filename.fileDescrLeft.filename, target, statusUpdater); break; - case syncDirNone: + case SYNC_DIR_NONE: return false; default: assert (false); } break; - case fileOnRightSideOnly: + case FILE_RIGHT_SIDE_ONLY: switch (config.exRightSideOnly) { - case syncDirLeft: //copy files to left + case SYNC_DIR_LEFT: //copy files to left target = filename.fileDescrLeft.directory + filename.fileDescrRight.relFilename; - statusUpdater->updateStatusText(wxString(_("Copying file ")) + "\"" + filename.fileDescrRight.filename + "\"" + - _(" to ") + "\"" + target + "\""); + statusUpdater->updateStatusText(wxString(_("Copying file ")) + wxT("\"") + filename.fileDescrRight.filename + wxT("\"") + + _(" to ") + wxT("\"") + target + wxT("\"")); copyfileMultithreaded(filename.fileDescrRight.filename, target, statusUpdater); break; - case syncDirRight: //delete files on right - statusUpdater->updateStatusText(wxString(_("Deleting file ")) + "\"" + filename.fileDescrRight.filename + "\""); + case SYNC_DIR_RIGHT: //delete files on right + statusUpdater->updateStatusText(wxString(_("Deleting file ")) + wxT("\"") + filename.fileDescrRight.filename + wxT("\"")); removeFile(filename.fileDescrRight.filename); break; - case syncDirNone: + case SYNC_DIR_NONE: return false; default: assert (false); } break; - case leftFileNewer: - case rightFileNewer: - case filesDifferent: + case FILE_LEFT_NEWER: + case FILE_RIGHT_NEWER: + case FILE_DIFFERENT: switch (getSyncDirection(filename.cmpResult, config)) { - case syncDirLeft: //copy from right to left - statusUpdater->updateStatusText(wxString(_("Copying file ")) + "\"" + filename.fileDescrRight.filename + "\"" + - _(" overwriting ") + "\"" + filename.fileDescrLeft.filename + "\""); + case SYNC_DIR_LEFT: //copy from right to left + statusUpdater->updateStatusText(wxString(_("Copying file ")) + wxT("\"") + filename.fileDescrRight.filename + wxT("\"") + + _(" overwriting ") + wxT("\"") + filename.fileDescrLeft.filename + wxT("\"")); removeFile(filename.fileDescrLeft.filename); //only used if switch activated by user, else file is simply deleted copyfileMultithreaded(filename.fileDescrRight.filename, filename.fileDescrLeft.filename, statusUpdater); break; - case syncDirRight: //copy from left to right - statusUpdater->updateStatusText(wxString(_("Copying file ")) + "\"" + filename.fileDescrLeft.filename + "\"" + - _(" overwriting ") + "\"" + filename.fileDescrRight.filename + "\""); + case SYNC_DIR_RIGHT: //copy from left to right + statusUpdater->updateStatusText(wxString(_("Copying file ")) + wxT("\"") + filename.fileDescrLeft.filename + wxT("\"") + + _(" overwriting ") + wxT("\"") + filename.fileDescrRight.filename + wxT("\"")); removeFile(filename.fileDescrRight.filename); //only used if switch activated by user, else file is simply deleted copyfileMultithreaded(filename.fileDescrLeft.filename, filename.fileDescrRight.filename, statusUpdater); break; - case syncDirNone: + case SYNC_DIR_NONE: return false; default: assert (false); } break; - case filesEqual: + case FILE_EQUAL: return false; default: @@ -1126,57 +1137,57 @@ bool FreeFileSync::synchronizeFolder(const FileCompareLine& filename, const Sync //synchronize folders: switch (filename.cmpResult) { - case fileOnLeftSideOnly: + case FILE_LEFT_SIDE_ONLY: switch (config.exLeftSideOnly) { - case syncDirLeft: //delete folders on left - statusUpdater->updateStatusText(wxString(_("Deleting folder ")) + "\"" + filename.fileDescrLeft.filename + "\""); + case SYNC_DIR_LEFT: //delete folders on left + statusUpdater->updateStatusText(wxString(_("Deleting folder ")) + wxT("\"") + filename.fileDescrLeft.filename + wxT("\"")); removeDirectory(filename.fileDescrLeft.filename); break; - case syncDirRight: //create folders on right + case SYNC_DIR_RIGHT: //create folders on right target = filename.fileDescrRight.directory + filename.fileDescrLeft.relFilename; - statusUpdater->updateStatusText(wxString(_("Creating folder ")) + "\"" + target + "\""); + statusUpdater->updateStatusText(wxString(_("Creating folder ")) + wxT("\"") + target + wxT("\"")); //some check to catch the error that directory on source has been deleted externally after the "compare"... if (!wxDirExists(filename.fileDescrLeft.filename)) - throw FileError(wxString(_("Error: Source directory does not exist anymore: ")) + "\"" + filename.fileDescrLeft.filename + "\""); + throw FileError(wxString(_("Error: Source directory does not exist anymore: ")) + wxT("\"") + filename.fileDescrLeft.filename + wxT("\"")); createDirectory(target); break; - case syncDirNone: + case SYNC_DIR_NONE: return false; default: assert (false); } break; - case fileOnRightSideOnly: + case FILE_RIGHT_SIDE_ONLY: switch (config.exRightSideOnly) { - case syncDirLeft: //create folders on left + case SYNC_DIR_LEFT: //create folders on left target = filename.fileDescrLeft.directory + filename.fileDescrRight.relFilename; - statusUpdater->updateStatusText(wxString(_("Creating folder ")) + "\"" + target + "\""); + statusUpdater->updateStatusText(wxString(_("Creating folder ")) + wxT("\"") + target + wxT("\"")); //some check to catch the error that directory on source has been deleted externally after the "compare"... if (!wxDirExists(filename.fileDescrRight.filename)) - throw FileError(wxString(_("Error: Source directory does not exist anymore: ")) + "\"" + filename.fileDescrRight.filename + "\""); + throw FileError(wxString(_("Error: Source directory does not exist anymore: ")) + wxT("\"") + filename.fileDescrRight.filename + wxT("\"")); createDirectory(target); break; - case syncDirRight: //delete folders on right - statusUpdater->updateStatusText(wxString(_("Deleting folder ")) + "\"" + filename.fileDescrRight.filename + "\""); + case SYNC_DIR_RIGHT: //delete folders on right + statusUpdater->updateStatusText(wxString(_("Deleting folder ")) + wxT("\"") + filename.fileDescrRight.filename + wxT("\"")); removeDirectory(filename.fileDescrRight.filename); break; - case syncDirNone: + case SYNC_DIR_NONE: return false; default: assert (false); } break; - case filesEqual: + case FILE_EQUAL: return false; - case rightFileNewer: - case leftFileNewer: - case filesDifferent: + case FILE_RIGHT_NEWER: + case FILE_LEFT_NEWER: + case FILE_DIFFERENT: default: assert (false); } @@ -1194,27 +1205,27 @@ wxString FreeFileSync::formatFilesizeToShortString(const double filesize) { double nrOfBytes = filesize; - wxString unit = " Byte"; + wxString unit = wxT(" Byte"); if (nrOfBytes > 999) { nrOfBytes/= 1024; - unit = " kB"; + unit = wxT(" kB"); if (nrOfBytes > 999) { nrOfBytes/= 1024; - unit = " MB"; + unit = wxT(" MB"); if (nrOfBytes > 999) { nrOfBytes/= 1024; - unit = " GB"; + unit = wxT(" GB"); if (nrOfBytes > 999) { nrOfBytes/= 1024; - unit = " TB"; + unit = wxT(" TB"); if (nrOfBytes > 999) { nrOfBytes/= 1024; - unit = " PB"; + unit = wxT(" PB"); } } } @@ -1222,13 +1233,11 @@ wxString FreeFileSync::formatFilesizeToShortString(const double filesize) } wxString temp; - if (unit == " Byte") //no decimal places in case of bytes + if (unit == wxT(" Byte")) //no decimal places in case of bytes { double integer = 0; modf(nrOfBytes, &integer); //get integer part of nrOfBytes temp = numberToWxString(int(integer)); - // if (!temp.Len()) //if nrOfBytes is zero GMP returns an empty string - // temp = "0"; } else { @@ -1243,13 +1252,13 @@ wxString FreeFileSync::formatFilesizeToShortString(const double filesize) switch (length) { case 0: - temp = "Error"; + temp = wxT("Error"); break; case 1: - temp = wxString("0") + GlobalResources::decimalPoint + "0" + temp; + temp = wxString(wxT("0")) + GlobalResources::decimalPoint + wxT("0") + temp; break; //0,01 case 2: - temp = wxString("0") + GlobalResources::decimalPoint + temp; + temp = wxString(wxT("0")) + GlobalResources::decimalPoint + temp; break; //0,11 case 3: temp.insert(1, GlobalResources::decimalPoint); @@ -1262,7 +1271,7 @@ wxString FreeFileSync::formatFilesizeToShortString(const double filesize) temp = temp.substr(0, 3); break; //111 default: - return "Error"; + return wxT("Error"); } } return (temp + unit); @@ -1275,9 +1284,9 @@ void FreeFileSync::filterCurrentGridData(FileCompareResult& currentGridData, con wxString excludeFilterTmp(excludeFilter); //make sure filters end with ";" - no problem with empty strings here - if (!includeFilterTmp.EndsWith(";")) + if (!includeFilterTmp.EndsWith(wxT(";"))) includeFilterTmp.Append(';'); - if (!excludeFilterTmp.EndsWith(";")) + if (!excludeFilterTmp.EndsWith(wxT(";"))) excludeFilterTmp.Append(';'); //load filters into vectors @@ -1308,7 +1317,7 @@ void FreeFileSync::filterCurrentGridData(FileCompareResult& currentGridData, con for (FileCompareResult::iterator i = currentGridData.begin(); i != currentGridData.end(); ++i) { //process include filters - if (i->fileDescrLeft.objType != isNothing) + if (i->fileDescrLeft.objType != TYPE_NOTHING) { bool includedLeft = false; for (vector<wxString>::const_iterator j = includeList.begin(); j != includeList.end(); ++j) @@ -1325,7 +1334,7 @@ void FreeFileSync::filterCurrentGridData(FileCompareResult& currentGridData, con } } - if (i->fileDescrRight.objType != isNothing) + if (i->fileDescrRight.objType != TYPE_NOTHING) { bool includedRight = false; for (vector<wxString>::const_iterator j = includeList.begin(); j != includeList.end(); ++j) @@ -1385,8 +1394,8 @@ wxString FreeFileSync::getFormattedDirectoryName(const wxString& dirname) inline bool deletionImminent(const FileCompareLine& line, const SyncConfiguration& config) { //test if current sync-line will result in deletion of files -> used to avoid disc space bottlenecks - if ((line.cmpResult == fileOnLeftSideOnly && config.exLeftSideOnly == syncDirLeft) || - (line.cmpResult == fileOnRightSideOnly && config.exRightSideOnly == syncDirRight)) + if ((line.cmpResult == FILE_LEFT_SIDE_ONLY && config.exLeftSideOnly == SYNC_DIR_LEFT) || + (line.cmpResult == FILE_RIGHT_SIDE_ONLY && config.exRightSideOnly == SYNC_DIR_RIGHT)) return true; else return false; @@ -1448,7 +1457,7 @@ void FreeFileSync::startSynchronizationProcess(FileCompareResult& grid, const Sy //synchronize folders: for (FileCompareResult::const_iterator i = grid.begin(); i != grid.end(); ++i) { - if (i->fileDescrLeft.objType == isDirectory || i->fileDescrRight.objType == isDirectory) + if (i->fileDescrLeft.objType == TYPE_DIRECTORY || i->fileDescrRight.objType == TYPE_DIRECTORY) { while (true) { //trigger display refresh @@ -1481,13 +1490,14 @@ void FreeFileSync::startSynchronizationProcess(FileCompareResult& grid, const Sy } //synchronize files: + bool deleteLoop = true; for (int k = 0; k < 2; ++k) //loop over all files twice; reason: first delete, then copy (no sorting necessary: performance) { - bool deleteLoop = !k; //-> first loop: delete files, second loop: copy files + deleteLoop = !k; //-> first loop: delete files, second loop: copy files for (FileCompareResult::const_iterator i = grid.begin(); i != grid.end(); ++i) { - if (i->fileDescrLeft.objType == isFile || i->fileDescrRight.objType == isFile) + if (i->fileDescrLeft.objType == TYPE_FILE || i->fileDescrRight.objType == TYPE_FILE) { if (deleteLoop && deletionImminent(*i, config) || !deleteLoop && !deletionImminent(*i, config)) @@ -1537,9 +1547,9 @@ void FreeFileSync::startSynchronizationProcess(FileCompareResult& grid, const Sy } } } - catch (std::runtime_error& theException) + catch (const RuntimeException& theException) { - wxMessageBox(_(theException.what()), _("An exception occured!"), wxOK | wxICON_ERROR); + wxMessageBox(theException.show(), _("An exception occured!"), wxOK | wxICON_ERROR); return; } } @@ -1547,16 +1557,22 @@ void FreeFileSync::startSynchronizationProcess(FileCompareResult& grid, const Sy bool FreeFileSync::isFFS_ConfigFile(const wxString& filename) { - ifstream config(filename.c_str()); - if (!config) + wxFFile configFile(filename.c_str(), wxT("rb")); + if (!configFile.IsOpened()) return false; char bigBuffer[10000]; //read FFS identifier - config.get(bigBuffer, FreeFileSync::FFS_ConfigFileID.Len() + 1); + size_t bytesRead = configFile.Read(bigBuffer, FreeFileSync::FfsConfigFileID.size()); - return (FFS_ConfigFileID == wxString(bigBuffer)); + if (!configFile.Error() && bytesRead < 10000) + { + bigBuffer[bytesRead] = 0; + return (FfsConfigFileID == string(bigBuffer)); + } + else + return false; } @@ -1565,10 +1581,10 @@ void FreeFileSync::addSubElements(set<int>& subElements, const FileCompareResult { wxString relevantDirectory; - if (relevantRow.fileDescrLeft.objType == isDirectory) + if (relevantRow.fileDescrLeft.objType == TYPE_DIRECTORY) relevantDirectory = relevantRow.fileDescrLeft.relFilename; - else if (relevantRow.fileDescrRight.objType == isDirectory) + else if (relevantRow.fileDescrRight.objType == TYPE_DIRECTORY) relevantDirectory = relevantRow.fileDescrRight.relFilename; else @@ -1596,14 +1612,14 @@ void FreeFileSync::deleteOnGridAndHD(FileCompareResult& grid, const set<int>& ro { try { - if (currentCmpLine.fileDescrLeft.objType == isFile) + if (currentCmpLine.fileDescrLeft.objType == TYPE_FILE) fileSyncObject.removeFile(currentCmpLine.fileDescrLeft.filename); - else if (currentCmpLine.fileDescrLeft.objType == isDirectory) + else if (currentCmpLine.fileDescrLeft.objType == TYPE_DIRECTORY) fileSyncObject.removeDirectory(currentCmpLine.fileDescrLeft.filename); - if (currentCmpLine.fileDescrRight.objType == isFile) + if (currentCmpLine.fileDescrRight.objType == TYPE_FILE) fileSyncObject.removeFile(currentCmpLine.fileDescrRight.filename); - else if (currentCmpLine.fileDescrRight.objType == isDirectory) + else if (currentCmpLine.fileDescrRight.objType == TYPE_DIRECTORY) fileSyncObject.removeDirectory(currentCmpLine.fileDescrRight.filename); rowsToDeleteInGrid.insert(*i); @@ -1618,7 +1634,7 @@ void FreeFileSync::deleteOnGridAndHD(FileCompareResult& grid, const set<int>& ro break; else if (rv == StatusUpdater::retry) - ; //continue with loop + ; //continue in loop else assert (false); } @@ -1654,7 +1670,7 @@ bool updateUI_IsAllowed() wxLongLong newExec = wxGetLocalTimeMillis(); - if (newExec - lastExec >= uiUpdateInterval) //perform ui updates not more often than necessary + if (newExec - lastExec >= UI_UPDATE_INTERVAL) //perform ui updates not more often than necessary { lastExec = newExec; return true; diff --git a/FreeFileSync.h b/FreeFileSync.h index f2311bc1..cf17a5d7 100644 --- a/FreeFileSync.h +++ b/FreeFileSync.h @@ -13,15 +13,15 @@ using namespace std; enum SyncDirection { - syncDirLeft, - syncDirRight, - syncDirNone + SYNC_DIR_LEFT, + SYNC_DIR_RIGHT, + SYNC_DIR_NONE }; enum CompareVariant { - compareByContent, - compareByTimeAndSize + CMP_BY_CONTENT, + CMP_BY_TIME_SIZE }; struct SyncConfiguration @@ -47,27 +47,27 @@ struct Configuration bool filterIsActive; //other options - bool useRecycleBin; //use Recycle bin when deleting or overwriting files while synchronizing + bool useRecycleBin; //use Recycle bin when deleting or overwriting files while synchronizing bool continueOnError; //hides error messages during synchronization }; struct FileInfo { - wxULongLong fileSize; + wxULongLong fileSize; //unit: bytes! wxString lastWriteTime; - wxULongLong lastWriteTimeRaw; + wxULongLong lastWriteTimeRaw; //unit: seconds! }; enum ObjectType { - isNothing, - isDirectory, - isFile + TYPE_NOTHING, + TYPE_DIRECTORY, + TYPE_FILE }; struct FileDescrLine { - FileDescrLine() : objType(isNothing) {} + FileDescrLine() : objType(TYPE_NOTHING) {} wxString filename; // == directory + relFilename wxString directory; //directory to be synced @@ -117,12 +117,12 @@ typedef set<FileDescrLine> DirectoryDescrType; enum CompareFilesResult { - fileOnLeftSideOnly, - fileOnRightSideOnly, - rightFileNewer, - leftFileNewer, - filesDifferent, - filesEqual + FILE_LEFT_SIDE_ONLY, + FILE_RIGHT_SIDE_ONLY, + FILE_RIGHT_NEWER, + FILE_LEFT_NEWER, + FILE_DIFFERENT, + FILE_EQUAL }; @@ -237,8 +237,8 @@ public: static bool isFFS_ConfigFile(const wxString& filename); - static const wxString FFS_ConfigFileID; - static const wxString FFS_LastConfigFile; + static const string FfsConfigFileID; + static const wxString FfsLastConfigFile; static void getFileInformation(FileInfo& output, const wxString& filename); @@ -266,7 +266,7 @@ class FileError //Exception class used to notify file/directory copy/delete erro public: FileError(const wxString& txt) : errorMessage(txt) {} - wxString show() + wxString show() const { return errorMessage; } @@ -1,4 +1,4 @@ -FreeFileSync v1.6 +FreeFileSync v1.7 ----------------- Usage @@ -30,14 +30,13 @@ Features 8. Easy configurable commandline mode for automated synchronization. 9. Support for filesizes > 4 GB. 10. Option to move files to Recycle Bin instead of deleting/overwriting them. -11. UTC (coordinated world time) is used when comparing file times avoiding problems with time zones or daylight saving time. -12. Automatically ignore directories "\RECYCLER" and "System Volume Information" when comparing and syncing. -13. Localized German version available. -14. Delete before copy: Avoid disc space shortages with large sync-operations. -15. Based on wxWidgets framework => Portable to many operating systems. -16. Filter functionality to include/exclude files from synchronization (without re-compare!). -17. Include/exclude specific files from synchronization manually. -18. Create sync jobs via GUI to synchronize automatically (can be scheduled or executed directly). +11. Automatically ignore directories "\RECYCLER" and "System Volume Information" when comparing and syncing. +12. Localized German version available. +13. Delete before copy: Avoid disc space shortages with large sync-operations. +14. Based on wxWidgets framework => Portable to many operating systems. +15. Filter functionality to include/exclude files from synchronization (without re-compare!). +16. Include/exclude specific files from synchronization manually. +17. Create sync jobs via GUI to synchronize automatically (can be scheduled or executed directly). Links diff --git a/Resources.dat b/Resources.dat Binary files differindex 08234bf7..73acee33 100644 --- a/Resources.dat +++ b/Resources.dat @@ -1,5 +1,7 @@ Time: Uhrzeit: + You may try to synchronize remaining items again (WITHOUT having to re-compare)! + Verbliebene Elemente können nochmals synchronisiert werden (OHNE dass ein erneuter Vergleich notwendig ist)! already exists. Overwrite? existiert bereits. Überschreiben? does not exist. @@ -14,16 +16,10 @@ Element(e):\n\n items on left, Elemente links, -Synchronization started. -Synchronisation gestartet. items on right, Elemente rechts, of von -Start -Start -Stop -Stop overwriting und überschreibe row in view @@ -166,8 +162,8 @@ Command file Command Datei Compare both sides Beide Seiten vergleichen -Compare by \"File size and date\"\n----------------------------------------\nThis compare variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. For the latter the system's UTC time (coordinated word time) is used internally, although the local file time is displayed on the result list. So there are no problems concerning different time zones or daylight saving time.\n\nWhen \"Compare\" is triggered with this option set the following decision tree is processed:\n\n -----------------\n |Decision tree|\n -----------------\n ________|___________\n | |\n file exists on both sides on one side only\n _____|______ __|___\n | | | |\nequal different left right\n _________|_____________\n | | |\n left newer right newer different (but same date)\n\nAs a result 6 different status can be returned to categorize all files:\n\n- exists left only\n- exists right only\n- left newer\n- right newer\n- different (but same date)\n- equal\n\n\nCompare by \"File content\"\n----------------------------------------\nAs the name suggests, two files which share the same name are marked as equal if and only if they have the same content. This option is useful for consistency checks rather than backup operations. Therefore the file times are not taken into account at all.\n\nWith this option enabled the decision tree is smaller:\n\n -----------------\n |Decision tree|\n -----------------\n ________|___________\n | |\n file exists on both sides on one side only\n _____|______ __|___\n | | | |\nequal different left right\n\nAs a result the files are separated into the following categories:\n\n- exists left only\n- exists right only\n- different\n- equal -Vergleichen nach \"Dateigröße und -datum\"\n---------------------------------------------------\nDiese Variante identifiziert zwei gleichnamige Dateien als gleich, wenn sie die gleiche Dateigröße haben UND der Zeitpunkt der letzten Änderung derselbe ist. Für Letzteres wird intern die UTC-Zeit (koordinierte Weltzeit) verwendet, auch wenn die lokale Zeit in der Ergebnisliste angezeigt wird. Dadurch werden Probleme vermieden, die durch verschiedene Zeitzonen oder Sommer-/Winterzeit entstehen.\n\nNachdem \"Compare\" mit dieser Einstellung gestartet wurde, wird der folgende Entscheidungsbaum abgearbeitet:\n\n -------------------------\n |Entscheidungsbaum|\n -------------------------\n __________|___________\n | |\n Datei ex. auf beiden Seiten nur auf einer Seite\n ________|____ __|___\n | | | |\n gleich verschieden links rechts\n __________|___________\n | | |\n links neuer rechts neuer verschieden (bei gleichem Datum)\n\nAls Ergebnis werden 6 verschiedene Status zurückgegeben, um Dateien zu kategorisieren:\n\n- existiert nur links\n- existiert nur rechts\n- links neuer\n- rechts neuer\n- verschieden (bei gleichem Datum)\n- gleich\n\n\nVergleichen nach \"Dateiinhalt\"\n------------------------------------\nWie der Name bereits sagt, werden zwei Dateien mit gleichem Namen genau dann als gleich angesehen, wenn sie den gleichen Dateiinhalt haben. Diese Einstellung ist eher für Konsistenzprüfungen geeignet als für Backup-Operationen. Aus diesem Grund wird der Zeitpunkt der letzten Änderung der Dateien nicht berücksichtigt.\n\nDer Entscheidungsbaum ist in diesem Fall kleiner:\n\n -------------------------\n |Entscheidungsbaum|\n -------------------------\n __________|___________\n | |\n Datei ex. auf beiden Seiten nur auf einer Seite\n ________|____ __|___\n | | | |\n gleich verschieden links rechts\n\nDas Ergebnis ist eine Aufteilung in folgende Kategorien:\n\n- existiert nur links\n- existiert nur rechts\n- verschieden\n- gleich +Compare by \"File size and date\"\n----------------------------------------\nThis variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. (Notice that the file time may deviate up to 2 seconds.)\n\nWhen \"Compare\" is triggered with this option set the following decision tree is processed:\n\n -----------------\n |Decision tree|\n -----------------\n ________|___________\n | |\n file exists on both sides on one side only\n _____|______ __|___\n | | | |\nequal different left right\n _________|_____________\n | | |\n left newer right newer different (but same date)\n\nAs a result 6 different status can be returned to categorize all files:\n\n- exists left only\n- exists right only\n- left newer\n- right newer\n- different (but same date)\n- equal\n\n\nCompare by \"File content\"\n----------------------------------------\nAs the name suggests, two files which share the same name are marked as equal if and only if they have the same content. This option is useful for consistency checks rather than backup operations. Therefore the file times are not taken into account at all.\n\nWith this option enabled the decision tree is smaller:\n\n -----------------\n |Decision tree|\n -----------------\n ________|___________\n | |\n file exists on both sides on one side only\n _____|______ __|___\n | | | |\nequal different left right\n\nAs a result the files are separated into the following categories:\n\n- exists left only\n- exists right only\n- different\n- equal +Vergleichen nach \"Dateigröße und -datum\"\n---------------------------------------------------\nDiese Variante identifiziert zwei gleichnamige Dateien als gleich, wenn sie die gleiche Dateigröße haben UND der Zeitpunkt der letzten Änderung derselbe ist. (Dabei wird eine Abweichung von bis zu zwei Sekunden toleriert.)\n\nNachdem \"Compare\" mit dieser Einstellung gestartet wurde, wird der folgende Entscheidungsbaum abgearbeitet:\n\n -------------------------\n |Entscheidungsbaum|\n -------------------------\n __________|___________\n | |\n Datei ex. auf beiden Seiten nur auf einer Seite\n ________|____ __|___\n | | | |\n gleich verschieden links rechts\n __________|___________\n | | |\n links neuer rechts neuer verschieden (bei gleichem Datum)\n\nAls Ergebnis werden 6 verschiedene Status zurückgegeben, um Dateien zu kategorisieren:\n\n- existiert nur links\n- existiert nur rechts\n- links neuer\n- rechts neuer\n- verschieden (bei gleichem Datum)\n- gleich\n\n\nVergleichen nach \"Dateiinhalt\"\n------------------------------------\nWie der Name bereits sagt, werden zwei Dateien mit gleichem Namen genau dann als gleich angesehen, wenn sie den gleichen Dateiinhalt haben. Diese Einstellung ist eher für Konsistenzprüfungen geeignet als für Backup-Operationen. Aus diesem Grund wird der Zeitpunkt der letzten Änderung der Dateien nicht berücksichtigt.\n\nDer Entscheidungsbaum ist in diesem Fall kleiner:\n\n -------------------------\n |Entscheidungsbaum|\n -------------------------\n __________|___________\n | |\n Datei ex. auf beiden Seiten nur auf einer Seite\n ________|____ __|___\n | | | |\n gleich verschieden links rechts\n\nDas Ergebnis ist eine Aufteilung in folgende Kategorien:\n\n- existiert nur links\n- existiert nur rechts\n- verschieden\n- gleich Compare by... Vergleichen nach... Comparing content of files @@ -332,6 +328,14 @@ Error overwriting file Fehler beim Überschreiben der Datei Error reading file: Fehler beim Lesen der Datei: +Error traversing directory +Fehler beim Durchsuchen des Verzeichnisses +Error when converting int to wxString +Fehler bei Konvertierung (int nach wxString) +Error when converting wxString to double +Fehler bei Konvertierung (wxString nach double) +Error when converting wxString to long +Fehler bei Konvertierung (wxString nach long) Error when modifying GUI grid Fehler beim Modifizieren des UI Grids Error: Source directory does not exist anymore: @@ -399,7 +403,7 @@ Ordner/Dateien, die nur rechts existieren FreeFileSync (Date: FreeFileSync (Datum: FreeFileSync - Folder Comparison and Synchronization -FreeFileSync - Dateivergleich und -synchronisation +FreeFileSync - Verzeichnisvergleich und -synchronisation FreeFileSync at Sourceforge FreeFileSync bei Sourceforge FreeFileSync configuration @@ -428,12 +432,18 @@ If you like FFS: FFS unterstützen: Include Einschließen +Info +Info Information Information +Initialization of Recycle Bin failed! It cannot be used! +Die Initialisierung des Papierkorbs ist fehlgeschlagen! Er kann nicht verwendet werden! It was not possible to gain access to Recycle Bin!\n\nIt's likely that you are not using Windows XP. (Probably Vista)\nIf you want this feature included, please contact the author. :) Die Papierkorbfunktion steht nicht zur Verfügung!\n\nWahrscheinlich ist das aktuelle Betriebssystem nicht Windows XP. (Möglicherweise Vista)\nWenn Sie diese Funktion wirklich benötigen kontaktieren Sie bitte den Autor. :) Items completed: Elemente komplett: +Left directory does not exist. Please select a new one! +Verzeichnis auf der linken Seite existiert nicht. Bitte ein anderes auswählen! Left folder: Linker Ordner: Legend\n @@ -444,6 +454,8 @@ Load configuration... Konfiguration laden... Log-messages: Lognachrichten: +Log-messages:\n------------- +Lognachrichten:\n--------------- Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization. Spiegel-Backup des linken Ordners erstellen: Der rechte Ordner wird dabei überschrieben und nach der Synchronisation dem linken exakt gleichen. Move files to Recycle Bin instead of deleting or overwriting them directly.\n @@ -452,8 +464,14 @@ Not all items have been synchronized! You may try to synchronize the remaining i Nicht alle Objekte wurden synchronisiert! Die Synchronisation kann erneut gestartet werden (OHNE dass ein erneuter Vergleich notwendig ist)! Not all items were synchronized! Have a look at the list. Nicht alle Objekte wurden synchronisiert! Siehe die verbliebenen Elemente im Hauptfenster. +Nothing to synchronize. Both directories adhere to the sync-configuration! +Nichts zu synchronisieren. Beide Verzeichnisse entsprechen den Synchronisationseinstellungen! Nothing to synchronize. Both directories seem to contain the same data! Nichts zu synchronisieren. Beide Verzeichnisse scheinen dieselben Daten zu enthalten! +Number of files and directories that will be created +Anzahl der Dateien und Verzeichnisse, die erstellt werden +Number of files and directories that will be deleted +Anzahl der Dateien und Verzeichnisse, die gelöscht werden Number of files or directories that will be created Anzahl der Dateien oder Verzeichnisse, die erstellt werden Number of files or directories that will be deleted @@ -480,6 +498,8 @@ Operation: Vorgang: Pause Pause +Please select both left and right directories! +Bitte für beide Seiten ein Verzeichnis wählen! Please select directories for both sides! Bitte für beide Seiten ein Verzeichnis wählen! Press button to activate filter @@ -500,6 +520,8 @@ Result Ergebnis Retry Wiederholen +Right directory does not exist. Please select a new one! +Verzeichnis auf der rechten Seite existiert nicht. Bitte ein anderes auswählen! Right folder: Rechter Ordner: Running... @@ -524,6 +546,18 @@ Set filter for synchronization Filter einstellen Shell script Shell Skript +Show files that are different +Zeige unterschiedliche Dateien +Show files that are equal +Zeige gleiche Dateien +Show files that are newer on left +Zeige Dateien, die auf beiden Seiten existieren; linke Datei ist neuer +Show files that are newer on right +Zeige Dateien, die auf beiden Seiten existieren; rechte Datei ist neuer +Show files that exist on left side only +Zeige Dateien, die nur links existieren +Show files that exist on right side only +Zeige Dateien, die nur rechts existieren Silent mode Stiller Modus Size @@ -540,20 +574,30 @@ Specify names to be included separated by ';'. Wildcards '*' and '?' are support Einzuschließende Namen, getrennt durch ';' angeben. Platzhalter '*' und '?' werden unterstützt. Standard: \"*\"\n Specify the sync-direction used for each type of file by a string of five chars:\n\n\t\tChar 1: Folders/files that exist on left side only\n\t\tChar 2: Folders/files that exist on right side only\n\t\tChar 3: Files that exist on both sides, left one is newer\n\t\tChar 4: Files that exist on both sides, right one is newer\n\t\tChar 5: Files that exist on both sides and are different\n\n\t\tSync-direction: L: left, R: right, N: none\n Synchronisationseinstellungen durch Zeichenkette der Länge 5 spezifizieren:\n\n\t\t1. Zeichen: Ordner/Dateien, die nur links existieren\n\t\t2. Zeichen: Ordner/Dateien, die nur rechts existieren\n\t\t3. Zeichen: Dateien, die auf beiden Seiten existieren; linke Datei ist neuer\n\t\t4. Zeichen: Dateien, die auf beiden Seiten existieren; rechte Datei ist neuer\n\t\t5. Zeichen: Dateien, die auf beiden Seiten existieren und verschieden sind\n\n\t\tSynchronisationsrichtung: L: links, R: rechts, N: nichts tun\n +Start +Start Start synchronization Starte die Synchronisation Start synchronizing files Beginne Synchronisation der Daten +Stop +Stop Swap sides Vertausche Seiten Synchronization aborted! Synchronisation abgebrochen! Synchronization aborted: You may try to synchronize remaining items again (WITHOUT having to re-compare)! Synchronisation abgebrochen: Die Synchronisation kann erneut gestartet werden (OHNE dass ein erneuter Vergleich notwendig ist)! +Synchronization completed successfully. +Synchronisation erfolgreich abgeschlossen. +Synchronization completed with errors! +Synchronisation abgeschlossen. Es sind Fehler aufgetreten. Synchronization completed. Synchronisation abgeschlossen. Synchronization settings Synchronisationseinstellungen +Synchronization started. +Synchronisation gestartet. Synchronization status Synchronisation: Status Synchronize both sides simultaneously: Copy new or updated files in both directions. diff --git a/library/CustomGrid.cpp b/library/CustomGrid.cpp index 053244f5..93f2107a 100644 --- a/library/CustomGrid.cpp +++ b/library/CustomGrid.cpp @@ -53,29 +53,29 @@ public: if (selectedForSynchronization) switch (result) { - case fileOnLeftSideOnly: - return "<|"; + case FILE_LEFT_SIDE_ONLY: + return wxT("<|"); break; - case fileOnRightSideOnly: - return "|>"; + case FILE_RIGHT_SIDE_ONLY: + return wxT("|>"); break; - case rightFileNewer: - return ">>"; + case FILE_RIGHT_NEWER: + return wxT(">>"); break; - case leftFileNewer: - return "<<"; + case FILE_LEFT_NEWER: + return wxT("<<"); break; - case filesDifferent: - return "!="; + case FILE_DIFFERENT: + return wxT("!="); break; - case filesEqual: - return "=="; + case FILE_EQUAL: + return wxT("=="); break; default: assert (false); return wxEmptyString; } - else return "(-)"; + else return wxT("(-)"); } @@ -93,7 +93,7 @@ public: case 1: if (col < 4) { - if (gridLine.fileDescrLeft.objType == isDirectory) + if (gridLine.fileDescrLeft.objType == TYPE_DIRECTORY) { switch (col) { @@ -107,7 +107,7 @@ public: return gridLine.fileDescrLeft.lastWriteTime; } } - else if (gridLine.fileDescrLeft.objType == isFile) + else if (gridLine.fileDescrLeft.objType == TYPE_FILE) { switch (col) { @@ -127,7 +127,7 @@ public: case 2: if (col < 4) { - if (gridLine.fileDescrRight.objType == isDirectory) + if (gridLine.fileDescrRight.objType == TYPE_DIRECTORY) { switch (col) { @@ -141,7 +141,7 @@ public: return gridLine.fileDescrRight.lastWriteTime; } } - else if (gridLine.fileDescrRight.objType == isFile) + else if (gridLine.fileDescrRight.objType == TYPE_FILE) { switch (col) { @@ -426,8 +426,7 @@ void CustomGrid::setScrollFriends(CustomGrid* grid1, CustomGrid* grid2, CustomGr void CustomGrid::setGridDataTable(GridView* gridRefUI, FileCompareResult* gridData) -{ - //set underlying grid data +{ //set underlying grid data assert(gridDataTable); gridDataTable->setGridDataTable(gridRefUI, gridData); } diff --git a/library/globalFunctions.cpp b/library/globalFunctions.cpp index d91fa8b1..5afb1650 100644 --- a/library/globalFunctions.cpp +++ b/library/globalFunctions.cpp @@ -71,7 +71,7 @@ int globalFunctions::wxStringToInt(const wxString& number) if (number.ToLong(&result)) return result; else - throw std::runtime_error("Error when converting number to long"); + throw RuntimeException(_("Error when converting wxString to long")); } @@ -82,7 +82,7 @@ double globalFunctions::wxStringToDouble(const wxString& number) if (number.ToDouble(&result)) return result; else - throw std::runtime_error("Error when converting number to double"); + throw RuntimeException(_("Error when converting wxString to double")); } diff --git a/library/globalFunctions.h b/library/globalFunctions.h index d9c0d69f..55e37c61 100644 --- a/library/globalFunctions.h +++ b/library/globalFunctions.h @@ -4,7 +4,6 @@ #include <string> #include <algorithm> #include <wx/string.h> -#include <stdexcept> //for std::runtime_error using namespace std; @@ -34,4 +33,20 @@ namespace globalFunctions wxString& includeNumberSeparator(wxString& number); } + + +class RuntimeException //Exception class used to notify of general runtime exceptions +{ +public: + RuntimeException(const wxString& txt) : errorMessage(txt) {} + + wxString show() const + { + return errorMessage; + } + +private: + wxString errorMessage; +}; + #endif // GLOBALFUNCTIONS_H_INCLUDED diff --git a/library/misc.cpp b/library/misc.cpp index 2a5c0ec2..44dcaf0e 100644 --- a/library/misc.cpp +++ b/library/misc.cpp @@ -3,15 +3,13 @@ #include <wx/msgdlg.h> #include "resources.h" -wxString exchangeEscapeChars(char* temp) +void exchangeEscapeChars(wxString& data) { - wxString output(temp); - output.Replace("\\\\", "\\"); - output.Replace("\\n", "\n"); - output.Replace("\\t", "\t"); - output.Replace("\"\"", """"); - output.Replace("\\\"", "\""); - return output; + data.Replace(wxT("\\\\"), wxT("\\")); + data.Replace(wxT("\\n"), wxT("\n")); + data.Replace(wxT("\\t"), wxT("\t")); + data.Replace(wxT("\"\""), wxT("""")); + data.Replace(wxT("\\\""), wxT("\"")); } @@ -25,13 +23,13 @@ CustomLocale::~CustomLocale() { //write language to file ofstream output("lang.dat"); - if (!output) + if (output) { - wxMessageBox(wxString(_("Could not write to ")) + "\"" + "lang.dat" + "\"", _("An exception occured!"), wxOK | wxICON_ERROR); - return; + output<<currentLanguage<<char(0); + output.close(); } - output<<currentLanguage<<char(0); - output.close(); + else + wxMessageBox(wxString(_("Could not write to ")) + wxT("\"") + wxT("lang.dat") + wxT("\""), _("An exception occured!"), wxOK | wxICON_ERROR); } @@ -61,7 +59,7 @@ void CustomLocale::loadLanguageFile(int language) { currentLanguage = language; - wxString languageFile; + string languageFile; switch (language) { case wxLANGUAGE_GERMAN: @@ -69,16 +67,17 @@ void CustomLocale::loadLanguageFile(int language) break; default: - languageFile = ""; + languageFile = string(); currentLanguage = wxLANGUAGE_ENGLISH; } //load language file into buffer translationDB.clear(); - char temp[100000]; - if (!languageFile.IsEmpty()) + const int bufferSize = 100000; + char temp[bufferSize]; + if (!languageFile.empty()) { - ifstream langFile(languageFile.c_str()); + ifstream langFile(languageFile.c_str(), ios::binary); if (langFile) { int rowNumber = 0; @@ -89,22 +88,20 @@ void CustomLocale::loadLanguageFile(int language) //Linux: 0xa //Mac: 0xd //Win: 0xd 0xa -#ifdef FFS_WIN - while (langFile.getline(temp, 100000)) - { -#elif defined FFS_LINUX - while (langFile.getline(temp, 100000, 0xd)) //specify delimiter explicitely + while (langFile.getline(temp, bufferSize, 0xd)) //specify delimiter explicitely { - //strangely this approach does NOT work under windows :( - langFile.get(); //delimiter 0xd is completely ignored (and also not extracted) -#else - assert (false); -#endif + langFile.get(); //discard the 0xa character + + //wxString formattedString(temp, *wxConvUTF8, bufferSize); //convert UTF8 input to Unicode + wxString formattedString(temp); + + exchangeEscapeChars(formattedString); + if (rowNumber%2 == 0) - currentLine.original = exchangeEscapeChars(temp); + currentLine.original = formattedString; else { - currentLine.translation = exchangeEscapeChars(temp); + currentLine.translation = formattedString; translationDB.insert(currentLine); } ++rowNumber; @@ -112,7 +109,7 @@ void CustomLocale::loadLanguageFile(int language) langFile.close(); } else - wxMessageBox(wxString(_("Could not read language file ")) + "\"" + languageFile + "\"", _("An exception occured!"), wxOK | wxICON_ERROR); + wxMessageBox(wxString(_("Could not read language file ")) + wxT("\"") + wxString(languageFile.c_str(), wxConvUTF8) + wxT("\""), _("An exception occured!"), wxOK | wxICON_ERROR); } else ; //if languageFile is empty language is defaulted to english diff --git a/library/multithreading.cpp b/library/multithreading.cpp index 099836de..bb598194 100644 --- a/library/multithreading.cpp +++ b/library/multithreading.cpp @@ -144,7 +144,7 @@ void UpdateWhileExecuting::execute(StatusUpdater* statusUpdater) theWorkerThread->beginProcessing.Signal(); theWorkerThread->readyToBeginProcessing.Unlock(); - while (receivingResult.WaitTimeout(uiUpdateInterval) == wxCOND_TIMEOUT) + while (receivingResult.WaitTimeout(UI_UPDATE_INTERVAL) == wxCOND_TIMEOUT) statusUpdater->triggerUI_Refresh(); //ATTENTION: Exception "AbortThisProcess" may be thrown here!!! } diff --git a/library/multithreading.h b/library/multithreading.h index 36b37f2a..56cff890 100644 --- a/library/multithreading.h +++ b/library/multithreading.h @@ -35,7 +35,7 @@ protected: }; -const int uiUpdateInterval = 100; //perform ui updates not more often than necessary, 100 seems to be a good value with only a minimal performance loss +const int UI_UPDATE_INTERVAL = 100; //perform ui updates not more often than necessary, 100 seems to be a good value with only a minimal performance loss class WorkerThread; diff --git a/library/resources.cpp b/library/resources.cpp index 73e11575..6e5feaf7 100644 --- a/library/resources.cpp +++ b/library/resources.cpp @@ -3,7 +3,7 @@ #include <wx/zipstrm.h> #include <wx/image.h> #include <wx/icon.h> -#include <stdexcept> //for std::runtime_error +#include "globalFunctions.h" #ifdef FFS_WIN wxChar GlobalResources::fileNameSeparator = '\\'; @@ -14,21 +14,21 @@ assert(false); #endif //these two global variables are language-dependent => cannot be set statically! See CustomLocale -const wxChar* GlobalResources::decimalPoint = ""; -const wxChar* GlobalResources::thousandsSeparator = ""; +const wxChar* GlobalResources::decimalPoint = wxEmptyString; +const wxChar* GlobalResources::thousandsSeparator = wxEmptyString; //command line parameters -const wxChar* GlobalResources::paramCompare = "cmp"; -const wxChar* GlobalResources::paramCfg = "cfg"; -const wxChar* GlobalResources::paramInclude = "incl"; -const wxChar* GlobalResources::paramExclude = "excl"; -const wxChar* GlobalResources::paramContinueError = "continue"; -const wxChar* GlobalResources::paramRecycler = "recycler"; -const wxChar* GlobalResources::paramSilent = "silent"; +const wxChar* GlobalResources::paramCompare = wxT("cmp"); +const wxChar* GlobalResources::paramCfg = wxT("cfg"); +const wxChar* GlobalResources::paramInclude = wxT("incl"); +const wxChar* GlobalResources::paramExclude = wxT("excl"); +const wxChar* GlobalResources::paramContinueError = wxT("continue"); +const wxChar* GlobalResources::paramRecycler = wxT("recycler"); +const wxChar* GlobalResources::paramSilent = wxT("silent"); -const wxChar* GlobalResources::valueSizeDate = "SIZEDATE"; -const wxChar* GlobalResources::valueContent = "CONTENT"; +const wxChar* GlobalResources::valueSizeDate = wxT("SIZEDATE"); +const wxChar* GlobalResources::valueContent = wxT("CONTENT"); map<wxString, wxBitmap*> GlobalResources::bitmapResource; @@ -90,57 +90,57 @@ wxIcon* GlobalResources::programIcon = 0; void GlobalResources::loadResourceFiles() { //map, allocate and initialize pictures - bitmapResource["left arrow.png"] = (bitmapLeftArrow = new wxBitmap(wxNullBitmap)); - bitmapResource["right arrow.png"] = (bitmapRightArrow = new wxBitmap(wxNullBitmap)); - bitmapResource["no arrow.png"] = (bitmapNoArrow = new wxBitmap(wxNullBitmap)); - bitmapResource["start sync.png"] = (bitmapStartSync = new wxBitmap(wxNullBitmap)); - bitmapResource["start sync dis.png"] = (bitmapStartSyncDis = new wxBitmap(wxNullBitmap)); - bitmapResource["delete.png"] = (bitmapDelete = new wxBitmap(wxNullBitmap)); - bitmapResource["email.png"] = (bitmapEmail = new wxBitmap(wxNullBitmap)); - bitmapResource["about.png"] = (bitmapAbout = new wxBitmap(wxNullBitmap)); - bitmapResource["website.png"] = (bitmapWebsite = new wxBitmap(wxNullBitmap)); - bitmapResource["exit.png"] = (bitmapExit = new wxBitmap(wxNullBitmap)); - bitmapResource["sync.png"] = (bitmapSync = new wxBitmap(wxNullBitmap)); - bitmapResource["compare.png"] = (bitmapCompare = new wxBitmap(wxNullBitmap)); - bitmapResource["sync disabled.png"] = (bitmapSyncDisabled = new wxBitmap(wxNullBitmap)); - bitmapResource["swap.png"] = (bitmapSwap = new wxBitmap(wxNullBitmap)); - bitmapResource["help.png"] = (bitmapHelp = new wxBitmap(wxNullBitmap)); - bitmapResource["leftOnly.png"] = (bitmapLeftOnly = new wxBitmap(wxNullBitmap)); - bitmapResource["leftNewer.png"] = (bitmapLeftNewer = new wxBitmap(wxNullBitmap)); - bitmapResource["different.png"] = (bitmapDifferent = new wxBitmap(wxNullBitmap)); - bitmapResource["rightNewer.png"] = (bitmapRightNewer = new wxBitmap(wxNullBitmap)); - bitmapResource["rightOnly.png"] = (bitmapRightOnly = new wxBitmap(wxNullBitmap)); - bitmapResource["leftOnlyDeact.png"] = (bitmapLeftOnlyDeact = new wxBitmap(wxNullBitmap)); - bitmapResource["leftNewerDeact.png"] = (bitmapLeftNewerDeact = new wxBitmap(wxNullBitmap)); - bitmapResource["differentDeact.png"] = (bitmapDifferentDeact = new wxBitmap(wxNullBitmap)); - bitmapResource["rightNewerDeact.png"] = (bitmapRightNewerDeact = new wxBitmap(wxNullBitmap)); - bitmapResource["rightOnlyDeact.png"] = (bitmapRightOnlyDeact = new wxBitmap(wxNullBitmap)); - bitmapResource["equal.png"] = (bitmapEqual = new wxBitmap(wxNullBitmap)); - bitmapResource["equalDeact.png"] = (bitmapEqualDeact = new wxBitmap(wxNullBitmap)); - bitmapResource["include.png"] = (bitmapInclude = new wxBitmap(wxNullBitmap)); - bitmapResource["exclude.png"] = (bitmapExclude = new wxBitmap(wxNullBitmap)); - bitmapResource["filter active.png"] = (bitmapFilterOn = new wxBitmap(wxNullBitmap)); - bitmapResource["filter not active.png"] = (bitmapFilterOff = new wxBitmap(wxNullBitmap)); - bitmapResource["warning.png"] = (bitmapWarning = new wxBitmap(wxNullBitmap)); - bitmapResource["small arrow up.png"] = (bitmapSmallUp = new wxBitmap(wxNullBitmap)); - bitmapResource["small arrow down.png"] = (bitmapSmallDown = new wxBitmap(wxNullBitmap)); - bitmapResource["save.png"] = (bitmapSave = new wxBitmap(wxNullBitmap)); - bitmapResource["FFS.png"] = (bitmapFFS = new wxBitmap(wxNullBitmap)); - bitmapResource["deleteFile.png"] = (bitmapDeleteFile = new wxBitmap(wxNullBitmap)); - bitmapResource["gpl.png"] = (bitmapGPL = new wxBitmap(wxNullBitmap)); - bitmapResource["statusPause.png"] = (bitmapStatusPause = new wxBitmap(wxNullBitmap)); - bitmapResource["statusError.png"] = (bitmapStatusError = new wxBitmap(wxNullBitmap)); - bitmapResource["statusSuccess.png"] = (bitmapStatusSuccess = new wxBitmap(wxNullBitmap)); - bitmapResource["statusWarning.png"] = (bitmapStatusWarning = new wxBitmap(wxNullBitmap)); - bitmapResource["statusScanning.png"] = (bitmapStatusScanning = new wxBitmap(wxNullBitmap)); - bitmapResource["statusComparing.png"] = (bitmapStatusComparing = new wxBitmap(wxNullBitmap)); - bitmapResource["statusSyncing.png"] = (bitmapStatusSyncing = new wxBitmap(wxNullBitmap)); - bitmapResource["logo.png"] = (bitmapLogo = new wxBitmap(wxNullBitmap)); - bitmapResource["finished.png"] = (bitmapFinished = new wxBitmap(wxNullBitmap)); - bitmapResource["statusEdge.png"] = (bitmapStatusEdge = new wxBitmap(wxNullBitmap)); - - wxFileInputStream input("Resources.dat"); - if (!input.IsOk()) throw runtime_error(_("Unable to load Resources.dat!")); + bitmapResource[wxT("left arrow.png")] = (bitmapLeftArrow = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("right arrow.png")] = (bitmapRightArrow = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("no arrow.png")] = (bitmapNoArrow = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("start sync.png")] = (bitmapStartSync = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("start sync dis.png")] = (bitmapStartSyncDis = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("delete.png")] = (bitmapDelete = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("email.png")] = (bitmapEmail = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("about.png")] = (bitmapAbout = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("website.png")] = (bitmapWebsite = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("exit.png")] = (bitmapExit = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("sync.png")] = (bitmapSync = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("compare.png")] = (bitmapCompare = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("sync disabled.png")] = (bitmapSyncDisabled = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("swap.png")] = (bitmapSwap = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("help.png")] = (bitmapHelp = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("leftOnly.png")] = (bitmapLeftOnly = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("leftNewer.png")] = (bitmapLeftNewer = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("different.png")] = (bitmapDifferent = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("rightNewer.png")] = (bitmapRightNewer = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("rightOnly.png")] = (bitmapRightOnly = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("leftOnlyDeact.png")] = (bitmapLeftOnlyDeact = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("leftNewerDeact.png")] = (bitmapLeftNewerDeact = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("differentDeact.png")] = (bitmapDifferentDeact = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("rightNewerDeact.png")] = (bitmapRightNewerDeact = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("rightOnlyDeact.png")] = (bitmapRightOnlyDeact = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("equal.png")] = (bitmapEqual = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("equalDeact.png")] = (bitmapEqualDeact = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("include.png")] = (bitmapInclude = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("exclude.png")] = (bitmapExclude = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("filter active.png")] = (bitmapFilterOn = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("filter not active.png")] = (bitmapFilterOff = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("warning.png")] = (bitmapWarning = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("small arrow up.png"]) = (bitmapSmallUp = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("small arrow down.png")] = (bitmapSmallDown = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("save.png")] = (bitmapSave = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("FFS.png")] = (bitmapFFS = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("deleteFile.png")] = (bitmapDeleteFile = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("gpl.png")] = (bitmapGPL = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("statusPause.png")] = (bitmapStatusPause = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("statusError.png")] = (bitmapStatusError = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("statusSuccess.png")] = (bitmapStatusSuccess = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("statusWarning.png")] = (bitmapStatusWarning = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("statusScanning.png")] = (bitmapStatusScanning = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("statusComparing.png")] = (bitmapStatusComparing = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("statusSyncing.png")] = (bitmapStatusSyncing = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("logo.png")] = (bitmapLogo = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("finished.png")] = (bitmapFinished = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("statusEdge.png")] = (bitmapStatusEdge = new wxBitmap(wxNullBitmap)); + + wxFileInputStream input(wxT("Resources.dat")); + if (!input.IsOk()) throw RuntimeException(_("Unable to load Resources.dat!")); wxZipInputStream resourceFile(input); @@ -159,11 +159,11 @@ void GlobalResources::loadResourceFiles() animationMoney = new wxAnimation(wxNullAnimation); animationSync = new wxAnimation(wxNullAnimation); - animationMoney->LoadFile("Resources.a01"); - animationSync->LoadFile("Resources.a02"); + animationMoney->LoadFile(wxT("Resources.a01")); + animationSync->LoadFile(wxT("Resources.a02")); #ifdef FFS_WIN - programIcon = new wxIcon("winIcon"); + programIcon = new wxIcon(wxT("winIcon")); #else #include "FreeFileSync.xpm" programIcon = new wxIcon(FreeFileSync_xpm); diff --git a/library/wxWidgets.h b/library/wxWidgets.h index dd27498c..a383a6f4 100644 --- a/library/wxWidgets.h +++ b/library/wxWidgets.h @@ -9,8 +9,11 @@ #endif //__BORLANDC__ #ifndef WX_PRECOMP -// Include your minimal set of headers here, or wx.h #include <wx/wx.h> #endif +#ifdef WX_PRECOMP +// put here all your rarely-changing header files +#endif // WX_PRECOMP + #endif // WXWIDGETS_H_INCLUDED diff --git a/ui/MainDialog.cpp b/ui/MainDialog.cpp index 1c31fa2a..e1681d13 100644 --- a/ui/MainDialog.cpp +++ b/ui/MainDialog.cpp @@ -43,7 +43,6 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, CustomLocale updateViewFilterButtons(); //set icons for this dialog - m_bpButton11->SetBitmapLabel(*GlobalResources::bitmapAbout); m_bpButton10->SetBitmapLabel(*GlobalResources::bitmapExit); m_bpButtonCompare->SetBitmapLabel(*GlobalResources::bitmapCompare); m_bpButtonSync->SetBitmapLabel(*GlobalResources::bitmapSync); @@ -58,13 +57,13 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, CustomLocale //create a right-click context menu contextMenu = new wxMenu; - contextMenu->Append(contextManualFilter, _("Filter manually")); - contextMenu->Append(contextCopyClipboard, _("Copy to clipboard\tCTRL+C")); + contextMenu->Append(CONTEXT_MANUAL_FILTER, _("Filter manually")); + contextMenu->Append(CONTEXT_CLIPBOARD, _("Copy to clipboard\tCTRL+C")); #ifdef FFS_WIN - contextMenu->Append(contextOpenExplorer, _("Open with Explorer\tD-Click")); + contextMenu->Append(CONTEXT_EXPLORER, _("Open with Explorer\tD-Click")); #endif contextMenu->AppendSeparator(); - contextMenu->Append(contextDeleteFiles, _("Delete files\tDEL")); + contextMenu->Append(CONTEXT_DELETE_FILES, _("Delete files\tDEL")); contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::onContextMenuSelection), NULL, this); @@ -150,10 +149,10 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, CustomLocale writeGrid(currentGridData); //load list of last used configuration files - cfgFileHistory = new wxConfig("FreeFileSync"); + cfgFileHistory = new wxConfig(wxT("FreeFileSync")); for (int i = CfgHistroyLength - 1; i >= 0; --i) //put files in reverse order to history { - const wxString key = "Selection" + numberToWxString(i); + const wxString key = wxString(wxT("Selection")) + numberToWxString(i); wxString value; if (cfgFileHistory->Read(key, &value)) @@ -247,7 +246,7 @@ MainDialog::~MainDialog() int vectorSize = cfgFileNames.size(); for (int i = 0; i < CfgHistroyLength; ++i) { - const wxString key = "Selection" + numberToWxString(i); + const wxString key = wxString(wxT("Selection")) + numberToWxString(i); if (i < vectorSize) cfgFileHistory->Write(key, cfgFileNames[i]); @@ -259,11 +258,11 @@ MainDialog::~MainDialog() } delete cfgFileHistory; - writeConfigurationToHD(FreeFileSync::FFS_LastConfigFile); //don't trow exceptions in destructors + writeConfigurationToHD(FreeFileSync::FfsLastConfigFile); //don't trow exceptions in destructors if (restartOnExit) { //create new dialog - MainDialog* frame = new MainDialog(0L, FreeFileSync::FFS_LastConfigFile, programLanguage); + MainDialog* frame = new MainDialog(0L, FreeFileSync::FfsLastConfigFile, programLanguage); frame->SetIcon(*GlobalResources::programIcon); //set application icon frame->Show(); } @@ -665,13 +664,13 @@ void MainDialog::deleteFilesOnGrid(const set<int>& rowsToDeleteOnUI) { const FileCompareLine& currentCmpLine = currentGridData[*i]; - if (currentCmpLine.fileDescrLeft.objType != isNothing) - filesToDelete+= currentCmpLine.fileDescrLeft.filename + "\n"; + if (currentCmpLine.fileDescrLeft.objType != TYPE_NOTHING) + filesToDelete+= currentCmpLine.fileDescrLeft.filename + wxT("\n"); - if (currentCmpLine.fileDescrRight.objType != isNothing) - filesToDelete+= currentCmpLine.fileDescrRight.filename + "\n"; + if (currentCmpLine.fileDescrRight.objType != TYPE_NOTHING) + filesToDelete+= currentCmpLine.fileDescrRight.filename + wxT("\n"); - filesToDelete+= "\n"; + filesToDelete+= wxT("\n"); } DeleteDialog* confirmDeletion = new DeleteDialog(headerText, filesToDelete, this); //no destruction needed; attached to main window @@ -720,27 +719,27 @@ void MainDialog::openWithFileBrowser(int rowNumber, int gridNr) #ifdef FFS_WIN if (gridNr == 1) { - wxString command = "explorer " + FreeFileSync::getFormattedDirectoryName(m_directoryPanel1->GetValue()); //default + wxString command = wxString(wxT("explorer ")) + FreeFileSync::getFormattedDirectoryName(m_directoryPanel1->GetValue()); //default if (0 <= rowNumber && rowNumber < int(gridRefUI.size())) { wxString filename = currentGridData[gridRefUI[rowNumber]].fileDescrLeft.filename; if (!filename.IsEmpty()) - command = "explorer /select," + filename; + command = wxString(wxT("explorer /select,")) + filename; } wxExecute(command); } else if (gridNr == 2) { - wxString command = "explorer " + FreeFileSync::getFormattedDirectoryName(m_directoryPanel2->GetValue()); //default + wxString command = wxString(wxT("explorer ")) + FreeFileSync::getFormattedDirectoryName(m_directoryPanel2->GetValue()); //default if (0 <= rowNumber && rowNumber < int(gridRefUI.size())) { wxString filename = currentGridData[gridRefUI[rowNumber]].fileDescrRight.filename; if (!filename.IsEmpty()) - command = "explorer /select," + filename; + command = wxString(wxT("explorer /select,")) + filename; } wxExecute(command); } @@ -774,22 +773,19 @@ void MainDialog::onResizeMainWindow(wxEvent& event) { if (!IsMaximized()) { - int width = 0; + int width = 0; int height = 0; - int x = 0; - int y = 0; + int x = 0; + int y = 0; GetSize(&width, &height); GetPosition(&x, &y); - if (width > 0 && height > 0) - { + if (width > 0 && height > 0 && x >= 0 && y >= 0) //test ALL parameters at once, since width/height are invalid if + { //the window is minimized (eg x,y == -32000; height = 28, width = 160) widthNotMaximized = width; heightNotMaximized = height; - } - if (x >= 0 && y >= 0) //might be < 0 under some strange circumstances - { posXNotMaximized = x; posYNotMaximized = y; } @@ -847,22 +843,22 @@ void MainDialog::OnOpenContextMenu( wxGridEvent& event ) //enable/disable context menu entries if (selection.size() > 0) { - contextMenu->Enable(contextManualFilter, true); - contextMenu->Enable(contextCopyClipboard, true); - contextMenu->Enable(contextDeleteFiles, true); + contextMenu->Enable(CONTEXT_MANUAL_FILTER, true); + contextMenu->Enable(CONTEXT_CLIPBOARD, true); + contextMenu->Enable(CONTEXT_DELETE_FILES, true); } else { - contextMenu->Enable(contextManualFilter, false); - contextMenu->Enable(contextCopyClipboard, false); - contextMenu->Enable(contextDeleteFiles, false); + contextMenu->Enable(CONTEXT_MANUAL_FILTER, false); + contextMenu->Enable(CONTEXT_CLIPBOARD, false); + contextMenu->Enable(CONTEXT_DELETE_FILES, false); } #ifdef FFS_WIN if ((leadingPanel == 1 || leadingPanel == 2) && selection.size() <= 1) - contextMenu->Enable(contextOpenExplorer, true); + contextMenu->Enable(CONTEXT_EXPLORER, true); else - contextMenu->Enable(contextOpenExplorer, false); + contextMenu->Enable(CONTEXT_EXPLORER, false); #endif //show context menu @@ -877,15 +873,15 @@ void MainDialog::onContextMenuSelection(wxCommandEvent& event) switch (event.GetId()) { - case contextManualFilter: + case CONTEXT_MANUAL_FILTER: filterRangeManual(getSelectedRows()); break; - case contextCopyClipboard: + case CONTEXT_CLIPBOARD: copySelectionToClipboard(getSelectedRows(), leadingPanel); break; - case contextOpenExplorer: + case CONTEXT_EXPLORER: selection = getSelectedRows(); if (leadingPanel == 1 || leadingPanel == 2) @@ -897,7 +893,7 @@ void MainDialog::onContextMenuSelection(wxCommandEvent& event) } break; - case contextDeleteFiles: + case CONTEXT_DELETE_FILES: deleteFilesOnGrid(getSelectedRows()); break; } @@ -961,7 +957,7 @@ void MainDialog::OnDirChangedPanel2(wxFileDirPickerEvent& event) wxString getFormattedHistoryElement(const wxString& filename) { wxString output = wxFileName(filename).GetFullName(); - if (output.EndsWith(".ffs")) + if (output.EndsWith(wxT(".ffs"))) output = output.BeforeLast('.'); return output; } @@ -986,7 +982,7 @@ bool sameFileSpecified(const wxString& file1, const wxString& file2) void MainDialog::addCfgFileToHistory(const wxString& filename) { //the default configFile should not be in the history - if (sameFileSpecified(FreeFileSync::FFS_LastConfigFile, filename)) + if (sameFileSpecified(FreeFileSync::FfsLastConfigFile, filename)) return; @@ -1078,7 +1074,7 @@ bool FileDropEvent::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filen void MainDialog::OnSaveConfig(wxCommandEvent& event) { - wxString defaultFileName = "SyncSettings.ffs"; + wxString defaultFileName = wxT("SyncSettings.ffs"); //try to use last selected configuration file as default int selectedItem; @@ -1088,7 +1084,7 @@ void MainDialog::OnSaveConfig(wxCommandEvent& event) defaultFileName = cfgFileNames[selectedItem - 1]; - wxFileDialog* filePicker = new wxFileDialog(this, "", "", defaultFileName, wxString(_("FreeFileSync configuration")) + " (*.ffs)|*.ffs", wxFD_SAVE); + wxFileDialog* filePicker = new wxFileDialog(this, wxEmptyString, wxEmptyString, defaultFileName, wxString(_("FreeFileSync configuration")) + wxT(" (*.ffs)|*.ffs"), wxFD_SAVE); if (filePicker->ShowModal() == wxID_OK) { @@ -1096,7 +1092,7 @@ void MainDialog::OnSaveConfig(wxCommandEvent& event) if (wxFileExists(newFileName)) { - wxMessageDialog* messageDlg = new wxMessageDialog(this, wxString("\"") + newFileName + "\"" + _(" already exists. Overwrite?"), _("Warning") , wxOK | wxCANCEL); + wxMessageDialog* messageDlg = new wxMessageDialog(this, wxString(wxT("\"")) + newFileName + wxT("\"") + _(" already exists. Overwrite?"), _("Warning") , wxOK | wxCANCEL); if (messageDlg->ShowModal() != wxID_OK) { @@ -1126,10 +1122,10 @@ void MainDialog::OnLoadConfiguration(wxCommandEvent& event) switch (selectedItem) { case 0: //load config from file - filePicker = new wxFileDialog(this, "", "", "", wxString(_("FreeFileSync configuration")) + " (*.ffs)|*.ffs", wxFD_OPEN); + filePicker = new wxFileDialog(this, wxEmptyString, wxEmptyString, wxEmptyString, wxString(_("FreeFileSync configuration")) + wxT(" (*.ffs)|*.ffs"), wxFD_OPEN); if (filePicker->ShowModal() == wxID_OK) - newCfgFile = filePicker->GetFilename(); + newCfgFile = filePicker->GetPath(); break; default: @@ -1179,14 +1175,14 @@ void MainDialog::OnChoiceKeyEvent(wxKeyEvent& event) void MainDialog::OnCompareByTimeSize(wxCommandEvent& event) { - cfg.compareVar = compareByTimeAndSize; + cfg.compareVar = CMP_BY_TIME_SIZE; updateCompareButtons(); } void MainDialog::OnCompareByContent(wxCommandEvent& event) { - cfg.compareVar = compareByContent; + cfg.compareVar = CMP_BY_CONTENT; updateCompareButtons(); } @@ -1206,17 +1202,17 @@ void MainDialog::OnQuit(wxCommandEvent &event) void MainDialog::loadDefaultConfiguration() { //default values - cfg.syncConfiguration.exLeftSideOnly = syncDirRight; - cfg.syncConfiguration.exRightSideOnly = syncDirRight; - cfg.syncConfiguration.leftNewer = syncDirRight; - cfg.syncConfiguration.rightNewer = syncDirRight; - cfg.syncConfiguration.different = syncDirRight; + cfg.syncConfiguration.exLeftSideOnly = SYNC_DIR_RIGHT; + cfg.syncConfiguration.exRightSideOnly = SYNC_DIR_RIGHT; + cfg.syncConfiguration.leftNewer = SYNC_DIR_RIGHT; + cfg.syncConfiguration.rightNewer = SYNC_DIR_RIGHT; + cfg.syncConfiguration.different = SYNC_DIR_RIGHT; - cfg.compareVar = compareByTimeAndSize; //compare algorithm + cfg.compareVar = CMP_BY_TIME_SIZE; //compare algorithm updateCompareButtons(); - cfg.includeFilter = "*"; //include all files/folders - cfg.excludeFilter = ""; //exlude nothing + cfg.includeFilter = wxT("*"); //include all files/folders + cfg.excludeFilter = wxEmptyString; //exlude nothing //set status of filter button cfg.filterIsActive = false; //do not filter by default @@ -1246,15 +1242,15 @@ void MainDialog::readConfigurationFromHD(const wxString& filename, bool programS if (programStartup) loadDefaultConfiguration(); else - wxMessageBox(wxString(_("Could not read configuration file ")) + "\"" + filename + "\"", _("An exception occured!"), wxOK | wxICON_ERROR); + wxMessageBox(wxString(_("Could not read configuration file ")) + wxT("\"") + filename + wxT("\""), _("An exception occured!"), wxOK | wxICON_ERROR); return; } //read FFS identifier - config.get(bigBuffer, FreeFileSync::FFS_ConfigFileID.Len() + 1); + config.get(bigBuffer, FreeFileSync::FfsConfigFileID.size() + 1); - if (wxString(bigBuffer) != FreeFileSync::FFS_ConfigFileID) + if (string(bigBuffer) != FreeFileSync::FfsConfigFileID) { wxMessageBox(_("The selected file does not contain a valid configuration!"), _("Warning"), wxOK); config.close(); @@ -1354,7 +1350,7 @@ void MainDialog::writeConfigurationToHD(const wxString& filename) ofstream config(filename.c_str()); if (!config) { - wxMessageBox(wxString(_("Could not write to ")) + "\"" + filename + "\"", _("An exception occured!"), wxOK | wxICON_ERROR); + wxMessageBox(wxString(_("Could not write to ")) + wxT("\"") + filename + wxT("\""), _("An exception occured!"), wxOK | wxICON_ERROR); return; } @@ -1362,7 +1358,7 @@ void MainDialog::writeConfigurationToHD(const wxString& filename) addCfgFileToHistory(filename); //write FFS identifier - config<<FreeFileSync::FFS_ConfigFileID.c_str(); + config<<FreeFileSync::FfsConfigFileID.c_str(); //write sync configuration config<<char(cfg.syncConfiguration.exLeftSideOnly) @@ -1410,14 +1406,6 @@ void MainDialog::writeConfigurationToHD(const wxString& filename) } -void MainDialog::OnAbout(wxCommandEvent &event) -{ - AboutDlg* aboutDlg = new AboutDlg(this); - aboutDlg->ShowModal(); - event.Skip(); -} - - void MainDialog::OnShowHelpDialog(wxCommandEvent &event) { HelpDlg* helpDlg = new HelpDlg(this); @@ -1445,11 +1433,11 @@ void MainDialog::OnFilterButton(wxCommandEvent &event) void MainDialog::OnHideFilteredButton(wxCommandEvent &event) { //toggle showing filtered rows cfg.hideFiltered = !cfg.hideFiltered; + //make sure, checkbox and "hideFiltered" are in sync + m_checkBoxHideFilt->SetValue(cfg.hideFiltered); writeGrid(currentGridData); - //make sure, checkbox and "hideFiltered" are in sync - m_checkBoxHideFilt->SetValue(cfg.hideFiltered); event.Skip(); } @@ -1465,7 +1453,7 @@ void MainDialog::OnConfigureFilter(wxHyperlinkEvent &event) if (beforeImage != afterImage) //if filter settings are changed: set filtering to "on" { - if (afterImage == (wxString("*") + wxChar(1))) //default + if (afterImage == (wxString(wxT("*")) + wxChar(1))) //default { cfg.filterIsActive = false; FreeFileSync::removeFilterOnCurrentGridData(currentGridData); @@ -1536,34 +1524,34 @@ void MainDialog::OnEqualFiles(wxCommandEvent& event) void MainDialog::updateViewFilterButtons() { if (leftOnlyFilesActive) - m_bpButton20->SetBitmapLabel(*GlobalResources::bitmapLeftOnly); + m_bpButtonLeftOnly->SetBitmapLabel(*GlobalResources::bitmapLeftOnly); else - m_bpButton20->SetBitmapLabel(*GlobalResources::bitmapLeftOnlyDeact); + m_bpButtonLeftOnly->SetBitmapLabel(*GlobalResources::bitmapLeftOnlyDeact); if (leftNewerFilesActive) - m_bpButton21->SetBitmapLabel(*GlobalResources::bitmapLeftNewer); + m_bpButtonLeftNewer->SetBitmapLabel(*GlobalResources::bitmapLeftNewer); + else + m_bpButtonLeftNewer->SetBitmapLabel(*GlobalResources::bitmapLeftNewerDeact); + + if (equalFilesActive) + m_bpButtonEqual->SetBitmapLabel(*GlobalResources::bitmapEqual); else - m_bpButton21->SetBitmapLabel(*GlobalResources::bitmapLeftNewerDeact); + m_bpButtonEqual->SetBitmapLabel(*GlobalResources::bitmapEqualDeact); if (differentFilesActive) - m_bpButton22->SetBitmapLabel(*GlobalResources::bitmapDifferent); + m_bpButtonDifferent->SetBitmapLabel(*GlobalResources::bitmapDifferent); else - m_bpButton22->SetBitmapLabel(*GlobalResources::bitmapDifferentDeact); + m_bpButtonDifferent->SetBitmapLabel(*GlobalResources::bitmapDifferentDeact); if (rightNewerFilesActive) - m_bpButton23->SetBitmapLabel(*GlobalResources::bitmapRightNewer); + m_bpButtonRightNewer->SetBitmapLabel(*GlobalResources::bitmapRightNewer); else - m_bpButton23->SetBitmapLabel(*GlobalResources::bitmapRightNewerDeact); + m_bpButtonRightNewer->SetBitmapLabel(*GlobalResources::bitmapRightNewerDeact); if (rightOnlyFilesActive) - m_bpButton24->SetBitmapLabel(*GlobalResources::bitmapRightOnly); + m_bpButtonRightOnly->SetBitmapLabel(*GlobalResources::bitmapRightOnly); else - m_bpButton24->SetBitmapLabel(*GlobalResources::bitmapRightOnlyDeact); - - if (equalFilesActive) - m_bpButton25->SetBitmapLabel(*GlobalResources::bitmapEqual); - else - m_bpButton25->SetBitmapLabel(*GlobalResources::bitmapEqualDeact); + m_bpButtonRightOnly->SetBitmapLabel(*GlobalResources::bitmapRightOnlyDeact); } @@ -1586,19 +1574,11 @@ void MainDialog::updateCompareButtons() { switch (cfg.compareVar) { - case compareByTimeAndSize: + case CMP_BY_TIME_SIZE: m_radioBtnSizeDate->SetValue(true); - - m_bpButton21->Show(); //show or hide filter buttons depending on selected compare variant - m_bpButton23->Show(); - bSizer59->Layout(); break; - case compareByContent: + case CMP_BY_CONTENT: m_radioBtnContent->SetValue(true); - - m_bpButton21->Hide(); - m_bpButton23->Hide(); - bSizer59->Layout(); break; default: assert (false); @@ -1737,21 +1717,24 @@ void MainDialog::OnSync(wxCommandEvent& event) SyncDialog* syncDlg = new SyncDialog(this, currentGridData, cfg, synchronizationEnabled); if (syncDlg->ShowModal() == SyncDialog::StartSynchronizationProcess) { - //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) - { - nothingToSync = false; - break; - } - - if (nothingToSync) + //check if there are files/folders to be sync'ed at all + int objectsToCreate = 0; + int objectsToOverwrite = 0; + int objectsToDelete = 0; + double dataToProcess = 0; + FreeFileSync::calcTotalBytesToSync(objectsToCreate, + objectsToOverwrite, + objectsToDelete, + dataToProcess, + currentGridData, + cfg.syncConfiguration); + if (objectsToCreate + objectsToOverwrite + objectsToDelete == 0) { - wxMessageBox(_("Nothing to synchronize. Both directories seem to contain the same data!"), _("Information"), wxICON_WARNING); + wxMessageBox(_("Nothing to synchronize. Both directories adhere to the sync-configuration!"), _("Information"), wxICON_WARNING); return; } + wxBeginBusyCursor(); clearStatusBar(); @@ -1846,24 +1829,24 @@ bool sortGridLeft(const GridViewLine a, const GridViewLine b) { case 0: //presort types: first files, then directories then empty rows - if (gridDataLineA.objType == isNothing) + if (gridDataLineA.objType == TYPE_NOTHING) return false; //empty rows always last - else if (gridDataLineB.objType == isNothing) + else if (gridDataLineB.objType == TYPE_NOTHING) return true; //empty rows always last - else if (gridDataLineA.objType == isDirectory) + else if (gridDataLineA.objType == TYPE_DIRECTORY) return false; - else if (gridDataLineB.objType == isDirectory) + else if (gridDataLineB.objType == TYPE_DIRECTORY) return true; else return cmpString(gridDataLineA.relFilename.AfterLast(GlobalResources::fileNameSeparator), gridDataLineB.relFilename.AfterLast(GlobalResources::fileNameSeparator)); case 1: - if (gridDataLineA.objType == isDirectory) + if (gridDataLineA.objType == TYPE_DIRECTORY) stringA = gridDataLineA.relFilename; else stringA = gridDataLineA.relFilename.BeforeLast(GlobalResources::fileNameSeparator); - if (gridDataLineB.objType == isDirectory) + if (gridDataLineB.objType == TYPE_DIRECTORY) stringB = gridDataLineB.relFilename; else stringB = gridDataLineB.relFilename.BeforeLast(GlobalResources::fileNameSeparator); @@ -1872,13 +1855,13 @@ bool sortGridLeft(const GridViewLine a, const GridViewLine b) case 2: //presort types: first files, then directories then empty rows - if (gridDataLineA.objType == isNothing) + if (gridDataLineA.objType == TYPE_NOTHING) return false; //empty rows always last - else if (gridDataLineB.objType == isNothing) + else if (gridDataLineB.objType == TYPE_NOTHING) return true; //empty rows always last - else if (gridDataLineA.objType == isDirectory) + else if (gridDataLineA.objType == TYPE_DIRECTORY) return false; - else if (gridDataLineB.objType == isDirectory) + else if (gridDataLineB.objType == TYPE_DIRECTORY) return true; else //use unformatted filesizes and sort by size return cmpLargeInt(gridDataLineA.fileSize, gridDataLineB.fileSize); @@ -1905,25 +1888,25 @@ bool sortGridRight(const GridViewLine a, const GridViewLine b) { case 0: //presort types: first files, then directories then empty rows - if (gridDataLineA.objType == isNothing) + if (gridDataLineA.objType == TYPE_NOTHING) return false; //empty rows always last - else if (gridDataLineB.objType == isNothing) + else if (gridDataLineB.objType == TYPE_NOTHING) return true; //empty rows always last - else if (gridDataLineA.objType == isDirectory) + else if (gridDataLineA.objType == TYPE_DIRECTORY) return false; - else if (gridDataLineB.objType == isDirectory) + else if (gridDataLineB.objType == TYPE_DIRECTORY) return true; else return cmpString(gridDataLineA.relFilename.AfterLast(GlobalResources::fileNameSeparator), gridDataLineB.relFilename.AfterLast(GlobalResources::fileNameSeparator)); case 1: - if (gridDataLineA.objType == isDirectory) + if (gridDataLineA.objType == TYPE_DIRECTORY) stringA = gridDataLineA.relFilename; else stringA = gridDataLineA.relFilename.BeforeLast(GlobalResources::fileNameSeparator); - if (gridDataLineB.objType == isDirectory) + if (gridDataLineB.objType == TYPE_DIRECTORY) stringB = gridDataLineB.relFilename; else stringB = gridDataLineB.relFilename.BeforeLast(GlobalResources::fileNameSeparator); @@ -1932,13 +1915,13 @@ bool sortGridRight(const GridViewLine a, const GridViewLine b) case 2: //presort types: first files, then directories then empty rows - if (gridDataLineA.objType == isNothing) + if (gridDataLineA.objType == TYPE_NOTHING) return false; //empty rows always last - else if (gridDataLineB.objType == isNothing) + else if (gridDataLineB.objType == TYPE_NOTHING) return true; //empty rows always last - else if (gridDataLineA.objType == isDirectory) + else if (gridDataLineA.objType == TYPE_DIRECTORY) return false; - else if (gridDataLineB.objType == isDirectory) + else if (gridDataLineB.objType == TYPE_DIRECTORY) return true; else //use unformatted filesizes and sort by size return cmpLargeInt(gridDataLineA.fileSize, gridDataLineB.fileSize); @@ -2040,13 +2023,13 @@ void MainDialog::updateStatusInformation(const GridView& visibleGrid) const FileCompareLine& refLine = currentGridData[*i]; //calculate total number of bytes for each sied - if (refLine.fileDescrLeft.objType != isNothing) + if (refLine.fileDescrLeft.objType != TYPE_NOTHING) { filesizeLeftView+= refLine.fileDescrLeft.fileSize; ++objectsOnLeftView; } - if (refLine.fileDescrRight.objType != isNothing) + if (refLine.fileDescrRight.objType != TYPE_NOTHING) { filesizeRightView+= refLine.fileDescrRight.fileSize; ++objectsOnRightView; @@ -2094,28 +2077,38 @@ void MainDialog::mapGridDataToUI(GridView& output, const FileCompareResult& file { output.clear(); + //show only those view filter buttons that really need to be displayed + bool leftOnly, rightOnly, leftNewer, rightNewer, different, equal; + leftOnly = rightOnly = leftNewer = rightNewer = different = equal = false; + unsigned int currentRow = 0; for (FileCompareResult::const_iterator i = fileCmpResult.begin(); i != fileCmpResult.end(); ++i, ++currentRow) { //process UI filter settings switch (i->cmpResult) { - case fileOnLeftSideOnly: + case FILE_LEFT_SIDE_ONLY: + leftOnly = true; if (!leftOnlyFilesActive) continue; break; - case fileOnRightSideOnly: + case FILE_RIGHT_SIDE_ONLY: + rightOnly = true; if (!rightOnlyFilesActive) continue; break; - case rightFileNewer: - if (!rightNewerFilesActive) continue; - break; - case leftFileNewer: + case FILE_LEFT_NEWER: + leftNewer = true; if (!leftNewerFilesActive) continue; break; - case filesDifferent: + case FILE_RIGHT_NEWER: + rightNewer = true; + if (!rightNewerFilesActive) continue; + break; + case FILE_DIFFERENT: + different = true; if (!differentFilesActive) continue; break; - case filesEqual: + case FILE_EQUAL: + equal = true; if (!equalFilesActive) continue; break; default: @@ -2129,6 +2122,47 @@ void MainDialog::mapGridDataToUI(GridView& output, const FileCompareResult& file output.push_back(currentRow); } + //hide or enable view filter buttons + if (leftOnly) + m_bpButtonLeftOnly->Show(); + else + m_bpButtonLeftOnly->Hide(); + + if (rightOnly) + m_bpButtonRightOnly->Show(); + else + m_bpButtonRightOnly->Hide(); + + if (leftNewer) + m_bpButtonLeftNewer->Show(); + else + m_bpButtonLeftNewer->Hide(); + + if (rightNewer) + m_bpButtonRightNewer->Show(); + else + m_bpButtonRightNewer->Hide(); + + if (different) + m_bpButtonDifferent->Show(); + else + m_bpButtonDifferent->Hide(); + + if (equal) + m_bpButtonEqual->Show(); + else + m_bpButtonEqual->Hide(); + + if (leftOnly || rightOnly || leftNewer || rightNewer || different || equal) + { + m_panel12->Show(); + m_panel12->Layout(); + } + else + m_panel12->Hide(); + + bSizer3->Layout(); + //sorting is expensive: do performance measurements before implementing here! } //######################################################################################################## @@ -2150,12 +2184,12 @@ CompareStatusUpdater::CompareStatusUpdater(MainDialog* dlg) : mainDialog->m_dirPicker1->Disable(); mainDialog->m_dirPicker2->Disable(); mainDialog->m_bpButtonSwap->Disable(); - mainDialog->m_bpButton20->Disable(); - mainDialog->m_bpButton21->Disable(); - mainDialog->m_bpButton22->Disable(); - mainDialog->m_bpButton23->Disable(); - mainDialog->m_bpButton24->Disable(); - mainDialog->m_bpButton25->Disable(); + mainDialog->m_bpButtonLeftOnly->Disable(); + mainDialog->m_bpButtonLeftNewer->Disable(); + mainDialog->m_bpButtonEqual->Disable(); + mainDialog->m_bpButtonDifferent->Disable(); + mainDialog->m_bpButtonRightNewer->Disable(); + mainDialog->m_bpButtonRightOnly->Disable(); mainDialog->m_panel1->Disable(); mainDialog->m_panel2->Disable(); mainDialog->m_panel3->Disable(); @@ -2197,12 +2231,12 @@ CompareStatusUpdater::~CompareStatusUpdater() mainDialog->m_dirPicker1->Enable(); mainDialog->m_dirPicker2->Enable(); mainDialog->m_bpButtonSwap->Enable(); - mainDialog->m_bpButton20->Enable(); - mainDialog->m_bpButton21->Enable(); - mainDialog->m_bpButton22->Enable(); - mainDialog->m_bpButton23->Enable(); - mainDialog->m_bpButton24->Enable(); - mainDialog->m_bpButton25->Enable(); + mainDialog->m_bpButtonLeftOnly->Enable(); + mainDialog->m_bpButtonLeftNewer->Enable(); + mainDialog->m_bpButtonEqual->Enable(); + mainDialog->m_bpButtonDifferent->Enable(); + mainDialog->m_bpButtonRightNewer->Enable(); + mainDialog->m_bpButtonRightOnly->Enable(); mainDialog->m_panel1->Enable(); mainDialog->m_panel2->Enable(); mainDialog->m_panel3->Enable(); @@ -2323,24 +2357,29 @@ 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"; + result+= unhandledErrors[j] + wxT("\n"); + result+= wxT("\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); - //notify to syncStatusFrame that current process has ended if (abortionRequested) - syncStatusFrame->processHasFinished(SyncStatus::statusAborted); //enable okay and close events - else if (failedItems) - syncStatusFrame->processHasFinished(SyncStatus::statusCompletedWithErrors); + { + result+= wxString(_("Synchronization aborted!")) + _(" You may try to synchronize remaining items again (WITHOUT having to re-compare)!"); + syncStatusFrame->setStatusText_NoUpdate(result); + syncStatusFrame->processHasFinished(SyncStatus::ABORTED); //enable okay and close events + } + else if (failedItems) + { + result+= wxString(_("Synchronization completed with errors!")) + _(" You may try to synchronize remaining items again (WITHOUT having to re-compare)!"); + syncStatusFrame->setStatusText_NoUpdate(result); + syncStatusFrame->processHasFinished(SyncStatus::FINISHED_WITH_ERROR); + } else - syncStatusFrame->processHasFinished(SyncStatus::statusCompletedWithSuccess); + { + result+= _("Synchronization completed successfully."); + syncStatusFrame->setStatusText_NoUpdate(result); + syncStatusFrame->processHasFinished(SyncStatus::FINISHED_WITH_SUCCESS); + } } @@ -2356,7 +2395,7 @@ void SyncStatusUpdater::initNewProcess(int objectsTotal, double dataTotal, int p assert (processID == FreeFileSync::synchronizeFilesProcess); syncStatusFrame->resetGauge(objectsTotal, dataTotal); - syncStatusFrame->setCurrentStatus(SyncStatus::statusSynchronizing); + syncStatusFrame->setCurrentStatus(SyncStatus::SYNCHRONIZING); } @@ -2375,14 +2414,12 @@ int SyncStatusUpdater::reportError(const wxString& text) return StatusUpdater::continueNext; } - syncStatusFrame->updateStatusDialogNow(); - wxString errorMessage = text + _("\n\nContinue with next object, retry or abort synchronization?"); - ErrorDlg* errorDlg = new ErrorDlg(errorMessage, continueError); + syncStatusFrame->updateStatusDialogNow(); int rv = errorDlg->ShowModal(); - errorDlg->Destroy(); + errorDlg->Destroy(); //dialog is not connected to any window => needs to be deleted manually switch (rv) { @@ -2399,18 +2436,17 @@ int SyncStatusUpdater::reportError(const wxString& text) } default: assert (false); + return StatusUpdater::continueNext; } - - return StatusUpdater::continueNext; //dummy return value } void SyncStatusUpdater::triggerUI_Refresh() { if (abortionRequested) - throw AbortThisProcess(); //abort can be triggered by syncStatusFrame + throw AbortThisProcess(); //abort can be triggered by syncStatusFrame - if (updateUI_IsAllowed()) //test if specific time span between ui updates is over + if (updateUI_IsAllowed()) //test if specific time span between ui updates is over syncStatusFrame->updateStatusDialogNow(); } @@ -2421,15 +2457,15 @@ void SyncStatusUpdater::triggerUI_Refresh() void MainDialog::OnMenuExportFileList(wxCommandEvent& event) { //get a filename - wxString fileName = "FileList.csv"; //proposal - wxFileDialog* filePicker = new wxFileDialog(this, "", "", fileName, wxString(_("Comma separated list")) + " (*.csv)|*.csv", wxFD_SAVE); + wxString fileName = wxT("FileList.csv"); //proposal + wxFileDialog* filePicker = new wxFileDialog(this, wxEmptyString, wxEmptyString, fileName, wxString(_("Comma separated list")) + wxT(" (*.csv)|*.csv"), wxFD_SAVE); if (filePicker->ShowModal() == wxID_OK) { fileName = filePicker->GetPath(); if (wxFileExists(fileName)) { - wxMessageDialog* messageDlg = new wxMessageDialog(this, wxString("\"") + fileName + "\"" + _(" already exists. Overwrite?"), _("Warning") , wxOK | wxCANCEL); + wxMessageDialog* messageDlg = new wxMessageDialog(this, wxString(wxT("\"")) + fileName + wxT("\"") + _(" already exists. Overwrite?"), _("Warning") , wxOK | wxCANCEL); if (messageDlg->ShowModal() != wxID_OK) { @@ -2474,7 +2510,7 @@ void MainDialog::OnMenuExportFileList(wxCommandEvent& event) } else { - wxMessageBox(wxString(_("Could not write to ")) + "\"" + fileName + "\"", _("An exception occured!"), wxOK | wxICON_ERROR); + wxMessageBox(wxString(_("Could not write to ")) + wxT("\"") + fileName + wxT("\""), _("An exception occured!"), wxOK | wxICON_ERROR); } } diff --git a/ui/MainDialog.h b/ui/MainDialog.h index d60c489d..3bc4c590 100644 --- a/ui/MainDialog.h +++ b/ui/MainDialog.h @@ -26,10 +26,10 @@ using namespace std; //IDs for context menu items enum ContextItem { - contextManualFilter = 10, - contextCopyClipboard, - contextOpenExplorer, - contextDeleteFiles + CONTEXT_MANUAL_FILTER = 10, + CONTEXT_CLIPBOARD, + CONTEXT_EXPLORER, + CONTEXT_DELETE_FILES }; extern int leadingPanel; @@ -128,7 +128,6 @@ private: void OnSync( wxCommandEvent& event); void OnClose( wxCloseEvent& event); void OnQuit( wxCommandEvent& event); - void OnAbout( wxCommandEvent& event); //menu events void OnMenuExportFileList( wxCommandEvent& event); diff --git a/ui/SmallDialogs.cpp b/ui/SmallDialogs.cpp index 36c5cae4..3961e28a 100644 --- a/ui/SmallDialogs.cpp +++ b/ui/SmallDialogs.cpp @@ -13,8 +13,14 @@ AboutDlg::AboutDlg(wxWindow* window) : AboutDlgGenerated(window) m_bitmap11->SetBitmap(*GlobalResources::bitmapLogo); m_bitmap13->SetBitmap(*GlobalResources::bitmapGPL); - //build - wxString build = wxString(_("(Build: ")) + __TDATE__ + ")"; + //build information + wxString build = wxString(_("(Build: ")) + __TDATE__; +#if wxUSE_UNICODE + build+= wxT(" - Unicode"); +#else + build+= wxT(" - ANSI"); +#endif //wxUSE_UNICODE + build+= + wxT(")"); m_build->SetLabel(build); m_animationControl1->SetAnimation(*GlobalResources::animationMoney); @@ -219,9 +225,9 @@ RemainingTime::~RemainingTime() ofstream output("test.txt"); for (unsigned i = 0; i < x.size(); ++i) { - output<<x[i]<<" "<<f[i]<<endl; + output<<x[i]<<" "<<f[i]<<'\n'; } - output<<endl<<z_1<<" "<<z_2<<endl; + output<<'\n'<<z_1<<" "<<z_2<<'\n'; output.close(); } @@ -363,7 +369,7 @@ void SyncStatus::updateStatusDialogNow() //support for pause button while (processPaused && currentProcessIsRunning) { - wxMilliSleep(uiUpdateInterval); + wxMilliSleep(UI_UPDATE_INTERVAL); updateUI_Now(); } } @@ -373,37 +379,37 @@ void SyncStatus::setCurrentStatus(SyncStatusID id) { switch (id) { - case statusAborted: + case ABORTED: m_bitmapStatus->SetBitmap(*GlobalResources::bitmapStatusError); m_staticTextStatus->SetLabel(_("Aborted")); break; - case statusCompletedWithSuccess: + case FINISHED_WITH_SUCCESS: m_bitmapStatus->SetBitmap(*GlobalResources::bitmapStatusSuccess); m_staticTextStatus->SetLabel(_("Completed")); break; - case statusCompletedWithErrors: + case FINISHED_WITH_ERROR: m_bitmapStatus->SetBitmap(*GlobalResources::bitmapStatusWarning); m_staticTextStatus->SetLabel(_("Completed")); break; - case statusPause: + case PAUSE: m_bitmapStatus->SetBitmap(*GlobalResources::bitmapStatusPause); m_staticTextStatus->SetLabel(_("Pause")); break; - case statusScanning: + case SCANNING: m_bitmapStatus->SetBitmap(*GlobalResources::bitmapStatusComparing); m_staticTextStatus->SetLabel(_("Scanning...")); break; - case statusComparing: + case COMPARING: m_bitmapStatus->SetBitmap(*GlobalResources::bitmapStatusComparing); m_staticTextStatus->SetLabel(_("Comparing...")); break; - case statusSynchronizing: + case SYNCHRONIZING: m_bitmapStatus->SetBitmap(*GlobalResources::bitmapStatusSyncing); m_staticTextStatus->SetLabel(_("Synchronizing...")); break; diff --git a/ui/SmallDialogs.h b/ui/SmallDialogs.h index c6495c83..127947f6 100644 --- a/ui/SmallDialogs.h +++ b/ui/SmallDialogs.h @@ -86,18 +86,18 @@ private: class SyncStatus : public SyncStatusDlgGenerated { public: - SyncStatus(StatusUpdater* updater, wxWindow* parentWindow = 0); + SyncStatus(StatusUpdater* updater, wxWindow* parentWindow = NULL); ~SyncStatus(); enum SyncStatusID { - statusAborted, - statusCompletedWithSuccess, - statusCompletedWithErrors, - statusPause, - statusScanning, - statusComparing, - statusSynchronizing + ABORTED, + FINISHED_WITH_SUCCESS, + FINISHED_WITH_ERROR, + PAUSE, + SCANNING, + COMPARING, + SYNCHRONIZING }; void resetGauge(int totalObjectsToProcess, double totalDataToProcess); diff --git a/ui/SyncDialog.cpp b/ui/SyncDialog.cpp index c138544e..efe85553 100644 --- a/ui/SyncDialog.cpp +++ b/ui/SyncDialog.cpp @@ -2,8 +2,10 @@ #include "../library/globalFunctions.h" #include "../library/resources.h" #include <wx/msgdlg.h> -#include <wx/file.h> #include <wx/stdpaths.h> +#include <fstream> + +using namespace std; SyncDialog::SyncDialog(wxWindow* window, const FileCompareResult& gridDataRef, @@ -41,18 +43,18 @@ SyncDialog::SyncDialog(wxWindow* window, } //set radiobutton - if (localSyncConfiguration.exLeftSideOnly == syncDirRight && - localSyncConfiguration.exRightSideOnly == syncDirRight && - localSyncConfiguration.leftNewer == syncDirRight && - localSyncConfiguration.rightNewer == syncDirRight && - localSyncConfiguration.different == syncDirRight) + if (localSyncConfiguration.exLeftSideOnly == SYNC_DIR_RIGHT && + localSyncConfiguration.exRightSideOnly == SYNC_DIR_RIGHT && + localSyncConfiguration.leftNewer == SYNC_DIR_RIGHT && + localSyncConfiguration.rightNewer == SYNC_DIR_RIGHT && + localSyncConfiguration.different == SYNC_DIR_RIGHT) m_radioBtn1->SetValue(true); //one way -> - else if (localSyncConfiguration.exLeftSideOnly == syncDirRight && - localSyncConfiguration.exRightSideOnly == syncDirLeft && - localSyncConfiguration.leftNewer == syncDirRight && - localSyncConfiguration.rightNewer == syncDirLeft && - localSyncConfiguration.different == syncDirNone) + else if (localSyncConfiguration.exLeftSideOnly == SYNC_DIR_RIGHT && + localSyncConfiguration.exRightSideOnly == SYNC_DIR_LEFT && + localSyncConfiguration.leftNewer == SYNC_DIR_RIGHT && + localSyncConfiguration.rightNewer == SYNC_DIR_LEFT && + localSyncConfiguration.different == SYNC_DIR_NONE) m_radioBtn2->SetValue(true); //two way <-> else @@ -73,81 +75,81 @@ void SyncDialog::updateConfigIcons(wxBitmapButton* button1, wxBitmapButton* button5, const SyncConfiguration& syncConfig) { - if (syncConfig.exLeftSideOnly == syncDirRight) + if (syncConfig.exLeftSideOnly == SYNC_DIR_RIGHT) { button1->SetBitmapLabel(*GlobalResources::bitmapRightArrow); button1->SetToolTip(_("Copy from left to right")); } - else if (syncConfig.exLeftSideOnly == syncDirLeft) + else if (syncConfig.exLeftSideOnly == SYNC_DIR_LEFT) { button1->SetBitmapLabel(*GlobalResources::bitmapDelete); button1->SetToolTip(_("Delete files/folders existing on left side only")); } - else if (syncConfig.exLeftSideOnly == syncDirNone) + else if (syncConfig.exLeftSideOnly == SYNC_DIR_NONE) { button1->SetBitmapLabel(*GlobalResources::bitmapNoArrow); button1->SetToolTip(_("Do nothing")); } - if (syncConfig.exRightSideOnly == syncDirRight) + if (syncConfig.exRightSideOnly == SYNC_DIR_RIGHT) { button2->SetBitmapLabel(*GlobalResources::bitmapDelete); button2->SetToolTip(_("Delete files/folders existing on right side only")); } - else if (syncConfig.exRightSideOnly == syncDirLeft) + else if (syncConfig.exRightSideOnly == SYNC_DIR_LEFT) { button2->SetBitmapLabel(*GlobalResources::bitmapLeftArrow); button2->SetToolTip(_("Copy from right to left")); } - else if (syncConfig.exRightSideOnly == syncDirNone) + else if (syncConfig.exRightSideOnly == SYNC_DIR_NONE) { button2->SetBitmapLabel(*GlobalResources::bitmapNoArrow); button2->SetToolTip(_("Do nothing")); } - if (syncConfig.leftNewer == syncDirRight) + if (syncConfig.leftNewer == SYNC_DIR_RIGHT) { button3->SetBitmapLabel(*GlobalResources::bitmapRightArrow); button3->SetToolTip(_("Copy from left to right overwriting")); } - else if (syncConfig.leftNewer == syncDirLeft) + else if (syncConfig.leftNewer == SYNC_DIR_LEFT) { button3->SetBitmapLabel(*GlobalResources::bitmapLeftArrow); button3->SetToolTip(_("Copy from right to left overwriting")); } - else if (syncConfig.leftNewer == syncDirNone) + else if (syncConfig.leftNewer == SYNC_DIR_NONE) { button3->SetBitmapLabel(*GlobalResources::bitmapNoArrow); button3->SetToolTip(_("Do nothing")); } - if (syncConfig.rightNewer == syncDirRight) + if (syncConfig.rightNewer == SYNC_DIR_RIGHT) { button4->SetBitmapLabel(*GlobalResources::bitmapRightArrow); button4->SetToolTip(_("Copy from left to right overwriting")); } - else if (syncConfig.rightNewer == syncDirLeft) + else if (syncConfig.rightNewer == SYNC_DIR_LEFT) { button4->SetBitmapLabel(*GlobalResources::bitmapLeftArrow); button4->SetToolTip(_("Copy from right to left overwriting")); } - else if (syncConfig.rightNewer == syncDirNone) + else if (syncConfig.rightNewer == SYNC_DIR_NONE) { button4->SetBitmapLabel(*GlobalResources::bitmapNoArrow); button4->SetToolTip(_("Do nothing")); } - if (syncConfig.different == syncDirRight) + if (syncConfig.different == SYNC_DIR_RIGHT) { button5->SetBitmapLabel(*GlobalResources::bitmapRightArrow); button5->SetToolTip(_("Copy from left to right overwriting")); } - else if (syncConfig.different == syncDirLeft) + else if (syncConfig.different == SYNC_DIR_LEFT) { button5->SetBitmapLabel(*GlobalResources::bitmapLeftArrow); button5->SetToolTip(_("Copy from right to left overwriting")); } - else if (syncConfig.different == syncDirNone) + else if (syncConfig.different == SYNC_DIR_NONE) { button5->SetBitmapLabel(*GlobalResources::bitmapNoArrow); button5->SetToolTip(_("Do nothing")); @@ -233,11 +235,11 @@ void SyncDialog::OnSelectRecycleBin(wxCommandEvent& event) void SyncDialog::OnSyncLeftToRight(wxCommandEvent& event) { - localSyncConfiguration.exLeftSideOnly = syncDirRight; - localSyncConfiguration.exRightSideOnly = syncDirRight; - localSyncConfiguration.leftNewer = syncDirRight; - localSyncConfiguration.rightNewer = syncDirRight; - localSyncConfiguration.different = syncDirRight; + localSyncConfiguration.exLeftSideOnly = SYNC_DIR_RIGHT; + localSyncConfiguration.exRightSideOnly = SYNC_DIR_RIGHT; + localSyncConfiguration.leftNewer = SYNC_DIR_RIGHT; + localSyncConfiguration.rightNewer = SYNC_DIR_RIGHT; + localSyncConfiguration.different = SYNC_DIR_RIGHT; updateConfigIcons(m_bpButton5, m_bpButton6, m_bpButton7, m_bpButton8, m_bpButton9, localSyncConfiguration); calculatePreview(); @@ -249,11 +251,11 @@ void SyncDialog::OnSyncLeftToRight(wxCommandEvent& event) void SyncDialog::OnSyncBothSides(wxCommandEvent& event) { - localSyncConfiguration.exLeftSideOnly = syncDirRight; - localSyncConfiguration.exRightSideOnly = syncDirLeft; - localSyncConfiguration.leftNewer = syncDirRight; - localSyncConfiguration.rightNewer = syncDirLeft; - localSyncConfiguration.different = syncDirNone; + localSyncConfiguration.exLeftSideOnly = SYNC_DIR_RIGHT; + localSyncConfiguration.exRightSideOnly = SYNC_DIR_LEFT; + localSyncConfiguration.leftNewer = SYNC_DIR_RIGHT; + localSyncConfiguration.rightNewer = SYNC_DIR_LEFT; + localSyncConfiguration.different = SYNC_DIR_NONE; updateConfigIcons(m_bpButton5, m_bpButton6, m_bpButton7, m_bpButton8, m_bpButton9, localSyncConfiguration); calculatePreview(); @@ -265,12 +267,12 @@ void SyncDialog::OnSyncBothSides(wxCommandEvent& event) void toggleSyncDirection(SyncDirection& current) { - if (current == syncDirRight) - current = syncDirLeft; - else if (current == syncDirLeft) - current = syncDirNone; - else if (current== syncDirNone) - current = syncDirRight; + if (current == SYNC_DIR_RIGHT) + current = SYNC_DIR_LEFT; + else if (current == SYNC_DIR_LEFT) + current = SYNC_DIR_NONE; + else if (current== SYNC_DIR_NONE) + current = SYNC_DIR_RIGHT; else assert (false); } @@ -338,10 +340,10 @@ BatchDialog::BatchDialog(wxWindow* window, switch (config.compareVar) { - case compareByTimeAndSize: + case CMP_BY_TIME_SIZE: m_radioBtnSizeDate->SetValue(true); break; - case compareByContent: + case CMP_BY_CONTENT: m_radioBtnContent->SetValue(true); break; default: @@ -459,13 +461,32 @@ void BatchDialog::OnCancel(wxCommandEvent& event) void BatchDialog::OnCreateJob(wxCommandEvent& event) { + if (m_directoryPanel1->GetValue().IsEmpty() || m_directoryPanel2->GetValue().IsEmpty()) + { + wxMessageBox(_("Please select both left and right directories!"), _("Information")); + return; + } + + //check if directories exist if loaded by config file + if (!wxDirExists(m_directoryPanel1->GetValue())) + { + wxMessageBox(_("Left directory does not exist. Please select a new one!"), _("Warning"), wxICON_WARNING); + return; + } + else if (!wxDirExists(m_directoryPanel2->GetValue())) + { + wxMessageBox(_("Right directory does not exist. Please select a new one!"), _("Warning"), wxICON_WARNING); + return; + } + + //get a filename #ifdef FFS_WIN - wxString fileName = "SyncJob.cmd"; //proposal - wxFileDialog* filePicker = new wxFileDialog(this, "", "", fileName, wxString(_("Command file")) + " (*.cmd)|*.cmd", wxFD_SAVE); + wxString fileName = wxT("SyncJob.cmd"); //proposal + wxFileDialog* filePicker = new wxFileDialog(this, wxEmptyString, wxEmptyString, fileName, wxString(_("Command file")) + wxT(" (*.cmd)|*.cmd"), wxFD_SAVE); #elif defined FFS_LINUX - wxString fileName = "SyncJob.sh"; //proposal - wxFileDialog* filePicker = new wxFileDialog(this, "", "", fileName, wxString(_("Shell script")) + " (*.sh)|*.sh", wxFD_SAVE); + wxString fileName = wxT("SyncJob.sh"); //proposal + wxFileDialog* filePicker = new wxFileDialog(this, wxEmptyString, wxEmptyString, fileName, wxString(_("Shell script")) + wxT(" (*.sh)|*.sh"), wxFD_SAVE); #else assert(false); #endif @@ -475,7 +496,7 @@ void BatchDialog::OnCreateJob(wxCommandEvent& event) fileName = filePicker->GetPath(); if (wxFileExists(fileName)) { - wxMessageDialog* messageDlg = new wxMessageDialog(this, wxString("\"") + fileName + "\"" + _(" already exists. Overwrite?"), _("Warning") , wxOK | wxCANCEL); + wxMessageDialog* messageDlg = new wxMessageDialog(this, wxString(wxT("\"")) + fileName + wxT("\"") + _(" already exists. Overwrite?"), _("Warning") , wxOK | wxCANCEL); if (messageDlg->ShowModal() != wxID_OK) { @@ -488,19 +509,19 @@ void BatchDialog::OnCreateJob(wxCommandEvent& event) wxString outputString = parseConfiguration(); //write export file - wxFile output(fileName, wxFile::write); - if (output.IsOpened()) + ofstream output(fileName.c_str()); + if (output) { - output.Write(outputString); + output<<outputString.c_str(); EndModal(batchFileCreated); } else - wxMessageBox(wxString(_("Could not write to ")) + "\"" + fileName + "\"", _("An exception occured!"), wxOK | wxICON_ERROR); + wxMessageBox(wxString(_("Could not write to ")) + wxT("\"") + fileName + wxT("\""), _("An exception occured!"), wxOK | wxICON_ERROR); } #ifdef FFS_LINUX //for linux the batch file needs the executable flag - wxExecute(wxString("chmod +x ") + fileName); + wxExecute(wxString(wxT("chmod +x ")) + fileName); #endif // FFS_LINUX event.Skip(); @@ -509,11 +530,11 @@ void BatchDialog::OnCreateJob(wxCommandEvent& event) wxString getFormattedSyncDirection(const SyncDirection direction) { - if (direction == syncDirRight) + if (direction == SYNC_DIR_RIGHT) return 'R'; - else if (direction == syncDirLeft) + else if (direction == SYNC_DIR_LEFT) return 'L'; - else if (direction == syncDirNone) + else if (direction == SYNC_DIR_NONE) return 'N'; else { @@ -526,15 +547,14 @@ wxString getFormattedSyncDirection(const SyncDirection direction) wxString BatchDialog::parseConfiguration() { wxString output; - #ifdef FFS_LINUX //shell script identifier - output+= "#!/bin/bash\n"; + output+= wxT("#!/bin/bash\n"); #endif - output+= "\"" + wxStandardPaths::Get().GetExecutablePath() + "\""; + output+= wxString(wxT("\"")) + wxStandardPaths::Get().GetExecutablePath() + wxT("\""); - output+= wxString(" -") + GlobalResources::paramCompare + " "; + output+= wxString(wxT(" -")) + GlobalResources::paramCompare + wxT(" "); if (m_radioBtnSizeDate->GetValue()) output+= GlobalResources::valueSizeDate; else if (m_radioBtnContent->GetValue()) @@ -542,7 +562,7 @@ wxString BatchDialog::parseConfiguration() else assert(false); - output+= wxString(" -") + GlobalResources::paramCfg + " " + + output+= wxString(wxT(" -")) + GlobalResources::paramCfg + wxT(" ") + getFormattedSyncDirection(localSyncConfiguration.exLeftSideOnly) + getFormattedSyncDirection(localSyncConfiguration.exRightSideOnly) + getFormattedSyncDirection(localSyncConfiguration.leftNewer) + @@ -551,26 +571,26 @@ wxString BatchDialog::parseConfiguration() if (filterIsActive) { - output+= wxString(" -") + GlobalResources::paramInclude + " " + - "\"" + m_textCtrlInclude->GetValue() + "\""; + output+= wxString(wxT(" -")) + GlobalResources::paramInclude + wxT(" ") + + wxT("\"") + m_textCtrlInclude->GetValue() + wxT("\""); - output+= wxString(" -") + GlobalResources::paramExclude + " " + - "\"" + m_textCtrlExclude->GetValue() + "\""; + output+= wxString(wxT(" -")) + GlobalResources::paramExclude + wxT(" ") + + wxT("\"") + m_textCtrlExclude->GetValue() + wxT("\""); } if (m_checkBoxUseRecycler->GetValue()) - output+= wxString(" -") + GlobalResources::paramRecycler; + output+= wxString(wxT(" -")) + GlobalResources::paramRecycler; if (m_checkBoxContinueError->GetValue()) - output+= wxString(" -") + GlobalResources::paramContinueError; + output+= wxString(wxT(" -")) + GlobalResources::paramContinueError; if (m_checkBoxSilent->GetValue()) - output+= wxString(" -") + GlobalResources::paramSilent; + output+= wxString(wxT(" -")) + GlobalResources::paramSilent; - output+= wxString(" ") + "\"" + m_directoryPanel1->GetValue() + "\""; - output+= wxString(" ") + "\"" + m_directoryPanel2->GetValue() + "\""; + output+= wxString(wxT(" ")) + wxT("\"") + wxDir(m_directoryPanel1->GetValue()).GetName() + wxT("\""); //directory WITHOUT trailing path separator + output+= wxString(wxT(" ")) + wxT("\"") + wxDir(m_directoryPanel2->GetValue()).GetName() + wxT("\""); //needed since e.g. "C:\" isn't parsed correctly by commandline - output+= "\n"; + output+= wxT("\n"); return output; } diff --git a/ui/guiGenerated.cpp b/ui/guiGenerated.cpp index 56feba35..be1db069 100644 --- a/ui/guiGenerated.cpp +++ b/ui/guiGenerated.cpp @@ -72,7 +72,7 @@ GuiGenerated::GuiGenerated( wxWindow* parent, wxWindowID id, const wxString& tit bSizer6 = new wxBoxSizer( wxHORIZONTAL ); - bSizer6->Add( 40, 0, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer6->Add( 15, 0, 0, wxALIGN_CENTER_VERTICAL, 5 ); wxBoxSizer* bSizer30; bSizer30 = new wxBoxSizer( wxHORIZONTAL ); @@ -145,7 +145,7 @@ GuiGenerated::GuiGenerated( wxWindow* parent, wxWindowID id, const wxString& tit m_hyperlinkCfgFilter->SetNormalColour( wxColour( 0, 0, 255 ) ); m_hyperlinkCfgFilter->SetVisitedColour( wxColour( 0, 0, 255 ) ); - m_hyperlinkCfgFilter->SetBackgroundColour( wxColour( 128, 128, 150 ) ); + m_hyperlinkCfgFilter->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_APPWORKSPACE ) ); bSizer23->Add( m_hyperlinkCfgFilter, 0, wxALL, 5 ); @@ -172,7 +172,7 @@ GuiGenerated::GuiGenerated( wxWindow* parent, wxWindowID id, const wxString& tit bSizer6->Add( m_bpButtonSync, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - bSizer6->Add( 40, 0, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer6->Add( 15, 0, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); m_panel71->SetSizer( bSizer6 ); m_panel71->Layout(); @@ -340,16 +340,6 @@ GuiGenerated::GuiGenerated( wxWindow* parent, wxWindowID id, const wxString& tit m_panel4 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); bSizer3 = new wxBoxSizer( wxHORIZONTAL ); - m_bpButton11 = new wxBitmapButton( m_panel4, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 50,50 ), wxBU_AUTODRAW ); - m_bpButton11->SetToolTip( _("About") ); - - m_bpButton11->SetToolTip( _("About") ); - - bSizer3->Add( m_bpButton11, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - - bSizer3->Add( 0, 0, 1, wxEXPAND, 5 ); - wxBoxSizer* bSizer58; bSizer58 = new wxBoxSizer( wxVERTICAL ); @@ -371,85 +361,87 @@ GuiGenerated::GuiGenerated( wxWindow* parent, wxWindowID id, const wxString& tit sbSizer16->Add( m_choiceLoad, 0, wxALIGN_CENTER_VERTICAL, 5 ); - bSizer58->Add( sbSizer16, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer58->Add( sbSizer16, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); bSizer58->Add( 0, 4, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); - bSizer3->Add( bSizer58, 0, wxALIGN_CENTER_VERTICAL, 5 ); - + bSizer3->Add( bSizer58, 1, wxALIGN_CENTER_VERTICAL, 5 ); - bSizer3->Add( 0, 0, 1, wxEXPAND, 5 ); - - bSizer59 = new wxBoxSizer( wxVERTICAL ); + m_panel12 = new wxPanel( m_panel4, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer64; + bSizer64 = new wxBoxSizer( wxVERTICAL ); wxStaticBoxSizer* sbSizer31; - sbSizer31 = new wxStaticBoxSizer( new wxStaticBox( m_panel4, wxID_ANY, _("Filter view") ), wxHORIZONTAL ); - - m_bpButton20 = new wxBitmapButton( m_panel4, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); - m_bpButton20->SetToolTip( _("Files that exist on left view only") ); - - m_bpButton20->SetToolTip( _("Files that exist on left view only") ); + sbSizer31 = new wxStaticBoxSizer( new wxStaticBox( m_panel12, wxID_ANY, _("Filter view") ), wxHORIZONTAL ); - sbSizer31->Add( m_bpButton20, 0, wxALIGN_CENTER_VERTICAL, 5 ); + sbSizer31->SetMinSize( wxSize( 100,-1 ) ); - m_bpButton21 = new wxBitmapButton( m_panel4, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); - m_bpButton21->SetToolTip( _("Files that are newer on left") ); + sbSizer31->Add( 0, 0, 1, wxEXPAND, 5 ); - m_bpButton21->SetToolTip( _("Files that are newer on left") ); + m_bpButtonLeftOnly = new wxBitmapButton( m_panel12, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); + m_bpButtonLeftOnly->SetToolTip( _("Show files that exist on left side only") ); - sbSizer31->Add( m_bpButton21, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_bpButtonLeftOnly->SetToolTip( _("Show files that exist on left side only") ); - m_bpButton25 = new wxBitmapButton( m_panel4, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); - m_bpButton25->SetToolTip( _("Files that are equal") ); + sbSizer31->Add( m_bpButtonLeftOnly, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_bpButton25->SetToolTip( _("Files that are equal") ); + m_bpButtonLeftNewer = new wxBitmapButton( m_panel12, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); + m_bpButtonLeftNewer->SetToolTip( _("Show files that are newer on left") ); - sbSizer31->Add( m_bpButton25, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_bpButtonLeftNewer->SetToolTip( _("Show files that are newer on left") ); - m_bpButton22 = new wxBitmapButton( m_panel4, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); - m_bpButton22->SetToolTip( _("Files that are different") ); + sbSizer31->Add( m_bpButtonLeftNewer, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_bpButton22->SetToolTip( _("Files that are different") ); + m_bpButtonEqual = new wxBitmapButton( m_panel12, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); + m_bpButtonEqual->SetToolTip( _("Show files that are equal") ); - sbSizer31->Add( m_bpButton22, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_bpButtonEqual->SetToolTip( _("Show files that are equal") ); - m_bpButton23 = new wxBitmapButton( m_panel4, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); - m_bpButton23->SetToolTip( _("Files that are newer on right") ); + sbSizer31->Add( m_bpButtonEqual, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_bpButton23->SetToolTip( _("Files that are newer on right") ); + m_bpButtonDifferent = new wxBitmapButton( m_panel12, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); + m_bpButtonDifferent->SetToolTip( _("Show files that are different") ); - sbSizer31->Add( m_bpButton23, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_bpButtonDifferent->SetToolTip( _("Show files that are different") ); - m_bpButton24 = new wxBitmapButton( m_panel4, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); - m_bpButton24->SetToolTip( _("Files that exist on right view only") ); + sbSizer31->Add( m_bpButtonDifferent, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_bpButton24->SetToolTip( _("Files that exist on right view only") ); + m_bpButtonRightNewer = new wxBitmapButton( m_panel12, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); + m_bpButtonRightNewer->SetToolTip( _("Show files that are newer on right") ); - sbSizer31->Add( m_bpButton24, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_bpButtonRightNewer->SetToolTip( _("Show files that are newer on right") ); - bSizer59->Add( sbSizer31, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + sbSizer31->Add( m_bpButtonRightNewer, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_bpButtonRightOnly = new wxBitmapButton( m_panel12, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); + m_bpButtonRightOnly->SetToolTip( _("Show files that exist on right side only") ); - bSizer59->Add( 0, 4, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + m_bpButtonRightOnly->SetToolTip( _("Show files that exist on right side only") ); - bSizer3->Add( bSizer59, 0, wxALIGN_CENTER_VERTICAL, 5 ); + sbSizer31->Add( m_bpButtonRightOnly, 0, wxALIGN_CENTER_VERTICAL, 5 ); - bSizer3->Add( 0, 0, 1, wxEXPAND, 5 ); + sbSizer31->Add( 0, 0, 1, wxEXPAND, 5 ); + bSizer64->Add( sbSizer31, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 ); - bSizer3->Add( 185, 0, 0, wxALL, 5 ); + m_panel12->SetSizer( bSizer64 ); + m_panel12->Layout(); + bSizer64->Fit( m_panel12 ); + bSizer3->Add( m_panel12, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 4 ); - - bSizer3->Add( 0, 0, 1, wxEXPAND, 5 ); + wxBoxSizer* bSizer66; + bSizer66 = new wxBoxSizer( wxVERTICAL ); m_bpButton10 = new wxBitmapButton( m_panel4, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 50,50 ), wxBU_AUTODRAW ); m_bpButton10->SetToolTip( _("Quit") ); m_bpButton10->SetToolTip( _("Quit") ); - bSizer3->Add( m_bpButton10, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + bSizer66->Add( m_bpButton10, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 ); + + bSizer3->Add( bSizer66, 1, wxALIGN_CENTER_VERTICAL, 5 ); m_panel4->SetSizer( bSizer3 ); m_panel4->Layout(); @@ -552,16 +544,15 @@ GuiGenerated::GuiGenerated( wxWindow* parent, wxWindowID id, const wxString& tit m_grid2->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( GuiGenerated::OnRightGridDoubleClick ), NULL, this ); m_grid2->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( GuiGenerated::OnOpenContextMenu ), NULL, this ); m_grid2->Connect( wxEVT_GRID_LABEL_LEFT_CLICK, wxGridEventHandler( GuiGenerated::OnSortRightGrid ), NULL, this ); - m_bpButton11->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnAbout ), NULL, this ); m_bpButton201->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnSaveConfig ), NULL, this ); m_choiceLoad->Connect( wxEVT_CHAR, wxKeyEventHandler( GuiGenerated::OnChoiceKeyEvent ), NULL, this ); m_choiceLoad->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( GuiGenerated::OnLoadConfiguration ), NULL, this ); - m_bpButton20->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnLeftOnlyFiles ), NULL, this ); - m_bpButton21->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnLeftNewerFiles ), NULL, this ); - m_bpButton25->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnEqualFiles ), NULL, this ); - m_bpButton22->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnDifferentFiles ), NULL, this ); - m_bpButton23->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnRightNewerFiles ), NULL, this ); - m_bpButton24->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnRightOnlyFiles ), NULL, this ); + m_bpButtonLeftOnly->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnLeftOnlyFiles ), NULL, this ); + m_bpButtonLeftNewer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnLeftNewerFiles ), NULL, this ); + m_bpButtonEqual->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnEqualFiles ), NULL, this ); + m_bpButtonDifferent->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnDifferentFiles ), NULL, this ); + m_bpButtonRightNewer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnRightNewerFiles ), NULL, this ); + m_bpButtonRightOnly->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnRightOnlyFiles ), NULL, this ); m_bpButton10->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnQuit ), NULL, this ); } @@ -596,16 +587,15 @@ GuiGenerated::~GuiGenerated() m_grid2->Disconnect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( GuiGenerated::OnRightGridDoubleClick ), NULL, this ); m_grid2->Disconnect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( GuiGenerated::OnOpenContextMenu ), NULL, this ); m_grid2->Disconnect( wxEVT_GRID_LABEL_LEFT_CLICK, wxGridEventHandler( GuiGenerated::OnSortRightGrid ), NULL, this ); - m_bpButton11->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnAbout ), NULL, this ); m_bpButton201->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnSaveConfig ), NULL, this ); m_choiceLoad->Disconnect( wxEVT_CHAR, wxKeyEventHandler( GuiGenerated::OnChoiceKeyEvent ), NULL, this ); m_choiceLoad->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( GuiGenerated::OnLoadConfiguration ), NULL, this ); - m_bpButton20->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnLeftOnlyFiles ), NULL, this ); - m_bpButton21->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnLeftNewerFiles ), NULL, this ); - m_bpButton25->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnEqualFiles ), NULL, this ); - m_bpButton22->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnDifferentFiles ), NULL, this ); - m_bpButton23->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnRightNewerFiles ), NULL, this ); - m_bpButton24->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnRightOnlyFiles ), NULL, this ); + m_bpButtonLeftOnly->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnLeftOnlyFiles ), NULL, this ); + m_bpButtonLeftNewer->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnLeftNewerFiles ), NULL, this ); + m_bpButtonEqual->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnEqualFiles ), NULL, this ); + m_bpButtonDifferent->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnDifferentFiles ), NULL, this ); + m_bpButtonRightNewer->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnRightNewerFiles ), NULL, this ); + m_bpButtonRightOnly->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnRightOnlyFiles ), NULL, this ); m_bpButton10->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( GuiGenerated::OnQuit ), NULL, this ); } @@ -1245,7 +1235,7 @@ HelpDlgGenerated::HelpDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr bSizer20->Add( 0, 5, 0, wxEXPAND, 5 ); - m_textCtrl8 = new wxTextCtrl( this, wxID_ANY, _("Compare by \"File size and date\"\n----------------------------------------\nThis compare variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. For the latter the system's UTC time (coordinated word time) is used internally, although the local file time is displayed on the result list. So there are no problems concerning different time zones or daylight saving time.\n\nWhen \"Compare\" is triggered with this option set the following decision tree is processed:\n\n -----------------\n |Decision tree|\n -----------------\n ________|___________\n | |\n file exists on both sides on one side only\n _____|______ __|___\n | | | |\nequal different left right\n _________|_____________\n | | |\n left newer right newer different (but same date)\n\nAs a result 6 different status can be returned to categorize all files:\n\n- exists left only\n- exists right only\n- left newer\n- right newer\n- different (but same date)\n- equal\n\n\nCompare by \"File content\"\n----------------------------------------\nAs the name suggests, two files which share the same name are marked as equal if and only if they have the same content. This option is useful for consistency checks rather than backup operations. Therefore the file times are not taken into account at all.\n\nWith this option enabled the decision tree is smaller:\n\n -----------------\n |Decision tree|\n -----------------\n ________|___________\n | |\n file exists on both sides on one side only\n _____|______ __|___\n | | | |\nequal different left right\n\nAs a result the files are separated into the following categories:\n\n- exists left only\n- exists right only\n- different\n- equal"), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY ); + m_textCtrl8 = new wxTextCtrl( this, wxID_ANY, _("Compare by \"File size and date\"\n----------------------------------------\nThis variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. (Notice that the file time may deviate up to 2 seconds.)\n\nWhen \"Compare\" is triggered with this option set the following decision tree is processed:\n\n -----------------\n |Decision tree|\n -----------------\n ________|___________\n | |\n file exists on both sides on one side only\n _____|______ __|___\n | | | |\nequal different left right\n _________|_____________\n | | |\n left newer right newer different (but same date)\n\nAs a result 6 different status can be returned to categorize all files:\n\n- exists left only\n- exists right only\n- left newer\n- right newer\n- different (but same date)\n- equal\n\n\nCompare by \"File content\"\n----------------------------------------\nAs the name suggests, two files which share the same name are marked as equal if and only if they have the same content. This option is useful for consistency checks rather than backup operations. Therefore the file times are not taken into account at all.\n\nWith this option enabled the decision tree is smaller:\n\n -----------------\n |Decision tree|\n -----------------\n ________|___________\n | |\n file exists on both sides on one side only\n _____|______ __|___\n | | | |\nequal different left right\n\nAs a result the files are separated into the following categories:\n\n- exists left only\n- exists right only\n- different\n- equal"), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY ); m_textCtrl8->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVEBORDER ) ); bSizer20->Add( m_textCtrl8, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); diff --git a/ui/guiGenerated.h b/ui/guiGenerated.h index de725c92..d46d2959 100644 --- a/ui/guiGenerated.h +++ b/ui/guiGenerated.h @@ -89,22 +89,17 @@ class GuiGenerated : public wxFrame CustomGrid* m_grid2; wxPanel* m_panel4; wxBoxSizer* bSizer3; - wxBitmapButton* m_bpButton11; - wxBitmapButton* m_bpButton201; wxChoice* m_choiceLoad; + wxPanel* m_panel12; - wxBoxSizer* bSizer59; - wxBitmapButton* m_bpButton20; - wxBitmapButton* m_bpButton21; - wxBitmapButton* m_bpButton25; - wxBitmapButton* m_bpButton22; - wxBitmapButton* m_bpButton23; - wxBitmapButton* m_bpButton24; - - - + wxBitmapButton* m_bpButtonLeftOnly; + wxBitmapButton* m_bpButtonLeftNewer; + wxBitmapButton* m_bpButtonEqual; + wxBitmapButton* m_bpButtonDifferent; + wxBitmapButton* m_bpButtonRightNewer; + wxBitmapButton* m_bpButtonRightOnly; wxBitmapButton* m_bpButton10; wxPanel* m_panel7; @@ -148,7 +143,6 @@ class GuiGenerated : public wxFrame virtual void OnDirChangedPanel2( wxFileDirPickerEvent& event ){ event.Skip(); } virtual void OnRightGridDoubleClick( wxGridEvent& event ){ event.Skip(); } virtual void OnSortRightGrid( wxGridEvent& event ){ event.Skip(); } - virtual void OnAbout( wxCommandEvent& event ){ event.Skip(); } virtual void OnSaveConfig( wxCommandEvent& event ){ event.Skip(); } virtual void OnChoiceKeyEvent( wxKeyEvent& event ){ event.Skip(); } virtual void OnLoadConfiguration( wxCommandEvent& event ){ event.Skip(); } |