diff options
200 files changed, 6416 insertions, 6610 deletions
diff --git a/Application.cpp b/Application.cpp index 18eb2265..5b6fa2d8 100644 --- a/Application.cpp +++ b/Application.cpp @@ -26,14 +26,12 @@ #include "lib/lock_holder.h" #ifdef FFS_LINUX -#include <gtkmm/main.h> #include <gtk/gtk.h> #endif using namespace zen; using namespace xmlAccess; - IMPLEMENT_APP(Application) @@ -67,9 +65,9 @@ bool Application::OnInit() //Note: initialization is done in the FIRST idle event instead of OnInit. Reason: batch mode requires the wxApp eventhandler to be established //for UI update events. This is not the case at the time of OnInit(). - Connect(wxEVT_IDLE, wxIdleEventHandler(Application::OnStartApplication), NULL, this); - Connect(wxEVT_QUERY_END_SESSION, wxEventHandler (Application::OnQueryEndSession ), NULL, this); - Connect(wxEVT_END_SESSION, wxEventHandler (Application::OnQueryEndSession ), NULL, this); + Connect(wxEVT_IDLE, wxIdleEventHandler(Application::OnStartApplication), nullptr, this); + Connect(wxEVT_QUERY_END_SESSION, wxEventHandler (Application::OnQueryEndSession ), nullptr, this); + Connect(wxEVT_END_SESSION, wxEventHandler (Application::OnQueryEndSession ), nullptr, this); return true; } @@ -77,12 +75,12 @@ bool Application::OnInit() void Application::OnStartApplication(wxIdleEvent&) { - Disconnect(wxEVT_IDLE, wxIdleEventHandler(Application::OnStartApplication), NULL, this); + Disconnect(wxEVT_IDLE, wxIdleEventHandler(Application::OnStartApplication), nullptr, this); //wxWidgets app exit handling is quite weird... we want the app to exit only if the logical main window is closed wxTheApp->SetExitOnFrameDelete(false); //avoid popup-windows from becoming temporary top windows leading to program exit after closure wxApp* app = wxTheApp; - ZEN_ON_BLOCK_EXIT(if (!mainWindowWasSet()) app->ExitMainLoop();); //quit application, if no main window was set (batch silent mode) + ZEN_ON_SCOPE_EXIT(if (!mainWindowWasSet()) app->ExitMainLoop();); //quit application, if no main window was set (batch silent mode) //if appname is not set, the default is the executable's name! SetAppName(wxT("FreeFileSync")); @@ -93,9 +91,9 @@ void Application::OnStartApplication(wxIdleEvent&) ::SetErrorMode(SEM_FAILCRITICALERRORS); #elif defined FFS_LINUX - Gtk::Main::init_gtkmm_internals(); + gtk_init(nullptr, nullptr); - ::gtk_rc_parse((utf8CvrtTo<Zstring>(getResourceDir()) + "styles.rc").c_str()); //remove inner border from bitmap buttons + ::gtk_rc_parse((getResourceDir() + "styles.rc").c_str()); //remove inner border from bitmap buttons #endif @@ -126,100 +124,99 @@ void Application::OnStartApplication(wxIdleEvent&) setLanguage(globalSettings.programLanguage); - //test if FFS is to be started on UI with config file passed as commandline parameter - std::vector<wxString> commandArgs; - for (int i = 1; i < argc; ++i) + //determine FFS mode of operation + std::vector<wxString> commandArgs; //wxWidgets screws up once again making "argv implicitly convertible to a wxChar**" in 2.9.3, + for (int i = 1; i < argc; ++i) //so we are forced to use this pitiful excuse for a range construction!! commandArgs.push_back(argv[i]); - bool gotDirNames = false; - for (auto iter = commandArgs.begin(); iter != commandArgs.end(); ++iter) - { - Zstring filename = toZ(*iter); - - if (iter == commandArgs.begin() && dirExists(filename)) //detect which "mode" by testing first command line argument - { - gotDirNames = true; - break; - } - - if (!fileExists(filename)) //be a little tolerant - { - if (fileExists(filename + Zstr(".ffs_batch"))) - filename = filename + Zstr(".ffs_batch"); - else if (fileExists(filename + Zstr(".ffs_gui"))) - filename = filename + Zstr(".ffs_gui"); - else - { - wxMessageBox(_("File does not exist:") + L" \"" + filename + L"\"", _("Error"), wxOK | wxICON_ERROR); - return; - } - } - } - if (commandArgs.empty()) runGuiMode(commandArgs, globalSettings); - else if (gotDirNames) //mode 1: create temp configuration based on directory names passed + else { - XmlGuiConfig guiCfg; - guiCfg.mainCfg.syncCfg.directionCfg.var = DirectionConfig::MIRROR; - - for (auto iter = commandArgs.begin(); iter != commandArgs.end(); ++iter) + const bool gotDirNames = std::any_of(commandArgs.begin(), commandArgs.end(), [](const wxString& dirname) { return dirExists(toZ(dirname)); }); + if (gotDirNames) //mode 1: create temp configuration based on directory names passed { - size_t index = iter - commandArgs.begin(); - Zstring dirname = toZ(*iter); + XmlGuiConfig guiCfg; + guiCfg.mainCfg.syncCfg.directionCfg.var = DirectionConfig::MIRROR; - FolderPairEnh& fp = [&]() -> FolderPairEnh& + for (auto iter = commandArgs.begin(); iter != commandArgs.end(); ++iter) { - if (index < 2) - return guiCfg.mainCfg.firstPair; + size_t index = iter - commandArgs.begin(); + Zstring dirname = toZ(*iter); - guiCfg.mainCfg.additionalPairs.resize((index - 2) / 2 + 1); - return guiCfg.mainCfg.additionalPairs.back(); - }(); + FolderPairEnh& fp = [&]() -> FolderPairEnh& + { + if (index < 2) + return guiCfg.mainCfg.firstPair; - if (index % 2 == 0) - fp.leftDirectory = dirname; - else if (index % 2 == 1) - fp.rightDirectory = dirname; - } + guiCfg.mainCfg.additionalPairs.resize((index - 2) / 2 + 1); + return guiCfg.mainCfg.additionalPairs.back(); + }(); - runGuiMode(guiCfg, globalSettings); - } - else //mode 2: try to set config/batch-filename set by %1 parameter - switch (getMergeType(commandArgs)) //throw () - { - case MERGE_BATCH: //pure batch config files - if (commandArgs.size() == 1) - runBatchMode(commandArgs[0], globalSettings); - else - runGuiMode(commandArgs, globalSettings); - break; + if (index % 2 == 0) + fp.leftDirectory = dirname; + else if (index % 2 == 1) + fp.rightDirectory = dirname; + } - case MERGE_GUI: //pure gui config files - case MERGE_GUI_BATCH: //gui and batch files - runGuiMode(commandArgs, globalSettings); - break; + runGuiMode(guiCfg, globalSettings); + } + else //mode 2: try to set config/batch-filename set by %1 parameter + { + for (auto iter = commandArgs.begin(); iter != commandArgs.end(); ++iter) + { + wxString& filename = *iter; - case MERGE_OTHER: //= none or unknown; - //commandArgs are not empty and contain at least one non-gui/non-batch config file: find it! - std::find_if(commandArgs.begin(), commandArgs.end(), - [](const wxString& filename) -> bool + if (!fileExists(toZ(filename))) //be a little tolerant { - switch (getXmlType(filename)) //throw() + if (fileExists(toZ(filename) + Zstr(".ffs_batch"))) + filename += L".ffs_batch"; + else if (fileExists(toZ(filename) + Zstr(".ffs_gui"))) + filename += L".ffs_gui"; + else { - case XML_TYPE_GLOBAL: - case XML_TYPE_OTHER: - wxMessageBox(wxString(_("The file does not contain a valid configuration:")) + wxT(" \"") + filename + wxT("\""), _("Error"), wxOK | wxICON_ERROR); - return true; - - case XML_TYPE_GUI: - case XML_TYPE_BATCH: - break; + wxMessageBox(_("File does not exist:") + L" \"" + filename + L"\"", _("Error"), wxOK | wxICON_ERROR); + return; } - return false; - }); - break; + } + } + + switch (getMergeType(commandArgs)) //throw () + { + case MERGE_BATCH: //pure batch config files + if (commandArgs.size() == 1) + runBatchMode(commandArgs[0], globalSettings); + else + runGuiMode(commandArgs, globalSettings); + break; + + case MERGE_GUI: //pure gui config files + case MERGE_GUI_BATCH: //gui and batch files + runGuiMode(commandArgs, globalSettings); + break; + + case MERGE_OTHER: //= none or unknown; + //commandArgs are not empty and contain at least one non-gui/non-batch config file: find it! + std::find_if(commandArgs.begin(), commandArgs.end(), + [](const wxString& filename) -> bool + { + switch (getXmlType(filename)) //throw() + { + case XML_TYPE_GLOBAL: + case XML_TYPE_OTHER: + wxMessageBox(wxString(_("The file does not contain a valid configuration:")) + wxT(" \"") + filename + wxT("\""), _("Error"), wxOK | wxICON_ERROR); + return true; + + case XML_TYPE_GUI: + case XML_TYPE_BATCH: + break; + } + return false; + }); + break; + } } + } } @@ -238,18 +235,18 @@ int Application::OnRun() catch (const std::exception& e) //catch all STL exceptions { //unfortunately it's not always possible to display a message box in this erroneous situation, however (non-stream) file output always works! - wxFile safeOutput(toWx(getConfigDir()) + wxT("LastError.txt"), wxFile::write); - safeOutput.Write(wxString::FromAscii(e.what())); + wxFile safeOutput(toWx(getConfigDir()) + L"LastError.txt", wxFile::write); + safeOutput.Write(utf8CvrtTo<wxString>(e.what())); - wxSafeShowMessage(_("An exception occurred!") + L" - FFS", wxString::FromAscii(e.what())); + wxSafeShowMessage(_("An exception occurred!") + L" - FFS", utf8CvrtTo<wxString>(e.what())); return -9; } catch (...) //catch the rest { - wxFile safeOutput(toWx(getConfigDir()) + wxT("LastError.txt"), wxFile::write); + wxFile safeOutput(toWx(getConfigDir()) + L"LastError.txt", wxFile::write); safeOutput.Write(wxT("Unknown exception!")); - wxSafeShowMessage(_("An exception occurred!"), wxT("Unknown exception!")); + wxSafeShowMessage(_("An exception occurred!"), L"Unknown exception!"); return -9; } @@ -279,9 +276,7 @@ int Application::OnExit() void Application::OnQueryEndSession(wxEvent& event) { //alas wxWidgets screws up once again: http://trac.wxwidgets.org/ticket/3069 - - MainDialog* mainWin = dynamic_cast<MainDialog*>(GetTopWindow()); - if (mainWin) + if (auto mainWin = dynamic_cast<MainDialog*>(GetTopWindow())) mainWin->onQueryEndSession(); OnExit(); //wxEntryCleanup(); -> gives popup "dll init failed" on XP diff --git a/BUILD/Changelog.txt b/BUILD/Changelog.txt index 0fca0d39..95f324da 100644 --- a/BUILD/Changelog.txt +++ b/BUILD/Changelog.txt @@ -2,6 +2,42 @@ |FreeFileSync| -------------- +Changelog v5.1 +-------------- +New category for time span filter: last x days +Fixed "Error loading library function: GetVolumeInformationByHandleW" if NTFS permissions are copied +Fixed command line issues: allow config name without extension, allow multiple directories instead of a config file +Reenabled global shortcut F8 to toggle data shown in middle grid +Unified error handling on failure to create log directory +Do not close batch creation dialog after save +Tree view: compress and filter root nodes the same way as regular folder nodes +Fixed wrong tooltip being shown if directory name changes +Date range selector does not trim year field anymore +Show action "do nothing" on mouse-hover for conflicts in middle grid +Fixed "Windows Error Code 59: An unexpected network error occurred" +New filter pattern: *\* matches all files in subdirectories of base directories +Fixed "*?" filter sub-sequence +Fixed "Cannot convert from the charset 'Unknown encoding (-1)'!" +Support Ctrl + A in filter dialog +Support large filter lists > 32 kByte +Allow to hide file icons +Avoid switching monitor when main dialog is maximized on multiple monitor systems +Improved huge XML files loading times by a factor of 3000, saving by a factor of 3 +Restore grid scroll position after repeated comparisons +Show log after sync when non-fatal errors occurred +Fixed crash in UTF8 conversion when processing a corrupted ffs_db file +Even more pedantic user interface fine-tuning +Compiles and runs on openSuse 12.1 +Fixed grid page-up/down keys scrolling twice (Linux, wxGTK 2.9.3) +Fixed unwanted grid scrolling when toggling middle column (Linux, wxGTK 2.9.3) +Fixed middle grid tooltip occasionally going blank (Linux) +Support single shift-click to check/set direction of multiple rows +Removed gtkmm dependency (Linux) +Installer remembers all settings for next installation (local installation only) +All executables digitally signed +Updated translation files + + Changelog v5.0 -------------- New grid control diff --git a/BUILD/FreeFileSync.chm b/BUILD/FreeFileSync.chm Binary files differindex 9f4bc7d9..5a59e94d 100644 --- a/BUILD/FreeFileSync.chm +++ b/BUILD/FreeFileSync.chm diff --git a/BUILD/Help/FreeFileSync.hhp b/BUILD/Help/FreeFileSync.hhp index 9e2bffc1..4f2effed 100644 --- a/BUILD/Help/FreeFileSync.hhp +++ b/BUILD/Help/FreeFileSync.hhp @@ -10,7 +10,6 @@ Title=FreeFileSync - Help [FILES] -html\Features.html html\Links.html html\CompareFileSize.html html\ExcludeSubfolder.html diff --git a/BUILD/Help/Table of Contents.hhc b/BUILD/Help/Table of Contents.hhc index 742ec77f..3dad4ac0 100644 --- a/BUILD/Help/Table of Contents.hhc +++ b/BUILD/Help/Table of Contents.hhc @@ -52,10 +52,6 @@ <param name="Local" value="html\ExternalApp.html"> </OBJECT> <LI> <OBJECT type="text/sitemap"> - <param name="Name" value="Features"> - <param name="Local" value="html\Features.html"> - </OBJECT> - <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Macros"> <param name="Local" value="html\Macros.html"> </OBJECT> diff --git a/BUILD/Help/html/ComparisonSettings.html b/BUILD/Help/html/ComparisonSettings.html index 15fffaaf..7af12727 100644 --- a/BUILD/Help/html/ComparisonSettings.html +++ b/BUILD/Help/html/ComparisonSettings.html @@ -5,7 +5,7 @@ <TITLE></TITLE> <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.2 (Win32)"> <META NAME="CREATED" CONTENT="20091206;16574000"> - <META NAME="CHANGED" CONTENT="20111117;19373200"> + <META NAME="CHANGED" CONTENT="20120227;12315700"> <META NAME="Info 1" CONTENT=""> <META NAME="Info 2" CONTENT=""> <META NAME="Info 3" CONTENT=""> @@ -29,9 +29,9 @@ Settings</FONT></H3> <H3 CLASS="western" STYLE="page-break-after: avoid"><FONT FACE="Tahoma, sans-serif">I. Compare by "File time and size"</FONT></H3> <P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">This -variant evaluates two equally named files as being equal when they -have the same modification time <B>and</B> file size. When the -comparison is started, the following decision tree is processed:</FONT></P> +variant considers two files with the same name as equal when +modification time <B>and</B> file size match. The following cases are +distinguished:</FONT></P> <OL TYPE=i> <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>file exists on one side only</B></FONT></P> @@ -63,8 +63,6 @@ comparison is started, the following decision tree is processed:</FONT></P> </UL> </OL> </OL> -<P STYLE="margin-bottom: 0cm"><BR> -</P> <P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">This results into the following categories:</FONT></P> <UL> @@ -85,10 +83,10 @@ results into the following categories:</FONT></P> <H3 CLASS="western" STYLE="page-break-after: avoid"><FONT FACE="Tahoma, sans-serif">II. Compare by "File content"</FONT></H3> <P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Two -files which have the same name are marked as equal if and only if -they have the same content. This option is more useful for -consistency checks rather than backup operations for reasons of -speed. The file modification time is not taken into account at all.</FONT></P> +files with the same name are marked as equal if and only if they have +the same content. This option is more useful for consistency checks +rather than backup operations since it is naturally slower. The file +modification time is not taken into account at all.</FONT></P> <OL TYPE=i> <LI VALUE=1><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>file exists on one side only</B></FONT></P> @@ -128,23 +126,21 @@ handling</FONT></H3> <P STYLE="margin-bottom: 0cm"><BR> </P> <P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">FreeFileSync -offers three options to configure processing of symbolic links (also +offers three options to configure handling of symbolic links (also called symlinks or soft links):</FONT></P> <OL> <LI><P STYLE="margin-bottom: 0cm"><SPAN STYLE="text-decoration: none"><FONT FACE="Tahoma, sans-serif"><SPAN STYLE="font-style: normal"><B>Exclude:</B></SPAN></FONT></SPAN> - <FONT FACE="Tahoma, sans-serif">skips symbolic links while scanning - input directories.<BR></FONT> </P> + S<FONT FACE="Tahoma, sans-serif">kip symbolic links while scanning + directories.<BR></FONT> </P> <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Direct:</B></FONT> - <FONT FACE="Tahoma, sans-serif">configures synchronization of the - symbolic link object itself and not its target. symbolic links will - be visible on main grid as a separate entity with corresponding meta - data. Links pointing to directories are not traversed and the link - object is copied directly during synchronization. <BR></FONT> </P> + <FONT FACE="Tahoma, sans-serif">Evaluate the symbolic link object + directly. Symbolic links will be shown as a separate entity on grid. + Links pointing to directories are not traversed and the link object + is copied directly during synchronization. <BR></FONT> </P> <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><SPAN STYLE="font-style: normal"><B>Follow:</B></SPAN> - dereferences symbolic links, i.e. they are treated like their target - objects. Links pointing to directories are traversed like ordinary - folders and the target of each link is copied during - synchronization.</FONT></P> + Treat symbolic links like the object they are pointing to. Links + pointing to directories are traversed like ordinary directories and + the target of each link is copied during synchronization.</FONT></P> </OL> <P STYLE="margin-bottom: 0cm"><BR> </P> @@ -153,15 +149,12 @@ called symlinks or soft links):</FONT></P> <FONT FACE="Tahoma, sans-serif"><B>Note:</B></FONT></P> <UL> <LI><P ALIGN=LEFT STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">In - Windows the options described above always apply to </FONT><FONT FACE="Tahoma, sans-serif"><I>"Reparse + Windows the symbolic link options apply to </FONT><FONT FACE="Tahoma, sans-serif"><I>"Reparse Points"</I></FONT><FONT FACE="Tahoma, sans-serif">. Reparse - Points are a more general concept including for example symbolic - links, junctions and mount points. The term </FONT><FONT FACE="Tahoma, sans-serif"><I>"symbolic - link" </I></FONT><FONT FACE="Tahoma, sans-serif"><SPAN STYLE="font-style: normal">has - been retained nevertheless for harmonization with Linux.</SPAN></FONT></P> + Points are a more general concept including symbolic links, + junctions and mount points.</FONT></P> <LI><P ALIGN=LEFT STYLE="margin-bottom: 0cm; font-style: normal"><FONT FACE="Tahoma, sans-serif">Copying - symbolic links requires the application to be started with - administrator rights.</FONT></P> + symbolic links requires administrator rights.</FONT></P> </UL> </SPAN><BR CLEAR=LEFT><BR> </P> diff --git a/BUILD/Help/html/ExcludeSubfolder.html b/BUILD/Help/html/ExcludeSubfolder.html index 49215730..c3261463 100644 --- a/BUILD/Help/html/ExcludeSubfolder.html +++ b/BUILD/Help/html/ExcludeSubfolder.html @@ -5,7 +5,7 @@ <TITLE></TITLE> <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.2 (Win32)"> <META NAME="CREATED" CONTENT="20091206;16574000"> - <META NAME="CHANGED" CONTENT="20110912;13300400"> + <META NAME="CHANGED" CONTENT="20120323;22023000"> <META NAME="Info 1" CONTENT=""> <META NAME="Info 2" CONTENT=""> <META NAME="Info 3" CONTENT=""> @@ -24,29 +24,30 @@ </HEAD> <BODY LANG="en-US" DIR="LTR"> <H3 CLASS="western"><FONT FACE="Tahoma, sans-serif">Exclude files</FONT></H3> -<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Excluding -files and directories works by specifying a phrase that is compared -against a file or directory path. Only if the file or directory -matches at least one entry in the include list and none of the -entries in the exclude list it passes filtering. The phrase is also a -file or directory name, but it must be relative to the base -sync-directory and may additionally include wild cards like '*' or -'?'.</FONT></P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Files +and directories can be excluded from synchronization by specifying +include and exclude filter lists. Only if they match at least one +entry in the include list and none of the entries in the exclude list +they pass filtering. Each list item is a file or directory path +relative to synchronization base directories. Optionally wild cards +like '*' or '?' may be used.</FONT></P> <P STYLE="margin-bottom: 0cm"><BR> </P> <P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Example:</B> -<SPAN STYLE="font-weight: normal">Exclude all sub directories</SPAN></FONT></P> +Exclude all files and folders located in subdirectories of base +directories</FONT></P> <P STYLE="margin-left: 1.32cm; margin-bottom: 0cm"><SPAN ID="Rahmen5" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: none; padding: 0cm; background: #e6e6e6"> <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-right: 0.98cm; margin-bottom: 0cm"> - <FONT FACE="Tahoma, sans-serif">Include: <FONT FACE="Courier New, monospace">*</FONT><BR>Exclude: - <FONT FACE="Courier New, monospace">*\</FONT></FONT></P> + <FONT FACE="Tahoma, sans-serif">Exclude: <FONT FACE="Courier New, monospace">*\*</FONT></FONT></P> </SPAN><BR CLEAR=LEFT><BR> </P> -<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">This -will exclude all objects within the two directories that end with a -'</FONT><FONT FACE="Courier New, monospace">\</FONT><FONT FACE="Tahoma, sans-serif">' -character, which is interpreted as the end of a directory name.</FONT></P> -<P STYLE="margin-bottom: 0cm"><BR> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Example:</B> +Include only <SPAN STYLE="font-weight: normal">files and folders +located in subdirectories of base directories</SPAN></FONT></P> +<P STYLE="margin-left: 1.32cm; margin-bottom: 0cm"><SPAN ID="Rahmen2" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: none; padding: 0cm; background: #e6e6e6"> + <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-right: 0.98cm; margin-bottom: 0cm"> + <FONT FACE="Tahoma, sans-serif">Include: <FONT FACE="Courier New, monospace">*\*</FONT></FONT></P> +</SPAN><BR CLEAR=LEFT><BR> </P> <P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Example:</B> <SPAN STYLE="font-weight: normal">Mirror-sync from </SPAN><FONT FACE="Courier New, monospace"><SPAN STYLE="font-weight: normal">C:\Source</SPAN></FONT> @@ -61,15 +62,16 @@ character, which is interpreted as the end of a directory name.</FONT></P> <P STYLE="margin-left: 0.82cm; margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><SPAN STYLE="font-weight: normal">Exclude all </SPAN></FONT><FONT FACE="Courier New, monospace"><SPAN STYLE="font-weight: normal">*.tmp</SPAN></FONT> <FONT FACE="Tahoma, sans-serif"><SPAN STYLE="font-weight: normal">files - located in </SPAN></FONT><FONT FACE="Courier New, monospace"><SPAN STYLE="font-weight: normal">subfolder</SPAN></FONT><FONT FACE="Tahoma, sans-serif"><SPAN STYLE="font-weight: normal"> - only:<BR></SPAN></FONT> <FONT FACE="Tahoma, sans-serif"><SPAN STYLE="font-weight: normal">Filter: + located in </SPAN></FONT><FONT FACE="Courier New, monospace"><SPAN STYLE="font-weight: normal">subfolder</SPAN></FONT> + <FONT FACE="Tahoma, sans-serif"><SPAN STYLE="font-weight: normal">only:<BR></SPAN></FONT> <FONT FACE="Tahoma, sans-serif"><SPAN STYLE="font-weight: normal">Filter: </SPAN></FONT><FONT FACE="Courier New, monospace">\sample\subfolder\*.tmp</FONT></P> <P STYLE="margin-left: 0.82cm; margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><SPAN STYLE="font-weight: normal">Exclude - files (and folders) named </SPAN></FONT><FONT FACE="Courier New, monospace"><SPAN STYLE="font-weight: normal">thumbs.db</SPAN></FONT><FONT FACE="Tahoma, sans-serif"><SPAN STYLE="font-weight: normal"> - in all sub directories:<BR></SPAN></FONT> <FONT FACE="Tahoma, sans-serif"><SPAN STYLE="font-weight: normal">Filter: + files (and folders) named </SPAN></FONT><FONT FACE="Courier New, monospace"><SPAN STYLE="font-weight: normal">thumbs.db</SPAN></FONT> + <FONT FACE="Tahoma, sans-serif"><SPAN STYLE="font-weight: normal">in + all directories:<BR></SPAN></FONT> <FONT FACE="Tahoma, sans-serif"><SPAN STYLE="font-weight: normal">Filter: </SPAN></FONT><FONT FACE="Courier New, monospace">*\thumbs.db</FONT></P> <P STYLE="margin-left: 0.82cm; margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><SPAN STYLE="font-weight: normal">Exclude - all files and folders that have </SPAN></FONT><FONT FACE="Courier New, monospace"><SPAN STYLE="font-weight: normal">test</SPAN></FONT> + files and folders that have </SPAN></FONT><FONT FACE="Courier New, monospace"><SPAN STYLE="font-weight: normal">test</SPAN></FONT> <FONT FACE="Tahoma, sans-serif"><SPAN STYLE="font-weight: normal">as part of their name:<BR></SPAN></FONT> <FONT FACE="Tahoma, sans-serif"><SPAN STYLE="font-weight: normal">Filter: </SPAN></FONT><FONT FACE="Courier New, monospace">*test*</FONT></P> @@ -83,24 +85,17 @@ character, which is interpreted as the end of a directory name.</FONT></P> </P> <P STYLE="margin-left: 1.46cm; margin-bottom: 0cm"><SPAN ID="Rahmen3" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: 1px solid #000080; padding: 0.05cm; background: #ccccff"> <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-right: 0.98cm; margin-bottom: 0cm"> - <FONT FACE="Tahoma, sans-serif"><B>Note:</B><BR>A filter phrase - „<FONT FACE="Courier New, monospace">\fileOrDir”</FONT> - matches both a file or a directory named „<FONT FACE="Courier New, monospace">fileOrDir”</FONT>. - In most cases there is no need to distinguish between a phrase to be - used for files or directories. In cases where it is clear you want - to process directories only, you can give a hint by adding a - backslash: „<FONT FACE="Courier New, monospace">\fileOrDir\”</FONT>. - Now this filter will be matched against directories only.</FONT></P> -</SPAN><BR CLEAR=LEFT><BR> -</P> -<P STYLE="margin-bottom: 0cm"><BR> -</P> -<P STYLE="margin-left: 1.46cm; margin-bottom: 0cm"><SPAN ID="Rahmen4" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: 1px solid #000080; padding: 0.05cm; background: #ccccff"> - <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-right: 0.98cm; margin-bottom: 0cm"> - <FONT FACE="Tahoma, sans-serif"><B>Note:</B><BR>In most cases - manually specifying a filter phrase is not necessary! You can - exclude files, directories and even complete lists of both directly - on main grid via context menu.</FONT></P> + <FONT FACE="Tahoma, sans-serif"><B>Note:</B></FONT></P> + <UL> + <LI><P ALIGN=LEFT STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">A + filter string is generally compared against both file and directory + names. If you want to consider directories only, you can give a + hint by appending a path separator: "<FONT FACE="Courier New, monospace">string\</FONT>".</FONT></P> + <LI><P ALIGN=LEFT STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">In + most cases manually specifying a filter phrase is not necessary! + You can exclude files, directories and even complete lists of both + directly on main grid via context menu.</FONT></P> + </UL> </SPAN><BR CLEAR=LEFT><BR> </P> </BODY> diff --git a/BUILD/Help/html/Features.html b/BUILD/Help/html/Features.html deleted file mode 100644 index 4b404317..00000000 --- a/BUILD/Help/html/Features.html +++ /dev/null @@ -1,92 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<HTML> -<HEAD> - <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> - <TITLE></TITLE> - <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.2 (Win32)"> - <META NAME="CREATED" CONTENT="20091206;16574000"> - <META NAME="CHANGED" CONTENT="20111121;19582100"> - <STYLE TYPE="text/css"> - <!-- - @page { margin: 2cm } - P { margin-bottom: 0.21cm } - H3 { margin-bottom: 0.21cm } - H3.western { font-family: "Arial", sans-serif } - H3.cjk { font-family: "MS Mincho" } - H3.ctl { font-family: "Mangal" } - A:link { so-language: zxx } - --> - </STYLE> -</HEAD> -<BODY LANG="de-DE" DIR="LTR"> -<H3 CLASS="western"><FONT FACE="Tahoma, sans-serif">Key Features</FONT></H3> -<OL> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Detection - of moved and renamed files</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Copy - locked files using Windows Volume Shadow Copy Service. (Windows - only)</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Support - for multiple folder pairs with distinct configuration</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Compare - files (bytewise or by date) and synchronize them.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Create - Batch Jobs for automated synchronization with or without GUI.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Optimized - performance, coded in C++ completely.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Native - 32 and 64 bit builds</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Transactional - file copy</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Synchronization - database for propagation of deleted files and conflict detection</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Cross-Platform</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Full - support for Windows/Linux Symbolic Links and Windows Junction - Points.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Full - unicode support.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Full - network support.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Built-in - support for very long filenames (more than MAX_PATH = 260 - characters).</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Copy - NTFS alternate data streams, compressed and encrypted file - attributes</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Lean - & easily accessible UI: only useful functionality, no feature - bloat.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Support - for filesizes larger than 4 GB.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Option - to move files to Recycle Bin instead of deleting/overwriting them.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Ignore - directories "\RECYCLER" and "\System Volume - Information" with default filter. (Windows only)</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Delete - before copy: Avoid disc space shortages for large sync-jobs.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Filter - functionality to include/exclude files from synchronization.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Automatically - handle daylight saving time changes on FAT/FAT32 volumes.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Portable - version available (selectable via installer).</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Opt-in - for automatic online update.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Localized - versions are available for many languages.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Create - recurring backups with macros %time%, %date% within directory names</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Copy - file create/modification times when synchronizing.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Advanced - locking strategy to allow multiple synchronization processes (e.g. - multiple writers, same network share).</FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Case-sensitive - synchronization of file, directory and symlink names</FONT></P> -</OL> -<P STYLE="margin-bottom: 0cm"><BR> -</P> -</BODY> -</HTML>
\ No newline at end of file diff --git a/BUILD/Help/html/FreeFileSync.html b/BUILD/Help/html/FreeFileSync.html index 762445b4..fe9457ad 100644 --- a/BUILD/Help/html/FreeFileSync.html +++ b/BUILD/Help/html/FreeFileSync.html @@ -5,7 +5,7 @@ <TITLE></TITLE> <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.2 (Win32)"> <META NAME="CREATED" CONTENT="20091206;16574000"> - <META NAME="CHANGED" CONTENT="20110903;14244700"> + <META NAME="CHANGED" CONTENT="20120229;11541300"> <META NAME="Info 1" CONTENT=""> <META NAME="Info 2" CONTENT=""> <META NAME="Info 3" CONTENT=""> @@ -13,7 +13,6 @@ <STYLE TYPE="text/css"> <!-- @page { margin: 2cm } - TD P { margin-bottom: 0.21cm } P { margin-bottom: 0.21cm } H3 { margin-bottom: 0.21cm } H3.western { font-family: "Arial", sans-serif } @@ -33,7 +32,7 @@ Folder Comparison and Synchronization -</SPAN></I></FONT></H3> left and right directories.<BR></FONT><IMG SRC="../img/SourceTarget.png" NAME="Grafik4" ALIGN=TEXTTOP WIDTH=427 HEIGHT=52 BORDER=0></P> <P STYLE="margin-bottom: 0cm"> </P> <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">"</FONT><FONT FACE="Tahoma, sans-serif"><I>Compare</I></FONT><FONT FACE="Tahoma, sans-serif">" - them.<BR></FONT><IMG SRC="../img/CompareButton.png" NAME="Grafik1" ALIGN=BOTTOM WIDTH=178 HEIGHT=39 BORDER=0></P> + them.<BR></FONT><IMG SRC="../img/CompareButton.png" NAME="Grafik1" ALIGN=BOTTOM WIDTH=178 HEIGHT=40 BORDER=0></P> <P STYLE="margin-bottom: 0cm"> </P> <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Select synchronization settings.<BR></FONT><IMG SRC="../img/SyncConfigButton.png" NAME="Grafik3" ALIGN=BOTTOM WIDTH=46 HEIGHT=40 BORDER=0></P> @@ -71,7 +70,7 @@ Dialog:</FONT></H3> left and right directories</FONT></FONT></P> <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><FONT SIZE=4>Save/load configuration</FONT></FONT></P> - <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><FONT SIZE=4>Exclude + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><FONT SIZE=4>Filter files</FONT></FONT></P> <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><FONT SIZE=4>Specify category for display</FONT></FONT></P> @@ -83,111 +82,56 @@ Dialog:</FONT></H3> </P> <P STYLE="margin-bottom: 0cm"><BR> </P> -<H3 CLASS="western" STYLE="page-break-before: always"><FONT FACE="Tahoma, sans-serif">Menu -bar:</FONT></H3> -<P STYLE="margin-bottom: 0cm"><BR> -</P> -<TABLE WIDTH=908 BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0 RULES=NONE STYLE="page-break-inside: avoid"> - <COL WIDTH=678> - <COL WIDTH=212> - <TR> - <TD WIDTH=678 VALIGN=TOP> - <P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Menu - "F<SPAN STYLE="font-style: normal">ile"</SPAN></B></FONT></P> - <UL> - <LI><P STYLE="margin-bottom: 0cm; font-style: normal"><FONT FACE="Tahoma, sans-serif"><B>1. - Compare</B><BR>Start comparing both sides according to comparison - settings (compare by filesize and date or by content).</FONT></P> - <LI><P STYLE="margin-bottom: 0cm; font-style: normal"><FONT FACE="Tahoma, sans-serif"><B>2. - Synchronize...</B><BR>Begin synchronization and copy files as - seen on the middle grid of the main dialog.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm; font-style: normal"><FONT FACE="Tahoma, sans-serif"><B>Switch - View</B><BR>After comparison has finished the relation between - files on left and right side can be visualized by two views: </FONT> - </P> - </UL> - <P STYLE="margin-left: 2cm; margin-bottom: 0cm; font-style: normal"> - <FONT FACE="Tahoma, sans-serif">1. „Comparison Result“ - shows a category for each row like „existing on left side - only“ or „left file is newer“.</FONT></P> - <P STYLE="margin-left: 2cm; margin-bottom: 0cm; font-style: normal"> - <FONT FACE="Tahoma, sans-serif">2. „Synchronization Preview“ - is the result of the synchronization configuration applied on each - category. The effective directions in which the files will be - copied are shown.</FONT></P> - <UL> - <LI><P STYLE="margin-bottom: 0cm; font-style: normal"><FONT FACE="Tahoma, sans-serif"><B>New</B><BR>Clears - all configuration data and restores an initial state.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm; font-style: normal"><FONT FACE="Tahoma, sans-serif"><B>Save - Configuration...</B><BR>Save the current settings into a file.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm; font-style: normal"><FONT FACE="Tahoma, sans-serif"><B>Load - Configuration...</B><BR>Load configuration from file.</FONT></P> - <LI><P STYLE="font-style: normal"><FONT FACE="Tahoma, sans-serif"><B>Quit</B><BR>Exit - FreeFileSync.</FONT></P> - </UL> - </TD> - <TD WIDTH=212> - <P><IMG SRC="../img/menuFile.png" NAME="Grafik7" ALIGN=MIDDLE WIDTH=211 HEIGHT=196 BORDER=0></P> - </TD> - </TR> -</TABLE> -<P STYLE="margin-bottom: 0cm"><BR> -</P> -<TABLE WIDTH=855 BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0 RULES=NONE STYLE="page-break-inside: avoid"> - <COL WIDTH=680> - <COL WIDTH=157> - <TR> - <TD WIDTH=680 VALIGN=TOP> - <P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Menu - "Advanced"</B></FONT></P> - <UL> - <LI><P STYLE="margin-bottom: 0cm; font-style: normal"><FONT FACE="Tahoma, sans-serif"><B>Language</B><BR>Change - the language of the tool.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm; font-style: normal"><FONT FACE="Tahoma, sans-serif"><B>Global - Settings...</B><BR>A number of settings that have a global status - in the sense that they will be applied to all GUI and batch - configurations (*.ffs_gui and *.ffs_batch).</FONT></P> - <LI><P STYLE="margin-bottom: 0cm; font-style: normal"><FONT FACE="Tahoma, sans-serif"><B>Create - Batch Job</B><BR>Creates a FreeFileSync batch file (*.ffs_batch) - that executes a predefined synchronization without user - intervention.</FONT></P> - <LI><P><FONT FACE="Tahoma, sans-serif"><SPAN STYLE="font-style: normal"><B>Export - File List...</B></SPAN><SPAN STYLE="font-style: normal"><BR>Export - all data that </SPAN>is currently shown on the main grids as a - *.csv file that can be imported into Excel.</FONT></P> - </UL> - </TD> - <TD WIDTH=157> - <P><IMG SRC="../img/menuAdv.png" NAME="Grafik11" ALIGN=MIDDLE WIDTH=159 HEIGHT=112 BORDER=0></P> - </TD> - </TR> -</TABLE> -<P STYLE="margin-bottom: 0cm"><BR> -</P> -<TABLE WIDTH=772 BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0 RULES=NONE STYLE="page-break-inside: avoid"> - <COL WIDTH=552> - <COL WIDTH=202> - <TR> - <TD WIDTH=552 VALIGN=TOP> - <P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Menu - "Help"</B></FONT></P> - <UL> - <LI><P STYLE="margin-bottom: 0cm; font-style: normal"><FONT FACE="Tahoma, sans-serif"><B>Content</B><BR>Show - this helpfile.</FONT></P> - <LI><P STYLE="margin-bottom: 0cm; font-style: normal"><FONT FACE="Tahoma, sans-serif"><B>Check - for new version</B><BR>Check online whether a more recent version - of FreeFileSync is existing.</FONT></P> - <LI><P STYLE="font-style: normal"><FONT FACE="Tahoma, sans-serif"><B>About...</B><BR>Credits.</FONT></P> - </UL> - </TD> - <TD WIDTH=202> - <P><IMG SRC="../img/menuHelp.png" NAME="Grafik8" ALIGN=BOTTOM WIDTH=202 HEIGHT=90 BORDER=0></P> - </TD> - </TR> -</TABLE> -<P STYLE="margin-bottom: 0cm"><BR> -</P> -<P STYLE="margin-bottom: 0cm"><BR> -</P> +<H3 CLASS="western" STYLE="page-break-before: always"><FONT FACE="Tahoma, sans-serif">Key +Features</FONT></H3> +<OL> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Detect + moved and renamed files and folders</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Copy + locked files (Volume Shadow Copy Service)</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Detect + conflicts and propagate deletions</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Binary + comparison</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Full + support for Symbolic Links</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Run + as a batch job</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Multiple + folder pairs</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Support + very long path names > 260 characters</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Transactional + file copy</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Cross-platform: + Windows/Linux</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Expand + environment variables like %USERPROFILE%</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Access + variable drive letters by volume name (USB sticks)</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Native + 32 and 64-bit builds</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Versioning + of deleted files</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Optimal + sync sequence prevents disc space bottlenecks</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Full + unicode support</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Highly + optimized performance</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Include/exclude + files via filter</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Local + or portable installation</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Handle + daylight saving time changes on FAT/FAT32</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Use + macros %time%, %date%, et al. for recurring backups</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Case + sensitive synchronization</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Built-in + locking serializes multiple jobs running against the same network + share</FONT></P> +</OL> </BODY> </HTML>
\ No newline at end of file diff --git a/BUILD/Help/html/RealtimeSync.html b/BUILD/Help/html/RealtimeSync.html index 3468bc76..7fd3b6c9 100644 --- a/BUILD/Help/html/RealtimeSync.html +++ b/BUILD/Help/html/RealtimeSync.html @@ -5,7 +5,7 @@ <TITLE></TITLE> <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.2 (Win32)"> <META NAME="CREATED" CONTENT="20091206;16574000"> - <META NAME="CHANGED" CONTENT="20110906;23572100"> + <META NAME="CHANGED" CONTENT="20120324;18334600"> <META NAME="Info 1" CONTENT=""> <META NAME="Info 2" CONTENT=""> <META NAME="Info 3" CONTENT=""> @@ -28,14 +28,11 @@ Automated Synchronization -</SPAN></I></FONT></H3> <P ALIGN=LEFT><BR><BR> </P> -<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">RealtimeSync's -primary function is to trigger synchronization immediately after -files in a source directory have changed. However its implementation -is more flexible to cover an even broader range of use: A list of -directories provided by the user is monitored for changes. Whenever a -file within these directories or sub directories is modified OR the -directory becomes available (e. g. insert of a USB-stick), -RealtimeSync responds by executing the user-specified command line.</FONT></P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">RealtimeSync +is a small tool which executes a command line each time it detects +changes in one of the monitored directories <SPAN STYLE="font-style: normal"><B>or</B></SPAN> +a directory becomes available (e. g. insert of a USB-stick). Usually +this command line will simply trigger a FreeFileSync batch job.</FONT></P> <P STYLE="margin-bottom: 0cm"><BR> </P> <P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Example:</B></FONT> @@ -44,11 +41,11 @@ combination with FreeFileSync</FONT></P> <P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">First start up RealtimeSync.exe located in FreeFileSync's installation directory. Then specify all directories that shall be monitored. -Instead of doing this manually you can simply import a </FONT><FONT FACE="Courier New, monospace">*.ffs_batch</FONT> +Instead of doing this manually you can import a </FONT><FONT FACE="Courier New, monospace">*.ffs_batch</FONT> <FONT FACE="Tahoma, sans-serif">file via </FONT><FONT FACE="Tahoma, sans-serif"><I>Menu -> File -> Load configuration</I></FONT><FONT FACE="Tahoma, sans-serif">. This not only extracts all directories relevant for synchronization -but also sets up the command-line to execute the </FONT><FONT FACE="Courier New, monospace">*.ffs_batch</FONT> +but also sets up the command line to execute the </FONT><FONT FACE="Courier New, monospace">*.ffs_batch</FONT> <FONT FACE="Tahoma, sans-serif">file each time changes are detected. Now press "</FONT><FONT FACE="Tahoma, sans-serif"><I>Start</I></FONT><FONT FACE="Tahoma, sans-serif">" to begin monitoring.</FONT></P> @@ -68,7 +65,7 @@ to begin monitoring.</FONT></P> <LI><P ALIGN=LEFT STYLE="margin-right: 0.98cm; margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">The settings dialog can be skipped by passing a RealtimeSync configuration file (<FONT FACE="Courier New, monospace">*.ffs_real</FONT>) - OR a FreeFileSync batch file (<FONT FACE="Courier New, monospace">*.ffs_batch</FONT>) + <B>or</B> a FreeFileSync batch file (<FONT FACE="Courier New, monospace">*.ffs_batch</FONT>) as first command-line argument to RealtimeSync.exe. This allows for integration with the operating system's auto start facility:<BR> <FONT FACE="Courier New, monospace">"C:\Program @@ -124,7 +121,7 @@ directories. (Windows)</FONT></P> <P><SPAN ID="Rahmen4" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: none; padding: 0cm; background: #e6e6e6"> <UL> <P ALIGN=LEFT STYLE="margin-right: 0.98cm; margin-bottom: 0cm"><FONT FACE="Courier New, monospace"><FONT FACE="Tahoma, sans-serif">Show - which file or directory has triggered a change. Enter into command + which file or directory has triggered a change. Enter command line:</FONT><BR> cmd /c echo "%changed_file%" & pause<BR><BR><FONT FACE="Tahoma, sans-serif">Write a list of all changes to a logfile:</FONT><BR> cmd @@ -133,7 +130,7 @@ directories. (Windows)</FONT></P> </SPAN><BR CLEAR=LEFT> </P> </UL> -<P STYLE="margin-bottom: 0cm; text-decoration: none"><BR> +<P STYLE="margin-bottom: 0cm"><BR> </P> <P STYLE="margin-bottom: 0cm; text-decoration: none"><FONT FACE="Tahoma, sans-serif">Limitations:</FONT></P> <UL> diff --git a/BUILD/Help/html/RunAsService.html b/BUILD/Help/html/RunAsService.html index 8b5e0d42..dcd0b029 100644 --- a/BUILD/Help/html/RunAsService.html +++ b/BUILD/Help/html/RunAsService.html @@ -5,7 +5,7 @@ <TITLE></TITLE> <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.2 (Win32)"> <META NAME="CREATED" CONTENT="20091206;16574000"> - <META NAME="CHANGED" CONTENT="20110903;15175900"> + <META NAME="CHANGED" CONTENT="20120217;11243000"> <META NAME="Info 1" CONTENT=""> <META NAME="Info 2" CONTENT=""> <META NAME="Info 3" CONTENT=""> @@ -29,9 +29,12 @@ </P> <P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">The following step-by-step guide describes how to setup RealtimeSync (or -any other application) as a Windows Service. This can be useful if -the tool shall run on a SYSTEM account without necessarily requiring -a user to log in.</FONT></P> +any other application) as a Windows Service. This is necessary if the +tool shall run on the SYSTEM account independent from currently +logged-in users. If you are the only user and all you want is to +start RealtimeSync automatically then it's better to place a link +into Windows' Autostart folder, specifying RealtimeSync.exe and the +.ffs_batch or .ffs_real file as argument.</FONT></P> <P STYLE="margin-bottom: 0cm"><BR> </P> <P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">1. Get @@ -75,18 +78,23 @@ service is now ready for operation!</FONT></P> <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-right: 0.98cm; margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif"><B>Attention:</B><BR>When running RealtimeSync as a service the application has no means to interact - with the user. Therefore any popup dialog will stop the process - flow! Consider the following options when setting up a FreeFileSync - batch job:</FONT></P> + with the user. Therefore any popup dialog will halt the process! + Consider the following options when setting up a FreeFileSync batch + job:</FONT></P> <UL> - <LI><P ALIGN=LEFT STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Enable - checkbox "<I>Run minimized</I>" to prevent showing the - results dialog after synchronization.</FONT></P> + <LI><P ALIGN=LEFT STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Disable + checkbox "<I>Show progress dialog</I>" or automatically + close it after synchronization.</FONT></P> <LI><P ALIGN=LEFT STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Set "<I>Error handling</I>" to either "<I>Exit instantly</I>" or "<I>Ignore errors</I>".</FONT></P> + <LI><P ALIGN=LEFT STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">At + least for debugging purposes or initial setup "Allow service + to interact with desktop". The may show error dialogs + otherwise hidden by the SYSTEM account.</FONT></P> </UL> -</SPAN><BR CLEAR=LEFT><BR> +</SPAN><BR CLEAR=LEFT><BR><IMG SRC="../img/RunAsService_html_13819326743214.png" NAME="Grafik2" ALIGN=TEXTTOP WIDTH=535 HEIGHT=589 BORDER=0></P> +<P STYLE="margin-left: 1.46cm; margin-bottom: 0cm"><BR> </P> <P ALIGN=LEFT STYLE="margin-right: 0.98cm; margin-bottom: 0cm"><BR> </P> diff --git a/BUILD/Help/html/ScheduleBatch.html b/BUILD/Help/html/ScheduleBatch.html index d15565e2..9a40cce5 100644 --- a/BUILD/Help/html/ScheduleBatch.html +++ b/BUILD/Help/html/ScheduleBatch.html @@ -5,7 +5,7 @@ <TITLE></TITLE> <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.2 (Win32)"> <META NAME="CREATED" CONTENT="20091206;16574000"> - <META NAME="CHANGED" CONTENT="20111206;16050900"> + <META NAME="CHANGED" CONTENT="20120221;18051600"> <STYLE TYPE="text/css"> <!-- @page { margin: 2cm } @@ -38,7 +38,7 @@ Job</FONT></H3> "Close progress dialog" located in synchronization settings. Note that even if the progress is not shown initially it can be displayed interactively at any time during synchronization, - by double-clicking the corresponding systray icon.<BR><IMG SRC="../img/SetupBatch.png" NAME="Grafik3" ALIGN=BOTTOM WIDTH=548 HEIGHT=319 BORDER=0></FONT></P> + by double-clicking the corresponding systray icon.<BR><IMG SRC="../img/SetupBatch.png" NAME="Grafik3" ALIGN=BOTTOM BORDER=0></FONT></P> <P STYLE="margin-bottom: 0cm"> </P> <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">In order to prevent error or warning popup messages from stopping @@ -112,7 +112,7 @@ Job</FONT></H3> <UL> <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><SPAN STYLE="font-style: normal"><SPAN STYLE="font-weight: normal">Specify the command as:</SPAN></SPAN></FONT> <FONT FACE="Courier New, monospace"><I><SPAN STYLE="font-weight: normal"><FreeFileSync - installation directory>\FreeFileSync <ffs_batch file><BR></SPAN></I></FONT><IMG SRC="../img/ubuntuScheduler.png" NAME="Grafik5" ALIGN=BOTTOM WIDTH=629 HEIGHT=560 BORDER=0></P> + installation directory>/FreeFileSync <ffs_batch file><BR></SPAN></I></FONT><IMG SRC="../img/ubuntuScheduler.png" NAME="Grafik5" ALIGN=BOTTOM WIDTH=629 HEIGHT=560 BORDER=0></P> </UL> </OL> </OL> diff --git a/BUILD/Help/html/VariableDrive.html b/BUILD/Help/html/VariableDrive.html index 3e0ea71e..87283a12 100644 --- a/BUILD/Help/html/VariableDrive.html +++ b/BUILD/Help/html/VariableDrive.html @@ -5,7 +5,7 @@ <TITLE></TITLE> <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.2 (Win32)"> <META NAME="CREATED" CONTENT="20091206;16574000"> - <META NAME="CHANGED" CONTENT="20110909;4200"> + <META NAME="CHANGED" CONTENT="20120206;18412300"> <STYLE TYPE="text/css"> <!-- @page { margin: 2cm } @@ -30,19 +30,19 @@ issue:</FONT></P> <P STYLE="margin-bottom: 0cm"><BR> </P> <P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Option -1: </B>Specify a directory via volume name: Syntax: <FONT FACE="Courier New, monospace">[<volume -name>]\<path></FONT></FONT></P> +1: </B>Specify a directory via volume name: Syntax: <FONT FACE="Courier New, monospace">[volume +name]\path</FONT></FONT></P> <P STYLE="margin-left: 1.32cm; margin-bottom: 0cm"><SPAN ID="Rahmen5" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: none; padding: 0cm; background: #e6e6e6"> <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-right: 0.98cm; margin-bottom: 0cm"> - <FONT FACE="Tahoma, sans-serif">Use "<FONT FACE="Courier New, monospace">[ZenJu-USB]\directory</FONT>" - instead of "<FONT FACE="Courier New, monospace">E:\directory</FONT>" - where "<FONT FACE="Courier New, monospace">ZenJu-USB</FONT>" - is the name of the USB stick.</FONT></P> + <FONT FACE="Tahoma, sans-serif">Use "<FONT FACE="Courier New, monospace">[ZENJU-USB]\folder</FONT>" + instead of "<FONT FACE="Courier New, monospace">G:\folder</FONT>" + where "<FONT FACE="Courier New, monospace">ZENJU-USB</FONT>" + is the name of the USB stick that is currently mounted in volume G:\.</FONT></P> </SPAN><BR CLEAR=LEFT><BR> </P> <P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">It is -not required to look up and enter the volume name manually. Just -select the corresponding entry in the drop down menu.<BR></FONT><IMG SRC="../img/VolumeName.png" NAME="Grafik1" ALIGN=BOTTOM WIDTH=279 HEIGHT=103 BORDER=0></P> +not required to look up and enter the volume name manually! Just +select the corresponding entry in the drop down menu.<BR></FONT><IMG SRC="../img/VolumeName.png" NAME="Grafik1" ALIGN=BOTTOM></P> <P STYLE="margin-bottom: 0cm"><BR> </P> <P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Option @@ -51,16 +51,16 @@ directory name:</FONT></P> <P STYLE="margin-left: 1.32cm; margin-bottom: 0cm"><SPAN ID="Rahmen1" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: none; padding: 0cm; background: #e6e6e6"> <UL> <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Use - "</FONT><FONT FACE="Courier New, monospace">\directory</FONT><FONT FACE="Tahoma, sans-serif">" - instead of "</FONT><FONT FACE="Courier New, monospace">E:\directory</FONT><FONT FACE="Tahoma, sans-serif">"<BR> </FONT></P> + "</FONT><FONT FACE="Courier New, monospace">\folder</FONT><FONT FACE="Tahoma, sans-serif">" + instead of "</FONT><FONT FACE="Courier New, monospace">G:\folder</FONT><FONT FACE="Tahoma, sans-serif">"<BR> </FONT></P> <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Save and copy synchronization settings to the USB stick: - "</FONT><FONT COLOR="#000000"><FONT FACE="Courier New, monospace"><FONT SIZE=3>E:\settings.ffs_gui"<BR> </FONT></FONT></FONT></P> + "</FONT><FONT COLOR="#000000"><FONT FACE="Courier New, monospace"><FONT SIZE=3>G:\settings.ffs_gui"<BR> </FONT></FONT></FONT></P> <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Start - FreeFileSync by double-clicking on "</FONT><FONT FACE="Courier New, monospace">E:\settings.ffs_gui</FONT><FONT FACE="Tahoma, sans-serif">"<BR>→ - Working directory is automatically set to "</FONT><FONT FACE="Courier New, monospace">E:\</FONT><FONT FACE="Tahoma, sans-serif">" - by the operating system so that "</FONT><FONT FACE="Courier New, monospace">\directory</FONT><FONT FACE="Tahoma, sans-serif">" - will be resolved as "</FONT><FONT FACE="Courier New, monospace">E:\directory</FONT><FONT FACE="Tahoma, sans-serif">" + FreeFileSync by double-clicking on "</FONT><FONT FACE="Courier New, monospace">G:\settings.ffs_gui</FONT><FONT FACE="Tahoma, sans-serif">"<BR>→ + Working directory is automatically set to "</FONT><FONT FACE="Courier New, monospace">G:\</FONT><FONT FACE="Tahoma, sans-serif">" + by the operating system so that "</FONT><FONT FACE="Courier New, monospace">\folder</FONT><FONT FACE="Tahoma, sans-serif">" + will be resolved as "</FONT><FONT FACE="Courier New, monospace">G:\folder</FONT><FONT FACE="Tahoma, sans-serif">" during synchronization.</FONT></P> </UL> </SPAN><BR CLEAR=LEFT><BR> diff --git a/BUILD/Help/img/CompareButton.png b/BUILD/Help/img/CompareButton.png Binary files differindex bab3780b..c45a1e86 100644 --- a/BUILD/Help/img/CompareButton.png +++ b/BUILD/Help/img/CompareButton.png diff --git a/BUILD/Help/img/MainDialog.png b/BUILD/Help/img/MainDialog.png Binary files differindex ab6a6f7c..6d7271a1 100644 --- a/BUILD/Help/img/MainDialog.png +++ b/BUILD/Help/img/MainDialog.png diff --git a/BUILD/Help/img/RunAsService_html_13819326743214.png b/BUILD/Help/img/RunAsService_html_13819326743214.png Binary files differnew file mode 100644 index 00000000..0ca018d1 --- /dev/null +++ b/BUILD/Help/img/RunAsService_html_13819326743214.png diff --git a/BUILD/Help/img/SetupBatch.png b/BUILD/Help/img/SetupBatch.png Binary files differindex d11d22db..d3dc81a0 100644 --- a/BUILD/Help/img/SetupBatch.png +++ b/BUILD/Help/img/SetupBatch.png diff --git a/BUILD/Help/img/VolumeName.png b/BUILD/Help/img/VolumeName.png Binary files differindex 9d1b9201..da39c9a5 100644 --- a/BUILD/Help/img/VolumeName.png +++ b/BUILD/Help/img/VolumeName.png diff --git a/BUILD/Help/img/menuAdv.png b/BUILD/Help/img/menuAdv.png Binary files differdeleted file mode 100644 index 3626c1f0..00000000 --- a/BUILD/Help/img/menuAdv.png +++ /dev/null diff --git a/BUILD/Help/img/menuFile.png b/BUILD/Help/img/menuFile.png Binary files differdeleted file mode 100644 index 7e6844d5..00000000 --- a/BUILD/Help/img/menuFile.png +++ /dev/null diff --git a/BUILD/Help/img/menuHelp.png b/BUILD/Help/img/menuHelp.png Binary files differdeleted file mode 100644 index db51f82f..00000000 --- a/BUILD/Help/img/menuHelp.png +++ /dev/null diff --git a/BUILD/Languages/chinese_simple.lng b/BUILD/Languages/chinese_simple.lng index 4b0d6151..fd5cbaf8 100644 --- a/BUILD/Languages/chinese_simple.lng +++ b/BUILD/Languages/chinese_simple.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>配置过滤</target> -<source>Customize columns</source> -<target>自定义栏</target> - <source>Global settings</source> <target>全局设置</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>浏览</target> -<source>Error reading from synchronization database:</source> -<target>从同步数据库中读取时出错:</target> - -<source>Error writing to synchronization database:</source> -<target>向同步数据库中写入时出错:</target> - <source>Invalid command line: %x</source> <target>无效的命令行: %x</target> +<source>Info</source> +<target>信息</target> + +<source>Fatal Error</source> +<target>致命错误</target> + <source>Windows Error Code %x:</source> <target>Windows错误代码 %x:</target> @@ -138,15 +135,21 @@ <pluralform>%x 字节</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>从同步数据库中读取时出错:</target> + +<source>Error writing to synchronization database:</source> +<target>向同步数据库中写入时出错:</target> + +<source>Incompatible synchronization database format:</source> +<target>不兼容的同步数据库格式:</target> + <source>Initial synchronization:</source> <target>初始化同步:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>FreeFileSync数据库文件其中一个不存在:</target> -<source>Incompatible synchronization database format:</source> -<target>不兼容的同步数据库格式:</target> - <source>Database files do not share a common synchronization session:</source> <target>数据库文件没不共享一个公共的同步段</target> @@ -170,12 +173,6 @@ <pluralform>%x 秒</pluralform> </target> -<source>Info</source> -<target>信息</target> - -<source>Fatal Error</source> -<target>致命错误</target> - <source>Error reading file:</source> <target>读取文件出错:</target> @@ -199,11 +196,14 @@ <source>Error parsing configuration file:</source> <target>分析配置文件出错:</target> -<source>Error moving to Recycle Bin:</source> -<target>移动到回收站出错:</target> +<source>Configuration loaded partially only:</source> +<target>只部分载入配置文件:</target> -<source>Could not load a required DLL:</source> -<target>不能加载所需的动态连接库:</target> +<source>Unable to move %x to the Recycle Bin!</source> +<target>无法移动 %x 到回收站!</target> + +<source>Cannot load file %x.</source> +<target>不能载入文件 %x.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>使用卷影复制服务时出错!</target> @@ -211,10 +211,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>不支持在WOW64上使用卷影复制. 请使用 FreeFileSync 64位版本.</target> -<source>Could not determine volume name for file:</source> -<target>不能确定此文件的卷名称:</target> +<source>Cannot determine volume name for file:</source> +<target>不能确定文件的卷名:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>卷名 %x 并非文件名 %y 的一部分!</target> <source>/sec</source> @@ -223,8 +223,8 @@ <source>File does not exist:</source> <target>文件不存在:</target> -<source>Could not read values for the following XML nodes:</source> -<target>不能从如下XML节点读取数值:</target> +<source>Cannot read the following XML elements:</source> +<target>无法读取如下XML元素:</target> <source>S&ave configuration...</source> <target>保存配置(&A)...</target> @@ -450,9 +450,6 @@ The command line is executed each time: <source>2. &Synchronize...</source> <target>2. 同步(&S)...</target> -<source>S&witch view</source> -<target>切换视图(&W)</target> - <source>&New</source> <target>新建(&N)</target> @@ -540,17 +537,17 @@ The command line is executed each time: <source>Speed:</source> <target>速度:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>剩余时间:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>已用时间:</target> <source>Batch job</source> <target>批处理作业</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>创建一个用于自动同步的批处理文件. 要开始批处理模式只需简单地双击此文件或通过命令行执行: FreeFileSync.exe <ffs_batch 文件>. 此文件还可以用于你操作系统的计划任务中.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>创建批处理文件并自动同步. 要在批处理模式下开始, 只需简单双击此文件或运行如下命令: FreeFileSync.exe SyncJob.ffs_batch. 此外也可在你系统中的计划任务里面执行.</target> <source>Help</source> <target>帮助</target> @@ -564,8 +561,8 @@ The command line is executed each time: <source>Right</source> <target>右侧</target> -<source>Overview</source> -<target>摘要</target> +<source>Sync setttings</source> +<target>同步设置</target> <source>Status feedback</source> <target>状况反馈</target> @@ -711,8 +708,8 @@ is the same <source>Published under the GNU General Public License</source> <target>在GNU通用公共许可下发布</target> -<source>Ignore subsequent errors</source> -<target>忽略随后的错误</target> +<source>Ignore further errors</source> +<target>忽略之后出现的错误</target> <source>Hide further error messages during the current process</source> <target>在当前进程中隐藏进一步的错误信息</target> @@ -735,22 +732,22 @@ is the same <source>&No</source> <target>否(&N)</target> +<source>Use Recycle Bin</source> +<target>使用回收站</target> + <source>Delete on both sides</source> <target>从两侧删除</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>从两侧删除(即使仅在一侧选择文件)</target> -<source>Use Recycle Bin</source> -<target>使用回收站</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -只有匹配所有过滤器设置的文件/目录会被选择用于同步. -备注:文件名过滤器必须指定为同步主目录的相对路径. +只有匹配所有过滤器的文件会被同步. +注:文件名必须是主目录的相对路径! </target> <source>Hints:</source> @@ -786,20 +783,20 @@ Exclude: \stuff\temp\* <source>Exclude</source> <target>排除</target> -<source>Minimum file size</source> -<target>最小文件大小</target> +<source>Time span</source> +<target>时间跨度</target> -<source>Maximum file size</source> -<target>最大文件大小</target> +<source>File size</source> +<target>文件大小</target> -<source>&Default</source> -<target>默认(&D)</target> +<source>Minimum</source> +<target>最小</target> -<source>Move column up</source> -<target>上移一行</target> +<source>Maximum</source> +<target>最大</target> -<source>Move column down</source> -<target>下移一行</target> +<source>&Default</source> +<target>默认(&D)</target> <source>Transactional file copy</source> <target>事务文件复制</target> @@ -819,14 +816,8 @@ Exclude: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>转移文件和目录的权限(需要管理员权限)</target> -<source>Hidden dialogs:</source> -<target>隐藏对话框:</target> - -<source>Reset</source> -<target>重置</target> - -<source>Show hidden dialogs</source> -<target>显示隐藏的对话框</target> +<source>Restore hidden dialogs</source> +<target>恢复被隐藏的对话框</target> <source>External applications</source> <target>外部应用程序</target> @@ -858,8 +849,8 @@ Exclude: \stuff\temp\* <source>Folder pairs</source> <target>文件夹对</target> -<source>Compressed view</source> -<target>压缩视图</target> +<source>Overview</source> +<target>摘要</target> <source>Select view</source> <target>选择视图</target> @@ -888,8 +879,8 @@ Exclude: \stuff\temp\* <source>Exclude all</source> <target>排除所有</target> -<source>Icon size:</source> -<target>图标大小:</target> +<source>Show icons:</source> +<target>显示图标:</target> <source>Small</source> <target>小</target> @@ -915,6 +906,9 @@ Exclude: \stuff\temp\* <source>Configuration saved!</source> <target>配置已保存!</target> +<source>Never save changes</source> +<target>永不保存更改</target> + <source>Save changes to current configuration?</source> <target>保存更改到当前配置?</target> @@ -1026,9 +1020,6 @@ Exclude: \stuff\temp\* <source>Error writing file:</source> <target>写入文件出错:</target> -<source>Batch file created successfully!</source> -<target>批处理文件创建成功!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1103,6 +1094,9 @@ Exclude: \stuff\temp\* <source>This year</source> <target>今年</target> +<source>Last x days</source> +<target>最后 x 天</target> + <source>Byte</source> <target>字节</target> @@ -1112,11 +1106,8 @@ Exclude: \stuff\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>过滤器:所有的配对</target> - -<source>Filter: Single pair</source> -<target>过滤器:单一的配对</target> +<source>Filter</source> +<target>过滤器</target> <source>Direct</source> <target>直接</target> @@ -1142,8 +1133,8 @@ Exclude: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- 另一侧参照 %dir</target> -<source>Restore all hidden dialogs?</source> -<target>恢复所有被隐藏的对话框?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>重新让被隐藏的对话框和警告信息变为可见?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1314,8 +1305,8 @@ Exclude: \stuff\temp\* <source>Preparing synchronization...</source> <target>正在准备同步...</target> -<source>Memory allocation failed!</source> -<target>内存分配失败!</target> +<source>Out of memory!</source> +<target>内存不足!</target> <source>File %x has an invalid date!</source> <target>文件 %x 的日期非法!</target> @@ -1470,11 +1461,11 @@ Exclude: \stuff\temp\* <source>Generating database...</source> <target>正在生成数据库...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>根据配置没有任何同步!</target> +<source>Nothing to synchronize!</source> +<target>没有什么可同步!</target> -<source>Error copying locked file %x!</source> -<target>复制已锁定的文件时出错 %x!</target> +<source>Unable to copy locked file %x!</source> +<target>无法复制已锁定文件 %x!</target> <source>Data verification error: Source and target file have different content!</source> <target>数据校验错误:源文件和目标文件内容不同!</target> diff --git a/BUILD/Languages/chinese_traditional.lng b/BUILD/Languages/chinese_traditional.lng index 082cbea6..c222463d 100644 --- a/BUILD/Languages/chinese_traditional.lng +++ b/BUILD/Languages/chinese_traditional.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>配置篩選</target> -<source>Customize columns</source> -<target>自訂列</target> - <source>Global settings</source> <target>整體設定</target> @@ -80,7 +77,7 @@ <target>尋找</target> <source>Select time span</source> -<target>選擇時間範圍</target> +<target>選擇時間間隔</target> <source>Show pop-up</source> <target>顯示彈出視窗</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>瀏覽</target> -<source>Error reading from synchronization database:</source> -<target>讀取同步資料庫錯誤:</target> - -<source>Error writing to synchronization database:</source> -<target>寫入同步資料庫錯誤:</target> - <source>Invalid command line: %x</source> <target>無效的命令列:%x</target> +<source>Info</source> +<target>訊息</target> + +<source>Fatal Error</source> +<target>嚴重錯誤</target> + <source>Windows Error Code %x:</source> <target>Windows錯誤代碼 %x:</target> @@ -138,15 +135,21 @@ <pluralform>%x 位元組</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>讀取同步資料庫錯誤:</target> + +<source>Error writing to synchronization database:</source> +<target>寫入同步資料庫錯誤:</target> + +<source>Incompatible synchronization database format:</source> +<target>同步資料庫格式不相容:</target> + <source>Initial synchronization:</source> <target>初始化同步:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>其中一個FreeFileSync資料庫檔案不存在:</target> -<source>Incompatible synchronization database format:</source> -<target>同步資料庫格式不相容:</target> - <source>Database files do not share a common synchronization session:</source> <target>資料庫檔案不要共享一個共同的同步連線:</target> @@ -157,7 +160,7 @@ <target>讀取檔案屬性錯誤:</target> <source>Waiting while directory is locked (%x)...</source> -<target>等待目錄被鎖定(%x)...</target> +<target>等待同時目錄被鎖定(%x)...</target> <source>Error setting directory lock:</source> <target>設定目錄鎖錯誤:</target> @@ -170,12 +173,6 @@ <pluralform>%x 秒</pluralform> </target> -<source>Info</source> -<target>訊息</target> - -<source>Fatal Error</source> -<target>嚴重錯誤</target> - <source>Error reading file:</source> <target>讀取檔案錯誤:</target> @@ -199,22 +196,25 @@ <source>Error parsing configuration file:</source> <target>分析配置檔案錯誤:</target> -<source>Error moving to Recycle Bin:</source> -<target>移動到資源回收筒錯誤:</target> +<source>Configuration loaded partially only:</source> +<target>只載入部分配置:</target> -<source>Could not load a required DLL:</source> -<target>無法載入一個必要的DLL:</target> +<source>Unable to move %x to the Recycle Bin!</source> +<target>無法將 %x 移動到資源回收筒!</target> + +<source>Cannot load file %x.</source> +<target>無法載入檔案 %x。</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>讀取卷影複製服務時錯誤!</target> <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> -<target>不支援製作WOW64上的卷影副本。請使用FreeFileSync 64位元版本。</target> +<target>不支援WOW64製作卷影副本。請使用FreeFileSync 64位元版本。</target> -<source>Could not determine volume name for file:</source> -<target>無法判斷此檔案的卷標名稱:</target> +<source>Cannot determine volume name for file:</source> +<target>無法判斷檔案卷名:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>卷名 %x 並非檔名 %y 的一部份!</target> <source>/sec</source> @@ -223,8 +223,8 @@ <source>File does not exist:</source> <target>檔案不存在:</target> -<source>Could not read values for the following XML nodes:</source> -<target>無法讀取XML之後節點的值:</target> +<source>Cannot read the following XML elements:</source> +<target>無法讀取下列XML元素:</target> <source>S&ave configuration...</source> <target>儲存配置(&A)...</target> @@ -266,7 +266,7 @@ The command line is executed each time: </source> <target> 命令列每次執行: -- 可用的目錄(例如插入USB隨身碟) +- 所有目錄為可用(例如插入USB隨身碟) - 檔案在這些目錄或子目錄會被修改 </target> @@ -289,7 +289,7 @@ The command line is executed each time: <target>最小閒置時間 [秒]</target> <source>Idle time between detection of last change and execution of command line in seconds</source> -<target>上次更改的檢測和執行命令列之間以秒為單位的閒置時間</target> +<target>在幾秒鐘內檢測上次更改和執行命令列之間的閒置時間</target> <source>Start</source> <target>開始</target> @@ -304,7 +304,7 @@ The command line is executed each time: <target>檔案已存在,要覆蓋嗎?</target> <source>&Restore</source> -<target>回復(&R)</target> +<target>還原(&R)</target> <source>&Exit</source> <target>結束(&E)</target> @@ -537,17 +537,17 @@ The command line is executed each time: <source>Speed:</source> <target>速度:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>剩餘時間:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>經過時間:</target> <source>Batch job</source> <target>批次處理作業</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>新建一個自動同步的批次檔。若要開始批次處理模式只需按兩下此檔或通過命令列執行:FreeFileSync.exe <ffs_batch file>。還可以安排在您的作業系統的任務計畫中。</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>新建一個批次檔,並自動執行同步。若要開始批次處理模式只需按兩下此檔或通過命令列執行:FreeFileSync.exe SyncJob.ffs批次處理。還可以安排在您的作業系統的任務計畫中。</target> <source>Help</source> <target>說明</target> @@ -561,8 +561,8 @@ The command line is executed each time: <source>Right</source> <target>右邊</target> -<source>Overview</source> -<target>摘要</target> +<source>Sync setttings</source> +<target>同步設定</target> <source>Status feedback</source> <target>狀態回報</target> @@ -595,7 +595,7 @@ The command line is executed each time: <target>選擇變數:</target> <source>Identify and propagate changes on both sides using a database. Deletions, renaming and conflicts are detected automatically.</source> -<target>對兩邊使用同一個資料庫的識別和傳送更改。自動檢測刪除和衝突部份。</target> +<target>對兩邊使用同一個資料庫來識別和傳送更改。自動檢測刪除、重新命名和衝突部份。</target> <source>Mirror backup of left folder. Right folder is modified to exactly match left folder after synchronization.</source> <target>鏡像備份的左邊的資料夾。同步後,右邊的資料夾進行修改以完全相配左邊的資料夾。</target> @@ -699,8 +699,8 @@ is the same <source>Published under the GNU General Public License</source> <target>在GNU通用公共許可證下發佈</target> -<source>Ignore subsequent errors</source> -<target>忽略後續錯誤</target> +<source>Ignore further errors</source> +<target>忽略進一步錯誤</target> <source>Hide further error messages during the current process</source> <target>在目前進程中隱藏進一步的錯誤訊息</target> @@ -723,22 +723,22 @@ is the same <source>&No</source> <target>否(&N)</target> +<source>Use Recycle Bin</source> +<target>使用資源回收筒</target> + <source>Delete on both sides</source> <target>兩邊都刪除</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>即使只在一邊中選好檔案,還是會刪除兩邊檔案。</target> -<source>Use Recycle Bin</source> -<target>使用資源回收筒</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -只有被選中篩選的檔案/目錄會進行同步。 -注意:篩選器將套用到基本同步目錄的相對名稱。 +只有符合所有篩選器設定的檔案才會被同步。 +注意:檔名必須相對到基本目錄! </target> <source>Hints:</source> @@ -774,20 +774,20 @@ Exclude: \stuff\temp\* <source>Exclude</source> <target>排除</target> -<source>Minimum file size</source> -<target>最小檔案大小</target> +<source>Time span</source> +<target>時間間隔</target> -<source>Maximum file size</source> -<target>最大檔案大小</target> +<source>File size</source> +<target>檔案大小</target> -<source>&Default</source> -<target>預設(&D)</target> +<source>Minimum</source> +<target>最小</target> -<source>Move column up</source> -<target>上移一行</target> +<source>Maximum</source> +<target>最大</target> -<source>Move column down</source> -<target>下移一行</target> +<source>&Default</source> +<target>預設(&D)</target> <source>Transactional file copy</source> <target>異動檔案副本</target> @@ -807,14 +807,8 @@ Exclude: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>傳輸檔案和目錄權限(需要管理員權限)</target> -<source>Hidden dialogs:</source> -<target>隱藏對話框:</target> - -<source>Reset</source> -<target>重置</target> - -<source>Show hidden dialogs</source> -<target>顯示隱藏的對話框</target> +<source>Restore hidden dialogs</source> +<target>還原隱藏的對話框</target> <source>External applications</source> <target>外部應用程式</target> @@ -846,8 +840,8 @@ Exclude: \stuff\temp\* <source>Folder pairs</source> <target>資料夾對</target> -<source>Compressed view</source> -<target>壓縮檢視</target> +<source>Overview</source> +<target>摘要</target> <source>Select view</source> <target>選擇檢視</target> @@ -876,8 +870,8 @@ Exclude: \stuff\temp\* <source>Exclude all</source> <target>排除所有</target> -<source>Icon size:</source> -<target>圖示大小:</target> +<source>Show icons:</source> +<target>顯示圖示:</target> <source>Small</source> <target>小</target> @@ -889,7 +883,7 @@ Exclude: \stuff\temp\* <target>大</target> <source>Select time span...</source> -<target>選擇時間範圍...</target> +<target>選擇時間間隔...</target> <source>Default view</source> <target>預設檢視</target> @@ -903,6 +897,9 @@ Exclude: \stuff\temp\* <source>Configuration saved!</source> <target>配置已儲存!</target> +<source>Never save changes</source> +<target>從不儲存更改</target> + <source>Save changes to current configuration?</source> <target>要儲存目前配置的更改嗎?</target> @@ -1014,9 +1011,6 @@ Exclude: \stuff\temp\* <source>Error writing file:</source> <target>寫入檔案錯誤:</target> -<source>Batch file created successfully!</source> -<target>批次檔新建成功!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1053,7 +1047,7 @@ Exclude: \stuff\temp\* <target>正在掃瞄...</target> <source>Comparing content...</source> -<target>正在比對檔案内容...</target> +<target>正在比對内容...</target> <source>Paused</source> <target>已暫停</target> @@ -1091,6 +1085,9 @@ Exclude: \stuff\temp\* <source>This year</source> <target>今年</target> +<source>Last x days</source> +<target>最後 x 天</target> + <source>Byte</source> <target>位元組</target> @@ -1100,11 +1097,8 @@ Exclude: \stuff\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>篩選器:所有對</target> - -<source>Filter: Single pair</source> -<target>篩選器:單對</target> +<source>Filter</source> +<target>篩選器</target> <source>Direct</source> <target>直接</target> @@ -1130,8 +1124,8 @@ Exclude: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- 另一邊對應到 %dir</target> -<source>Restore all hidden dialogs?</source> -<target>要還原全部隱藏的對話框嗎?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>讓隱藏的對話框和警告訊息再被看見嗎?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1276,7 +1270,7 @@ Exclude: \stuff\temp\* <target>無法判斷同步方向:</target> <source>No change since last synchronization!</source> -<target>自上次同步以來都沒有變更!</target> +<target>自上次同步以來都沒有更改!</target> <source>Filter settings have changed!</source> <target>篩選器設定已更改!</target> @@ -1302,8 +1296,8 @@ Exclude: \stuff\temp\* <source>Preparing synchronization...</source> <target>正在準備同步...</target> -<source>Memory allocation failed!</source> -<target>記憶體分配失敗!</target> +<source>Out of memory!</source> +<target>記憶體不足!</target> <source>File %x has an invalid date!</source> <target>檔案 %x 的日期無效!</target> @@ -1414,7 +1408,7 @@ Exclude: \stuff\temp\* <target>正在驗證檔案 %x</target> <source>Updating attributes of %x</source> -<target>正在更新 %x 個的屬性</target> +<target>正在更新 %x 個屬性</target> <source>Target directory name must not be empty!</source> <target>目標目錄名稱不能空白!</target> @@ -1458,11 +1452,11 @@ Exclude: \stuff\temp\* <source>Generating database...</source> <target>正在產生資料庫...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>根據配置没有任何同步!</target> +<source>Nothing to synchronize!</source> +<target>沒有什麼東西可同步!</target> -<source>Error copying locked file %x!</source> -<target>複製已鎖定檔案錯誤 %x!</target> +<source>Unable to copy locked file %x!</source> +<target>無法複製被鎖定的檔案 %X!</target> <source>Data verification error: Source and target file have different content!</source> <target>資料驗證錯誤:來源和目標檔案內容不同!</target> diff --git a/BUILD/Languages/croatian.lng b/BUILD/Languages/croatian.lng index 6bd28bc4..708eda95 100644 --- a/BUILD/Languages/croatian.lng +++ b/BUILD/Languages/croatian.lng @@ -41,7 +41,7 @@ <target>Počisti postavke filtera</target> <source>Create a batch job</source> -<target>Izradi batch zadatak</target> +<target>Izradi slijedni zadatak</target> <source>Synchronization settings</source> <target>Postavke sinkronizacije</target> @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Konfiguriraj filter</target> -<source>Customize columns</source> -<target>Uredi stupce</target> - <source>Global settings</source> <target>Globalne postavke</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Odaberi</target> -<source>Error reading from synchronization database:</source> -<target>Greška pri čitanju iz sinkronizacijske baze:</target> - -<source>Error writing to synchronization database:</source> -<target>Greška pri pisanju u sinkronizacijsku bazu:</target> - <source>Invalid command line: %x</source> <target>Netočna naredba: %x</target> +<source>Info</source> +<target>Info</target> + +<source>Fatal Error</source> +<target>Kritična greška</target> + <source>Windows Error Code %x:</source> <target>Windows greška %x:</target> @@ -140,15 +137,21 @@ <pluralform>%x Bajtova</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Greška pri čitanju iz sinkronizacijske baze:</target> + +<source>Error writing to synchronization database:</source> +<target>Greška pri pisanju u sinkronizacijsku bazu:</target> + +<source>Incompatible synchronization database format:</source> +<target>Nekompatibilan format sinkronizacijske podatkovne baze:</target> + <source>Initial synchronization:</source> <target>Početna sinkronizacija:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>Jedna od FreeFileSync datoteka podatkovne baze još ne postoji:</target> -<source>Incompatible synchronization database format:</source> -<target>Nekompatibilan format sinkronizacijske podatkovne baze:</target> - <source>Database files do not share a common synchronization session:</source> <target>Datoteke podatkovne baze ne dijele zajedničke sinkronizacijske sesije:</target> @@ -174,12 +177,6 @@ <pluralform>%x sek</pluralform> </target> -<source>Info</source> -<target>Info</target> - -<source>Fatal Error</source> -<target>Kritična greška</target> - <source>Error reading file:</source> <target>Greška pri čitanju datoteke:</target> @@ -205,11 +202,14 @@ <source>Error parsing configuration file:</source> <target>Greška pri raščlanjivanju datoteke postavki:</target> -<source>Error moving to Recycle Bin:</source> -<target>Greška pri premještanju u Koš za smeće:</target> +<source>Configuration loaded partially only:</source> +<target>Konfiguracija učitala samo djelomično:</target> -<source>Could not load a required DLL:</source> -<target>Nemože se pokrenuti potrebni DLL:</target> +<source>Unable to move %x to the Recycle Bin!</source> +<target>Nije moguće prebaciti u Koš za smeće</target> + +<source>Cannot load file %x.</source> +<target>Ne mogu učitati datoteku %x.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>Greška pri pristupu servisu particijskog kopiranja!</target> @@ -217,10 +217,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>Stvaranje sjeničnih kopija na WOW63 nije podržano. Molimo koristite 64-bitnu FreeFileSync inačnicu.</target> -<source>Could not determine volume name for file:</source> -<target>Nemože se odrediti naziv particije za datoteku:</target> +<source>Cannot determine volume name for file:</source> +<target>Nemože se ustanoviti naziv datoteke</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>Naziv particije %x dio naziva datoteke %y!</target> <source>/sec</source> @@ -229,8 +229,8 @@ <source>File does not exist:</source> <target>Datoteka ne postoji:</target> -<source>Could not read values for the following XML nodes:</source> -<target>Nemogu pročitati vrijednosti iz slijedećih XML središta:</target> +<source>Cannot read the following XML elements:</source> +<target>Ne mogu čitati slijedeće XML elemente</target> <source>S&ave configuration...</source> <target>&Spremi postavke...</target> @@ -346,19 +346,19 @@ Naredba će biti izvršena kada: <target>Uobičajeno</target> <source>FreeFileSync batch file</source> -<target>FreeFileSync batch datoteka</target> +<target>FreeFileSync slijedna datoteka</target> <source>FreeFileSync configuration</source> <target>FreeFileSync postavke</target> <source>FreeFileSync Batch Job</source> -<target>FreeFileSync Batch zadatak</target> +<target>FreeFileSync Slijedni zadatak</target> <source>Unable to create log file!</source> <target>Nemogu napraviti zapisnik!</target> <source>Batch execution</source> -<target>Batch izvršavanje</target> +<target>Slijedno izvršavanje</target> <source>Stop</source> <target>Zaustavi</target> @@ -469,7 +469,7 @@ Naredba će biti izvršena kada: <target>&Globalne postavke...</target> <source>&Create batch job...</source> -<target>&Izradi batch zadatak...</target> +<target>&Izradi slijedni zadatak...</target> <source>&Export file list...</source> <target>&Izvoz liste datoteka...</target> @@ -543,17 +543,17 @@ Naredba će biti izvršena kada: <source>Speed:</source> <target>Brzina:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Vremena preostalo:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Vremena prošlo:</target> <source>Batch job</source> -<target>Batch zadatak</target> +<target>Slijedni zadatak</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Napravite batch datoteku za automatsku sinkronizaciju. Da bi započeli batch mod dvostruki-klik na fajl ili izvršite pomoću komandne linije: FreeFileSync.exe <ffs_batch datoteka>. Ovo se također može zadati u planeru operacijskog sustava.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>Izradi slijednu datoteku i automatiziraj sinkronizaciju. Za započeti u slijednom modu dvostruki klik na ovu datoteku ili pokrenuti naredbu: FreeFileSync.exe SyncJob.ffs_batch. Ovo također može biti zadano u vašem sistemskom planeru zadataka</target> <source>Help</source> <target>Pomoć</target> @@ -567,9 +567,6 @@ Naredba će biti izvršena kada: <source>Right</source> <target>Desno</target> -<source>Overview</source> -<target>Pregled</target> - <source>Status feedback</source> <target>Status veze</target> @@ -586,7 +583,7 @@ Naredba će biti izvršena kada: <target>Odaberite direktorij izvješća:</target> <source>Batch settings</source> -<target>Batch postavke</target> +<target>Slijedne postavke</target> <source>&Save</source> <target>&Spremi</target> @@ -714,8 +711,8 @@ jednak <source>Published under the GNU General Public License</source> <target>Objavljeno pod licencom GNU General Public</target> -<source>Ignore subsequent errors</source> -<target>Ignoriraj naknadne greške</target> +<source>Ignore further errors</source> +<target>Zanemari buduće greške</target> <source>Hide further error messages during the current process</source> <target>Sakrij iduće poruke grešaka tokom slijedećeg procesa</target> @@ -738,22 +735,22 @@ jednak <source>&No</source> <target>&Ne</target> +<source>Use Recycle Bin</source> +<target>Uporabi Koš za smeće</target> + <source>Delete on both sides</source> <target>Izbriši na obje strane</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Izbriši na obje strane iako je označena datoteka samo na jednoj strani</target> -<source>Use Recycle Bin</source> -<target>Uporabi Koš za smeće</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Samo datoteke/direktorije koji odgovaraju svim filterskim postavkama će biti odabrane za sinkronizaciju. -Napomena: Ime filtra mora biti određeno relativno(!) prema glavnim sinkronizacijskim direktorijima. +Samo datoteke koje odgovaraju svim filterskim postavkama će biti sinkronizirane. +Napomena: Imena datoteka moraju biti srodni s glavnim mapama! </target> <source>Hints:</source> @@ -789,20 +786,20 @@ Isključi: \stuff\temp\* <source>Exclude</source> <target>Isključi</target> -<source>Minimum file size</source> -<target>Minimalna veličina datoteke</target> +<source>Time span</source> +<target>Vremensko ograničenje</target> -<source>Maximum file size</source> -<target>Maksimalna veličina datoteke</target> +<source>File size</source> +<target>Veličina datoteke</target> -<source>&Default</source> -<target>&Zadano</target> +<source>Minimum</source> +<target>Minimum</target> -<source>Move column up</source> -<target>Premakni stupac gore</target> +<source>Maximum</source> +<target>Maksimum</target> -<source>Move column down</source> -<target>Premakni stupac dolje</target> +<source>&Default</source> +<target>&Zadano</target> <source>Transactional file copy</source> <target>Transakcijsko kopiranje datoteke</target> @@ -822,13 +819,7 @@ Isključi: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Prebaci datotečna dopuštenja (Zahtjeva Administratorske ovlasti)</target> -<source>Hidden dialogs:</source> -<target>Skriveni prozori:</target> - -<source>Reset</source> -<target>Resetiraj</target> - -<source>Show hidden dialogs</source> +<source>Restore hidden dialogs</source> <target>Prikaži skrivene prozore</target> <source>External applications</source> @@ -861,8 +852,8 @@ Isključi: \stuff\temp\* <source>Folder pairs</source> <target>Par mape</target> -<source>Compressed view</source> -<target>Prikaz zauzeća</target> +<source>Overview</source> +<target>Pregled</target> <source>Select view</source> <target>Izaberite pogled</target> @@ -891,8 +882,8 @@ Isključi: \stuff\temp\* <source>Exclude all</source> <target>Izdvoji sve</target> -<source>Icon size:</source> -<target>Veličina Ikone</target> +<source>Show icons:</source> +<target>Prikaži ikone:</target> <source>Small</source> <target>Malo</target> @@ -918,6 +909,9 @@ Isključi: \stuff\temp\* <source>Configuration saved!</source> <target>Postavke spremljene!</target> +<source>Never save changes</source> +<target>Nikad ne spremaj promjene</target> + <source>Save changes to current configuration?</source> <target>Spremiti promjene na trenutne postavke?</target> @@ -1029,9 +1023,6 @@ Isključi: \stuff\temp\* <source>Error writing file:</source> <target>Napaka pri pisanju datoteke:</target> -<source>Batch file created successfully!</source> -<target>Batch datoteka uspješno izrađena!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1114,6 +1105,9 @@ Isključi: \stuff\temp\* <source>This year</source> <target>Ove godine</target> +<source>Last x days</source> +<target>Zadnjih x dana</target> + <source>Byte</source> <target>Bajt</target> @@ -1123,11 +1117,8 @@ Isključi: \stuff\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>Filtriraj: Sve parove</target> - -<source>Filter: Single pair</source> -<target>Filtriraj: Sam par</target> +<source>Filter</source> +<target>Filtriranje</target> <source>Direct</source> <target>Neposredno</target> @@ -1153,8 +1144,8 @@ Isključi: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- Duplikat s druge strane k %dir</target> -<source>Restore all hidden dialogs?</source> -<target>Vrati sve skrivene prozore?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>Učini skrivene prozore i upozorenja ponovno vidljivima</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1290,9 +1281,6 @@ Isključi: \stuff\temp\* <source>Error copying file:</source> <target>Greška pri kopiranju datoteke:</target> -<source>Error opening file:</source> -<target>Greška pri otvaranju datoteke:</target> - <source>Error traversing directory:</source> <target>Greška pri prelasku direktorija:</target> @@ -1335,8 +1323,8 @@ Isključi: \stuff\temp\* <source>Preparing synchronization...</source> <target>Pripremam sinkronizaciju</target> -<source>Memory allocation failed!</source> -<target>Neuspješno dodjeljivanje memorije!</target> +<source>Out of memory!</source> +<target>Nedostatak memorije</target> <source>File %x has an invalid date!</source> <target>Datoteka %x ima nevaljan datum!</target> @@ -1491,11 +1479,11 @@ Isključi: \stuff\temp\* <source>Generating database...</source> <target>Izrađujem bazu podataka...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>Po trenutnim postavkama nema ništa za sinkroniziranje!</target> +<source>Nothing to synchronize!</source> +<target>Ništa za sinkronizirati!</target> -<source>Error copying locked file %x!</source> -<target>Greška pri kopiranju zaključane datoteke %x!</target> +<source>Unable to copy locked file %x!</source> +<target>Nemoguće kopirati blokiranu datoteku %x!</target> <source>Data verification error: Source and target file have different content!</source> <target>Greška pri provjeravanju podataka: Izvorna i ciljna datoteka imaju različit sadržaj!</target> diff --git a/BUILD/Languages/czech.lng b/BUILD/Languages/czech.lng index adcaaf17..cd0aa8f0 100644 --- a/BUILD/Languages/czech.lng +++ b/BUILD/Languages/czech.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Nastavení filtru</target> -<source>Customize columns</source> -<target>Vlastní sloupce</target> - <source>Global settings</source> <target>Nastavení programu</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Procházet</target> -<source>Error reading from synchronization database:</source> -<target>Chyba čtení synchronizační databáze:</target> - -<source>Error writing to synchronization database:</source> -<target>Chyba zápisu synchronizační databáze:</target> - <source>Invalid command line: %x</source> <target>Neplatný příkaz: %x</target> +<source>Info</source> +<target>Info</target> + +<source>Fatal Error</source> +<target>Závažná chyba</target> + <source>Windows Error Code %x:</source> <target>Chybový kód Windows %x:</target> @@ -119,7 +116,7 @@ <target>Chybový kód Linux %x:</target> <source>Error resolving symbolic link:</source> -<target>Chyba odkazu zástupce:</target> +<target>Nelze najít odkaz zástupce:</target> <source>%x MB</source> <target>%x MB</target> @@ -140,15 +137,21 @@ <pluralform>%x B</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Nelze číst ze synchronizační databáze:</target> + +<source>Error writing to synchronization database:</source> +<target>Nelze zapsat do synchronizační databáze:</target> + +<source>Incompatible synchronization database format:</source> +<target>Chybný formát synchronizační databáze:</target> + <source>Initial synchronization:</source> <target>Prvotní synchronizace:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>Některý z databázových souborů FreeFileSync neexistuje:</target> -<source>Incompatible synchronization database format:</source> -<target>Chyba formátu synchronizační databáze:</target> - <source>Database files do not share a common synchronization session:</source> <target>Databázové soubory nejsou navzájem komplementární</target> @@ -156,13 +159,13 @@ <target>Vyskytla se chyba!</target> <source>Error reading file attributes:</source> -<target>Chyba čtení atributů souboru:</target> +<target>Nelze číst atributy souboru:</target> <source>Waiting while directory is locked (%x)...</source> <target>Čekání na uzamčení adresáře (%x)</target> <source>Error setting directory lock:</source> -<target>Chyba nastavení zámku adresáře:</target> +<target>Nelze nastavit zámek adresáře:</target> <source> <pluralform>1 sec</pluralform> @@ -174,14 +177,8 @@ <pluralform>%x sekund</pluralform> </target> -<source>Info</source> -<target>Info</target> - -<source>Fatal Error</source> -<target>Závažná chyba</target> - <source>Error reading file:</source> -<target>Chyba čtení souboru:</target> +<target>Nelze číst soubor:</target> <source>Scanning:</source> <target>Zpracováváno:</target> @@ -203,24 +200,27 @@ <target>Chybný konfigurační soubor FreeFileSync!</target> <source>Error parsing configuration file:</source> -<target>Chyba zpracování konfigurace:</target> +<target>Nelze zpracovat konfigurační soubor:</target> + +<source>Configuration loaded partially only:</source> +<target>Konfigurace byla načtena jen částečně:</target> -<source>Error moving to Recycle Bin:</source> -<target>Chyba přesunu do Koše:</target> +<source>Unable to move %x to the Recycle Bin!</source> +<target>Není možné přesunout %x do Koše!</target> -<source>Could not load a required DLL:</source> -<target>Nelze načíst požadovanou knihovnu DLL:</target> +<source>Cannot load file %x.</source> +<target>Nelze načíst soubor %x.</target> <source>Error accessing Volume Shadow Copy Service!</source> -<target>Chyba přístupu ke službě Volume Shadow Copy Service!</target> +<target>Nepodařil se přístup ke službě Volume Shadow Copy Service!</target> <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>Vytváření stínových kopií na WOW64 není podporováno. Prosím použijte 64 bitovou verzi FreeFileSync.</target> -<source>Could not determine volume name for file:</source> -<target>Není možné zjistit jméno jednotky souboru:</target> +<source>Cannot determine volume name for file:</source> +<target>Nelze zjistit jméno jednotky souboru:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>Disk %x není součástí jména souboru %y!</target> <source>/sec</source> @@ -229,8 +229,8 @@ <source>File does not exist:</source> <target>Soubor neexistuje:</target> -<source>Could not read values for the following XML nodes:</source> -<target>Nelze načíst hodnoty následujících XML elementy:</target> +<source>Cannot read the following XML elements:</source> +<target>Nelze načíst následující XML elementy:</target> <source>S&ave configuration...</source> <target>&Uložení konfigurace...</target> @@ -456,9 +456,6 @@ Příkazová řádka je spuštěna pokaždé když: <source>2. &Synchronize...</source> <target>2. &Synchronizovat...</target> -<source>S&witch view</source> -<target>&Změnit zobrazení</target> - <source>&New</source> <target>&Nový</target> @@ -546,16 +543,16 @@ Příkazová řádka je spuštěna pokaždé když: <source>Speed:</source> <target>Rychlost:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Zbývající čas:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Uplynulý čas:</target> <source>Batch job</source> <target>Dávkový soubor</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> <target>Vytvoří dávkový souboru pro automatický provoz. Ke spuštění dávky jednoduše poklikejte na vytvořený soubor nebo jeho jméno zadejte jako parametr při spuštění FreeFileSync: FreeFileSync.exe <jméno_souboru>. Stejně tak můžete ke spuštění využít plánovač úloh vašeho operačního systému.</target> <source>Help</source> @@ -570,9 +567,6 @@ Příkazová řádka je spuštěna pokaždé když: <source>Right</source> <target>Pravý</target> -<source>Overview</source> -<target>Přehled</target> - <source>Status feedback</source> <target>Běh programu</target> @@ -717,7 +711,7 @@ je stejný <source>Published under the GNU General Public License</source> <target>Vydáno pod GNU General Public License (GPL)</target> -<source>Ignore subsequent errors</source> +<source>Ignore further errors</source> <target>Přeskočit další chyby</target> <source>Hide further error messages during the current process</source> @@ -741,22 +735,22 @@ je stejný <source>&No</source> <target>&Ne</target> +<source>Use Recycle Bin</source> +<target>Použít Koš</target> + <source>Delete on both sides</source> <target>Smazat z obou stran</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Smazat na obou stranách i když je soubor vybrán pouze na jedné z nich</target> -<source>Use Recycle Bin</source> -<target>Použít Koš</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Pouze soubory/adresáře odpovídající nastavenému filtru budou vybrány pro synchronizaci. -Poznámka: Filtr je aplikován relativně(!) k cestě synchronizovaných adresářů. +Pouze soubory odpovídající nastavenému filtru budou vybrány pro synchronizaci. +Poznámka: Filtr je aplikován relativně k základním adresářům. </target> <source>Hints:</source> @@ -792,21 +786,21 @@ Vynechat: \někde\něco\* <source>Exclude</source> <target>Vynechat</target> -<source>Minimum file size</source> -<target>Minimální velikost souboru:</target> +<source>Time span</source> +<target>Časové rozmezí</target> + +<source>File size</source> +<target>Velikost souboru</target> + +<source>Minimum</source> +<target>Od</target> -<source>Maximum file size</source> -<target>Maximální velikost souboru:</target> +<source>Maximum</source> +<target>Do</target> <source>&Default</source> <target>&Předdefinované</target> -<source>Move column up</source> -<target>Přesunout sloupec nahoru</target> - -<source>Move column down</source> -<target>Přesunout sloupec dolů</target> - <source>Transactional file copy</source> <target>Bezpečné kopírování souborů</target> @@ -825,14 +819,8 @@ Vynechat: \někde\něco\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Přenést přístupová oprávnění souborů a adresářů (Vyžaduje administrátorké oprávnění)</target> -<source>Hidden dialogs:</source> -<target>Skryté dialogy:</target> - -<source>Reset</source> -<target>Resetovat</target> - -<source>Show hidden dialogs</source> -<target>Zobrazit skryté dialogy</target> +<source>Restore hidden dialogs</source> +<target>Obnovit skryté dialogy</target> <source>External applications</source> <target>Externí aplikace</target> @@ -864,7 +852,7 @@ Vynechat: \někde\něco\* <source>Folder pairs</source> <target>Adresářové páry</target> -<source>Compressed view</source> +<source>Overview</source> <target>Navigační zobrazení</target> <source>Select view</source> @@ -894,8 +882,8 @@ Vynechat: \někde\něco\* <source>Exclude all</source> <target>Vynechat vše</target> -<source>Icon size:</source> -<target>Velikost ikon:</target> +<source>Show icons:</source> +<target>Ikony:</target> <source>Small</source> <target>Malé</target> @@ -921,6 +909,9 @@ Vynechat: \někde\něco\* <source>Configuration saved!</source> <target>Konfigurace uložena.</target> +<source>Never save changes</source> +<target>Nikdy neukládat změny</target> + <source>Save changes to current configuration?</source> <target>Uložit změny do aktuální konfigurace?</target> @@ -1030,10 +1021,7 @@ Vynechat: \někde\něco\* <target>Seznam souborů exportován!</target> <source>Error writing file:</source> -<target>Chyba zápisu souboru:</target> - -<source>Batch file created successfully!</source> -<target>Dávka úspěšně vytvořena!</target> +<target>Nelze zapsat souboru:</target> <source> <pluralform>Object deleted successfully!</pluralform> @@ -1117,6 +1105,9 @@ Vynechat: \někde\něco\* <source>This year</source> <target>Tento rok</target> +<source>Last x days</source> +<target>Za posledních x dní</target> + <source>Byte</source> <target>Byte</target> @@ -1126,11 +1117,8 @@ Vynechat: \někde\něco\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>Filtr: Všechny páry</target> - -<source>Filter: Single pair</source> -<target>Filtr: Jeden pár</target> +<source>Filter</source> +<target>Filtr</target> <source>Direct</source> <target>Zachovat</target> @@ -1156,8 +1144,8 @@ Vynechat: \někde\něco\* <source>- Other side's counterpart to %dir</source> <target>- pouze cesta z opačného panelu</target> -<source>Restore all hidden dialogs?</source> -<target>Obnovit všechny skryté dialogy?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>Povolit opět zobrazování skrytých dialogů a hlášení?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1246,64 +1234,61 @@ Vynechat: \někde\něco\* <target>Nelze nastavit monitorování adresáře:</target> <source>Error when monitoring directories.</source> -<target>Chyba při sledování adresářů.</target> +<target>Nelze pokračovat ve sledování adresářů.</target> <source>Conversion error:</source> <target>Chyba konverze:</target> <source>Error deleting file:</source> -<target>Chyba mazání souboru:</target> +<target>Nelze smazat soubor:</target> <source>Error moving file:</source> -<target>Chyba přesouvání souboru:</target> +<target>Nelze přesunout soubor:</target> <source>Target file already existing!</source> <target>Cílový soubor již existuje!</target> <source>Error moving directory:</source> -<target>Chyba přesouvání adresáře:</target> +<target>Nelze přesunout adresář:</target> <source>Target directory already existing!</source> <target>Cílový adresář již existuje!</target> <source>Error deleting directory:</source> -<target>Chyba mazání adresáře:</target> +<target>Nelze smazat adresář:</target> <source>Error changing modification time:</source> -<target>Chyba nastavení času změny:</target> +<target>Nelze nastavit atribut času změny:</target> <source>Error loading library function:</source> -<target>Chyba načtení knihovny funkcí:</target> +<target>Nepodařilo se načíst funkci z knihovny:</target> <source>Error reading security context:</source> -<target>Chyba při čtení přístupových práv:</target> +<target>Nelze číst přístupová práva:</target> <source>Error writing security context:</source> -<target>Chyba při zápisu přístupových práv:</target> +<target>Nelze zapsat přístupová práva:</target> <source>Error copying file permissions:</source> -<target>Chyba kopírování oprávnění souborů:</target> +<target>Nelze kopírovat oprávnění souboru:</target> <source>Error creating directory:</source> -<target>Chyba vytvoření adresáře:</target> +<target>Nelze vytvořit adresář:</target> <source>Error copying symbolic link:</source> -<target>Chyba kopírování zástupce:</target> +<target>Nelze kopírovat zástupce:</target> <source>Error copying file:</source> -<target>Chyba kopírování souboru:</target> - -<source>Error opening file:</source> -<target>Chyba otevření souboru:</target> +<target>Nelze kopírovat souboru:</target> <source>Error traversing directory:</source> -<target>Chyba procházení adresáře:</target> +<target>Nelze procházet adresář:</target> <source>Endless loop when traversing directory:</source> <target>Zacyklení při procházení adresáře:</target> <source>Error setting privilege:</source> -<target>Chyba nastavení práv:</target> +<target>Nelze nastavit práva:</target> <source>Both sides have changed since last synchronization!</source> <target>Došlo ke změně obou stran od poslední synchronizace!</target> @@ -1338,8 +1323,8 @@ Vynechat: \někde\něco\* <source>Preparing synchronization...</source> <target>Příprava synchronizace...</target> -<source>Memory allocation failed!</source> -<target>Chyba přidělení paměti!</target> +<source>Out of memory!</source> +<target>Nedostatek pracovní paměti!</target> <source>File %x has an invalid date!</source> <target>Soubor %x má chybné datum!</target> @@ -1494,12 +1479,12 @@ Vynechat: \někde\něco\* <source>Generating database...</source> <target>Vytváření databáze...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>Podle dané konfigurace není co synchronizovat!</target> +<source>Nothing to synchronize!</source> +<target>Není co synchronizovat!</target> -<source>Error copying locked file %x!</source> -<target>Chyba kopírování zamčeného souboru %x!</target> +<source>Unable to copy locked file %x!</source> +<target>Nelze kopírovat zamčený souboru %x!</target> <source>Data verification error: Source and target file have different content!</source> -<target>Chyba verifikace dat: Zdrojový a cílový soubor mají rozdílný obsah!</target> +<target>Nezdařila se verifikace dat: Zdrojový a cílový soubor mají rozdílný obsah!</target> diff --git a/BUILD/Languages/danish.lng b/BUILD/Languages/danish.lng index c82d1920..08634a4f 100644 --- a/BUILD/Languages/danish.lng +++ b/BUILD/Languages/danish.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Indstil filter</target> -<source>Customize columns</source> -<target>Rediger kolonner</target> - <source>Global settings</source> <target>Fælles indstillinger</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Gennemse</target> -<source>Error reading from synchronization database:</source> -<target>Fejl i læsning fra synkroniserings databasen:</target> - -<source>Error writing to synchronization database:</source> -<target>Fejl i skrivning til synkroniserings databasen:</target> - <source>Invalid command line: %x</source> <target>Ugyldig kommando: %x</target> +<source>Info</source> +<target>Info</target> + +<source>Fatal Error</source> +<target>Uoprettelig Fejl</target> + <source>Windows Error Code %x:</source> <target>Windows Fejl kode %x:</target> @@ -139,15 +136,21 @@ <pluralform>%x Bytes</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Fejl i læsning fra synkroniserings databasen:</target> + +<source>Error writing to synchronization database:</source> +<target>Fejl i skrivning til synkroniserings databasen:</target> + +<source>Incompatible synchronization database format:</source> +<target>Ukompatibelt synkroniserings database format:</target> + <source>Initial synchronization:</source> <target>Indledende synkronisering:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>En af FreeFileSync database filerne findes ikke endnu:</target> -<source>Incompatible synchronization database format:</source> -<target>Ukompatibelt synkroniserings database format:</target> - <source>Database files do not share a common synchronization session:</source> <target>Database filer deler ikke en fælles synkroniserings session</target> @@ -172,12 +175,6 @@ <pluralform>%x sek</pluralform> </target> -<source>Info</source> -<target>Info</target> - -<source>Fatal Error</source> -<target>Uoprettelig Fejl</target> - <source>Error reading file:</source> <target>Fejl i læsning af fil:</target> @@ -202,11 +199,14 @@ <source>Error parsing configuration file:</source> <target>Fejl i at lave konfigurations filen:</target> -<source>Error moving to Recycle Bin:</source> -<target>Fejl i at flytte til skraldespand:</target> +<source>Configuration loaded partially only:</source> +<target>Konfiguration kun delvist hentet:</target> + +<source>Unable to move %x to the Recycle Bin!</source> +<target>Ude af stand til at flytte %x til skraldespanden!</target> -<source>Could not load a required DLL:</source> -<target>Kunne ikke hente en krævet DLL:</target> +<source>Cannot load file %x.</source> +<target>Kan ikke læse filen %x.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>Fejl i adgang til Enhedens Kopi Service</target> @@ -214,10 +214,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>At lave spejl kopier af WOW64 er ikke understøttet. Brug venligst FreeFileSync 64-bit version.</target> -<source>Could not determine volume name for file:</source> -<target>Kunne ikke finde drev navn til filen:</target> +<source>Cannot determine volume name for file:</source> +<target>Kan ikke bestemme drev navn for filen:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>Drev navn %x ikke en del af filnavn %y!</target> <source>/sec</source> @@ -226,8 +226,8 @@ <source>File does not exist:</source> <target>Filen findes ikke:</target> -<source>Could not read values for the following XML nodes:</source> -<target>Kunne ikke læse værdierne for følgende XML punkter:</target> +<source>Cannot read the following XML elements:</source> +<target>Kan ikke læse følgende XML emner:</target> <source>S&ave configuration...</source> <target>G&em konfiguration...</target> @@ -540,17 +540,17 @@ Kommando linjen bliver afviklet hver gang: <source>Speed:</source> <target>Hastighed:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Tid tilbage:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Tid gået:</target> <source>Batch job</source> <target>Batch job</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Lav en batch til til automatiseret synkronisering. For at starte i batch mode dobbelt-klik på filen eller afvikle via. kommando linjen: FreeFileSync.exe <ffs_batch file>. Dette kan også planlægges i dit operativsystems opgavestyring.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>Lav en batch fil og automatiser synkronisering. For at starte i batch mode dobbelt-klik på filen eller kør kommandoen: FreeFileSync.exe SyncJob.ffs_batch. Dette kan også planlægges i dit systems opgavestyring.</target> <source>Help</source> <target>Hjælp</target> @@ -564,8 +564,8 @@ Kommando linjen bliver afviklet hver gang: <source>Right</source> <target>Højre</target> -<source>Overview</source> -<target>Overblik</target> +<source>Sync setttings</source> +<target>Synkroniser indstillinger</target> <source>Status feedback</source> <target>Status feedback</target> @@ -711,8 +711,8 @@ er det samme <source>Published under the GNU General Public License</source> <target>Udgivet under GNU General Public Licence</target> -<source>Ignore subsequent errors</source> -<target>Ignorer underliggende fejl</target> +<source>Ignore further errors</source> +<target>Ignorer fremtidige fejl</target> <source>Hide further error messages during the current process</source> <target>Skjul yderligere fejl beskeder under nuværende opgave</target> @@ -735,22 +735,22 @@ er det samme <source>&No</source> <target>&Nej</target> +<source>Use Recycle Bin</source> +<target>Brug skraldespanden</target> + <source>Delete on both sides</source> <target>Slet på begge sider</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Slet på begge sider selvom der kun er valgt en side</target> -<source>Use Recycle Bin</source> -<target>Brug skraldespanden</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Kun filer/biblioteker der passer til alle filter indstillinger vil blive valgt til synkronisering. -Bemærk: Navnefilteret skal være faktisk specificeret(!) til hoved synkroniserings bibliotekerne. +Synkroniserer kun filer der passer alle filtre. +Note: Fil navne må skal passe til grund bibliotekerne! </target> <source>Hints:</source> @@ -786,20 +786,20 @@ Udeluk: \ting\temp\* <source>Exclude</source> <target>Udeluk</target> -<source>Minimum file size</source> -<target>Minimum fil størrelse</target> +<source>Time span</source> +<target>Tidsrum</target> -<source>Maximum file size</source> -<target>Maksimum fil størrelse</target> +<source>File size</source> +<target>Fil Størrelse</target> -<source>&Default</source> -<target>&Standard</target> +<source>Minimum</source> +<target>Minimum</target> -<source>Move column up</source> -<target>Flyt kolonne op</target> +<source>Maximum</source> +<target>Maksimum</target> -<source>Move column down</source> -<target>Flyt kolonne ned</target> +<source>&Default</source> +<target>&Standard</target> <source>Transactional file copy</source> <target>Transaktionel fil kopiering</target> @@ -819,14 +819,8 @@ Udeluk: \ting\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Overfør fil og biblioteks tilladelser (Kræver Administrator rettigheder)</target> -<source>Hidden dialogs:</source> -<target>Skjulte dialoger:</target> - -<source>Reset</source> -<target>Nulstil</target> - -<source>Show hidden dialogs</source> -<target>Vi skjulte dialoger</target> +<source>Restore hidden dialogs</source> +<target>Gendan skjulte dialoger</target> <source>External applications</source> <target>Eksterne programmer</target> @@ -858,8 +852,8 @@ Udeluk: \ting\temp\* <source>Folder pairs</source> <target>Mappe par</target> -<source>Compressed view</source> -<target>Komprimmeret tilstand</target> +<source>Overview</source> +<target>Overblik</target> <source>Select view</source> <target>Vælg udseende</target> @@ -888,8 +882,8 @@ Udeluk: \ting\temp\* <source>Exclude all</source> <target>Fravælg alle</target> -<source>Icon size:</source> -<target>Ikon størrelse:</target> +<source>Show icons:</source> +<target>Vis ikoner:</target> <source>Small</source> <target>Lille</target> @@ -915,6 +909,9 @@ Udeluk: \ting\temp\* <source>Configuration saved!</source> <target>Konfiguration gemt!</target> +<source>Never save changes</source> +<target>Gem aldrig ændringer</target> + <source>Save changes to current configuration?</source> <target>Gem ændringer til nuværende konfiguration?</target> @@ -1026,9 +1023,6 @@ Udeluk: \ting\temp\* <source>Error writing file:</source> <target>Fejl i at skrive fil:</target> -<source>Batch file created successfully!</source> -<target>Batch fil oprettet!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1107,6 +1101,9 @@ Udeluk: \ting\temp\* <source>This year</source> <target>Dette år</target> +<source>Last x days</source> +<target>Sidste x dage</target> + <source>Byte</source> <target>Byte</target> @@ -1116,11 +1113,8 @@ Udeluk: \ting\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>Filter: Alle par</target> - -<source>Filter: Single pair</source> -<target>Filter: Par</target> +<source>Filter</source> +<target>Filter</target> <source>Direct</source> <target>Direkte</target> @@ -1146,8 +1140,8 @@ Udeluk: \ting\temp\* <source>- Other side's counterpart to %dir</source> <target>- Modsatte sides modpart til %dir</target> -<source>Restore all hidden dialogs?</source> -<target>Gendan alle skjulte dialoger?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>Lav skjulte dialoger og advarselsbeskeder synlige igen?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1323,8 +1317,8 @@ Udeluk: \ting\temp\* <source>Preparing synchronization...</source> <target>Forbereder synkronisering...</target> -<source>Memory allocation failed!</source> -<target>Hukommelses fejl!</target> +<source>Out of memory!</source> +<target>Ude af hukommelse!</target> <source>File %x has an invalid date!</source> <target>Filen %x har en ugyldig dato!</target> @@ -1479,11 +1473,11 @@ Udeluk: \ting\temp\* <source>Generating database...</source> <target>Opretter database...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>Intet at synkroniserer ifølge dokumentationen!</target> +<source>Nothing to synchronize!</source> +<target>Intet at synkronisere!</target> -<source>Error copying locked file %x!</source> -<target>Fejl i kopiering af låst fil %x!</target> +<source>Unable to copy locked file %x!</source> +<target>Ude af stand til at kopiere låst fil %x!</target> <source>Data verification error: Source and target file have different content!</source> <target>Data godkendelses fejl: Kilde og destinations fil har forskelligt indhold!</target> diff --git a/BUILD/Languages/dutch.lng b/BUILD/Languages/dutch.lng index 5e47f202..9a2ac4f7 100644 --- a/BUILD/Languages/dutch.lng +++ b/BUILD/Languages/dutch.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Filter configuratie</target> -<source>Customize columns</source> -<target>Aanpassen kolommen</target> - <source>Global settings</source> <target>Algemene instellingen</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Verkennen</target> -<source>Error reading from synchronization database:</source> -<target>Fout tijdens uitlezen van synchronisatie-database:</target> - -<source>Error writing to synchronization database:</source> -<target>Fout tijdens schrijven naar synchronisatie-database:</target> - <source>Invalid command line: %x</source> <target>Ongeldige opdrachtregel: %x</target> +<source>Info</source> +<target>Info</target> + +<source>Fatal Error</source> +<target>Fatale fout</target> + <source>Windows Error Code %x:</source> <target>Windows Fout Code %x:</target> @@ -139,15 +136,21 @@ <pluralform>%x Bytes</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Fout tijdens uitlezen van synchronisatie-database:</target> + +<source>Error writing to synchronization database:</source> +<target>Fout tijdens schrijven naar synchronisatie-database:</target> + +<source>Incompatible synchronization database format:</source> +<target>Opmaak van synchronisatie-database komt niet overeen:</target> + <source>Initial synchronization:</source> <target>Initiële synchronisatie:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>Eén van de FreeFileSync database bestanden bestaat nog niet:</target> -<source>Incompatible synchronization database format:</source> -<target>Opmaak van synchronisatie-database komt niet overeen:</target> - <source>Database files do not share a common synchronization session:</source> <target>Database bestanden delen geen gezamelijke synchronisatie sessie:</target> @@ -172,12 +175,6 @@ <pluralform>%x sec</pluralform> </target> -<source>Info</source> -<target>Info</target> - -<source>Fatal Error</source> -<target>Fatale fout</target> - <source>Error reading file:</source> <target>Fout tijdens lezen van bestand:</target> @@ -202,11 +199,14 @@ <source>Error parsing configuration file:</source> <target>Fout tijdens verwerking configuratiebestand:</target> -<source>Error moving to Recycle Bin:</source> -<target>Fout tijdens verplaatsen naar prullenbak:</target> +<source>Configuration loaded partially only:</source> +<target>Configuratie alleen gedeeltelijk geladen:</target> -<source>Could not load a required DLL:</source> -<target>Kon een benodigde DLL niet laden:</target> +<source>Unable to move %x to the Recycle Bin!</source> +<target>Niet mogelijk om %x naar de Prullenbak te verplaatsen!</target> + +<source>Cannot load file %x.</source> +<target>Kan bestand %x niet laden.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>Fout bij toegang tot Volume Schaduwkopie Service!</target> @@ -214,10 +214,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>Het aanmaken van schaduwkopieën op WOW64 wordt niet ondersteund. Gebruik alstublieft de 64-bit versie van FreeFileSync.</target> -<source>Could not determine volume name for file:</source> -<target>Kon de schijfnaam niet vaststellen van bestand:</target> +<source>Cannot determine volume name for file:</source> +<target>Kan volumenaam niet bepalen voor bestand:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>Schijfnaam %x maakt geen deel uit van bestandsnaam %y!</target> <source>/sec</source> @@ -226,8 +226,8 @@ <source>File does not exist:</source> <target>Bestand bestaat niet:</target> -<source>Could not read values for the following XML nodes:</source> -<target>Kon geen waarden inlezen voor de volgende XML punten:</target> +<source>Cannot read the following XML elements:</source> +<target>Kan de volgende XML elementen niet lezen:</target> <source>S&ave configuration...</source> <target>Sl&a configuratie op...</target> @@ -433,7 +433,7 @@ De opdrachtregel wordt telkens uitgevoerd indien: <target>Drag en drop</target> <source>Close progress dialog</source> -<target>Sluit proce dialoog</target> +<target>Sluit voortgangsvenster</target> <source>Shut down</source> <target>Afsluiten</target> @@ -540,17 +540,17 @@ De opdrachtregel wordt telkens uitgevoerd indien: <source>Speed:</source> <target>Snelheid:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Benodigde tijd:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Verstreken tijd:</target> <source>Batch job</source> <target>Taaklijst</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Maak een batch bestand voor automatische synchronisatie. Om te starten in batch mode kunt u simpel dubbelklikken op het bestand of uitvoeren via de opdrachtregel: FreeFileSync.exe <ffs_batchbestand>. Dit kan ook worden gepland in de taakplanner van uw besturingssysteem.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>Maak een batch bestand en automatiseer synchronisatie. Om te starten in batch modus dubbelklik je op dit bestand of voer het volgende commando uit: FreeFileSync.exe SyncJob.ffs_batch. Dit kan ook worden gepland in uw taakplanner van uw systeem.</target> <source>Help</source> <target>Help</target> @@ -564,9 +564,6 @@ De opdrachtregel wordt telkens uitgevoerd indien: <source>Right</source> <target>Rechts</target> -<source>Overview</source> -<target>Overzicht</target> - <source>Status feedback</source> <target>Status terugkoppeling</target> @@ -711,8 +708,8 @@ overeenkomt <source>Published under the GNU General Public License</source> <target>Gepubliceerd onder de GNU General Public License</target> -<source>Ignore subsequent errors</source> -<target>Negeer erop volgende foutmeldingen</target> +<source>Ignore further errors</source> +<target>Negeer verdere foutmeldingen</target> <source>Hide further error messages during the current process</source> <target>Verberg eventuele foutmeldingen gedurende de huidige bewerking</target> @@ -735,22 +732,22 @@ overeenkomt <source>&No</source> <target>&Nee</target> +<source>Use Recycle Bin</source> +<target>Gebruik de prullenbak</target> + <source>Delete on both sides</source> <target>Verwijder aan beide zijdes</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Verwijder aan beide zijdes ook al is het bestand maar aan één zijde geselecteerd</target> -<source>Use Recycle Bin</source> -<target>Gebruik de prullenbak</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Alleen bestanden/mappen die overeenkomen met de filter instellingen worden geselecteerd voor synchronisatie. -Aantekening: De naam van de filter moet relatief gespecificeerd zijn (!) aan de hoofd synchronisatie map. +Alleen bestanden die met alle filter instellingen overeen komen worden gesynchroniseerd. +Opmerking: Bestandsnamen moeten relatief zijn aan de basis mappen! </target> <source>Hints:</source> @@ -786,20 +783,20 @@ Uitsluiten: \stuff\temp\* <source>Exclude</source> <target>Uitsluiten</target> -<source>Minimum file size</source> -<target>Minimale bestandsgrootte</target> +<source>Time span</source> +<target>Tijdspanne</target> -<source>Maximum file size</source> -<target>Maximale bestandsgrootte</target> +<source>File size</source> +<target>Bestandsgrootte</target> -<source>&Default</source> -<target>&Standaard</target> +<source>Minimum</source> +<target>Minimum</target> -<source>Move column up</source> -<target>Verplaats kolom naar boven</target> +<source>Maximum</source> +<target>Maximum</target> -<source>Move column down</source> -<target>Verplaats kolom naar beneden</target> +<source>&Default</source> +<target>&Standaard</target> <source>Transactional file copy</source> <target>Transactionele bestands kopie</target> @@ -819,14 +816,8 @@ Uitsluiten: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Zet bestand en map permissies over (Vereist Administrator rechten)</target> -<source>Hidden dialogs:</source> -<target>Verborgen dialogen:</target> - -<source>Reset</source> -<target>Opnieuw instellen</target> - -<source>Show hidden dialogs</source> -<target>Toon verborgen dialogen</target> +<source>Restore hidden dialogs</source> +<target>Herstel verborgen dialogen</target> <source>External applications</source> <target>Externe applicaties</target> @@ -858,8 +849,8 @@ Uitsluiten: \stuff\temp\* <source>Folder pairs</source> <target>Map paren</target> -<source>Compressed view</source> -<target>Compacte weergave</target> +<source>Overview</source> +<target>Overzicht</target> <source>Select view</source> <target>Selecteer weergave</target> @@ -888,8 +879,8 @@ Uitsluiten: \stuff\temp\* <source>Exclude all</source> <target>Alles uitsluiten</target> -<source>Icon size:</source> -<target>Icoon grootte:</target> +<source>Show icons:</source> +<target>Laat pictogrammen zien:</target> <source>Small</source> <target>Klein</target> @@ -915,6 +906,9 @@ Uitsluiten: \stuff\temp\* <source>Configuration saved!</source> <target>Configuratie opgeslagen!</target> +<source>Never save changes</source> +<target>Veranderingen nooit opslaan</target> + <source>Save changes to current configuration?</source> <target>Veranderingen opslaan in de huidige configuratie?</target> @@ -1026,9 +1020,6 @@ Uitsluiten: \stuff\temp\* <source>Error writing file:</source> <target>Fout tijdens schrijven van bestand:</target> -<source>Batch file created successfully!</source> -<target>Taakbestand is succesvol aangemaakt!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1107,6 +1098,9 @@ Uitsluiten: \stuff\temp\* <source>This year</source> <target>Dit jaar</target> +<source>Last x days</source> +<target>Laatste x dagen</target> + <source>Byte</source> <target>Byte</target> @@ -1116,17 +1110,14 @@ Uitsluiten: \stuff\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>Filter: Alle paren</target> - -<source>Filter: Single pair</source> -<target>Filter: Enkel paar</target> +<source>Filter</source> +<target>Filter</target> <source>Direct</source> <target>Direct</target> <source>Follow</source> -<target>Volg</target> +<target>Volgen</target> <source>Copy NTFS permissions</source> <target>Kopiëer NTFS permissies</target> @@ -1146,8 +1137,8 @@ Uitsluiten: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- Tegenhanger andere zijde naar %dir</target> -<source>Restore all hidden dialogs?</source> -<target>Alle verborgen dialogen herstellen?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>Maak verborgen dialogen en waarschuwings berichten opnieuw zichtbaar?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1180,7 +1171,7 @@ Uitsluiten: \stuff\temp\* <target>Gebruik de prullenbak bij verwijderen of overschrijven van bestanden</target> <source>Versioning</source> -<target>Versieën</target> +<target>Versiebeheer</target> <source>Move files into a time-stamped subdirectory</source> <target>Verplaats de bestanden naar een tijd-gemarkeerde submap</target> @@ -1278,9 +1269,6 @@ Uitsluiten: \stuff\temp\* <source>Error copying file:</source> <target>Fout tijdens kopiëren van bestand:</target> -<source>Error opening file:</source> -<target>Fout tijdens openen van bestand:</target> - <source>Error traversing directory:</source> <target>Fout tijdens doorzoeken van map:</target> @@ -1323,8 +1311,8 @@ Uitsluiten: \stuff\temp\* <source>Preparing synchronization...</source> <target>Synchronisatie voorbereiden</target> -<source>Memory allocation failed!</source> -<target>RAM geheugen error!</target> +<source>Out of memory!</source> +<target>Onvoldoende geheugen!</target> <source>File %x has an invalid date!</source> <target>Bestand %x heeft een ongeldige datum!</target> @@ -1479,11 +1467,11 @@ Uitsluiten: \stuff\temp\* <source>Generating database...</source> <target>Genereren van database...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>Volgens de configuratie hoeft er niets gesynchroniseerd te worden!</target> +<source>Nothing to synchronize!</source> +<target>Niks om te synchroniseren!</target> -<source>Error copying locked file %x!</source> -<target>Fout tijdens kopiëren van vergrendeld bestand %x!</target> +<source>Unable to copy locked file %x!</source> +<target>Niet in staat om vergrendeld bestand %x te synchroniseren!</target> <source>Data verification error: Source and target file have different content!</source> <target>Dataverificatie-fout: Bron en doelbestand hebben verschillende inhoud!</target> diff --git a/BUILD/Languages/english_uk.lng b/BUILD/Languages/english_uk.lng index 40321b96..000b07d0 100644 --- a/BUILD/Languages/english_uk.lng +++ b/BUILD/Languages/english_uk.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Configure filter</target> -<source>Customize columns</source> -<target>Customise columns</target> - <source>Global settings</source> <target>Global settings</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Browse</target> -<source>Error reading from synchronization database:</source> -<target>Error reading from synchronisation database:</target> - -<source>Error writing to synchronization database:</source> -<target>Error writing to synchronisation database:</target> - <source>Invalid command line: %x</source> <target>Invalid command line: %x</target> +<source>Info</source> +<target>Info</target> + +<source>Fatal Error</source> +<target>Fatal Error</target> + <source>Windows Error Code %x:</source> <target>Windows Error Code %x:</target> @@ -139,15 +136,21 @@ <pluralform>%x Bytes</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Error reading from synchronisation database:</target> + +<source>Error writing to synchronization database:</source> +<target>Error writing to synchronisation database:</target> + +<source>Incompatible synchronization database format:</source> +<target>Incompatible synchronisation database format:</target> + <source>Initial synchronization:</source> <target>Initial synchronisation:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>One of the FreeFileSync database files is not yet existing:</target> -<source>Incompatible synchronization database format:</source> -<target>Incompatible synchronisation database format:</target> - <source>Database files do not share a common synchronization session:</source> <target>Database files do not share a common synchronisation session:</target> @@ -172,12 +175,6 @@ <pluralform>%x sec</pluralform> </target> -<source>Info</source> -<target>Info</target> - -<source>Fatal Error</source> -<target>Fatal Error</target> - <source>Error reading file:</source> <target>Error reading file:</target> @@ -202,11 +199,14 @@ <source>Error parsing configuration file:</source> <target>Error parsing configuration file:</target> -<source>Error moving to Recycle Bin:</source> -<target>Error moving to Recycle Bin:</target> +<source>Configuration loaded partially only:</source> +<target>Configuration loaded partially only:</target> -<source>Could not load a required DLL:</source> -<target>Could not load a required DLL:</target> +<source>Unable to move %x to the Recycle Bin!</source> +<target>Unable to move %x to the Recycle Bin!</target> + +<source>Cannot load file %x.</source> +<target>Cannot load file %x.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>Error accessing Volume Shadow Copy Service!</target> @@ -214,11 +214,11 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</target> -<source>Could not determine volume name for file:</source> -<target>Could not determine volume name for file:</target> +<source>Cannot determine volume name for file:</source> +<target>Cannot determine volume name for file:</target> -<source>Volume name %x not part of filename %y!</source> -<target>Volume name %x not part of filename %y!</target> +<source>Volume name %x not part of file name %y!</source> +<target>Volume name %x not part of file name %y!</target> <source>/sec</source> <target>/sec</target> @@ -226,8 +226,8 @@ <source>File does not exist:</source> <target>File does not exist:</target> -<source>Could not read values for the following XML nodes:</source> -<target>Could not read values for the following XML nodes:</target> +<source>Cannot read the following XML elements:</source> +<target>Cannot read the following XML elements:</target> <source>S&ave configuration...</source> <target>S&ave configuration...</target> @@ -453,9 +453,6 @@ The command line is executed each time: <source>2. &Synchronize...</source> <target>2. &Synchronise...</target> -<source>S&witch view</source> -<target>S&witch view</target> - <source>&New</source> <target>&New</target> @@ -543,17 +540,17 @@ The command line is executed each time: <source>Speed:</source> <target>Speed:</target> -<source>Time remaining:</source> -<target>Time remaining:</target> +<source>Remaining time:</source> +<target>Remaining time:</target> -<source>Time elapsed:</source> -<target>Time elapsed:</target> +<source>Elapsed time:</source> +<target>Elapsed time:</target> <source>Batch job</source> <target>Batch job</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Create a batch file for automated synchronisation. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>Create a batch file and automate synchronisation. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</target> <source>Help</source> <target>Help</target> @@ -567,8 +564,8 @@ The command line is executed each time: <source>Right</source> <target>Right</target> -<source>Overview</source> -<target>Overview</target> +<source>Sync setttings</source> +<target>Sync setttings</target> <source>Status feedback</source> <target>Status feedback</target> @@ -714,8 +711,8 @@ is the same <source>Published under the GNU General Public License</source> <target>Published under the GNU General Public Licence</target> -<source>Ignore subsequent errors</source> -<target>Ignore subsequent errors</target> +<source>Ignore further errors</source> +<target>Ignore further errors</target> <source>Hide further error messages during the current process</source> <target>Hide further error messages during the current process</target> @@ -738,22 +735,22 @@ is the same <source>&No</source> <target>&No</target> +<source>Use Recycle Bin</source> +<target>Use Recycle Bin</target> + <source>Delete on both sides</source> <target>Delete on both sides</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Delete on both sides even if the file is selected on one side only</target> -<source>Use Recycle Bin</source> -<target>Use Recycle Bin</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Only files/directories that match all filter settings will be selected for synchronisation. -Note: The name filter must be specified relative(!) to main synchronisation directories. +Only files that match all filter settings will be synchronised. +Note: File names must be relative to base directories! </target> <source>Hints:</source> @@ -789,20 +786,20 @@ Exclude: \stuff\temp\* <source>Exclude</source> <target>Exclude</target> -<source>Minimum file size</source> -<target>Minimum file size</target> +<source>Time span</source> +<target>Time span</target> -<source>Maximum file size</source> -<target>Maximum file size</target> +<source>File size</source> +<target>File size</target> -<source>&Default</source> -<target>&Default</target> +<source>Minimum</source> +<target>Minimum</target> -<source>Move column up</source> -<target>Move column up</target> +<source>Maximum</source> +<target>Maximum</target> -<source>Move column down</source> -<target>Move column down</target> +<source>&Default</source> +<target>&Default</target> <source>Transactional file copy</source> <target>Transactional file copy</target> @@ -822,14 +819,8 @@ Exclude: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Transfer file and directory permissions (Requires Administrator rights)</target> -<source>Hidden dialogs:</source> -<target>Hidden dialogues:</target> - -<source>Reset</source> -<target>Reset</target> - -<source>Show hidden dialogs</source> -<target>Show hidden dialogues</target> +<source>Restore hidden dialogs</source> +<target>Restore hidden dialogs</target> <source>External applications</source> <target>External applications</target> @@ -861,8 +852,8 @@ Exclude: \stuff\temp\* <source>Folder pairs</source> <target>Folder pairs</target> -<source>Compressed view</source> -<target>Compressed view</target> +<source>Overview</source> +<target>Overview</target> <source>Select view</source> <target>Select view</target> @@ -891,8 +882,8 @@ Exclude: \stuff\temp\* <source>Exclude all</source> <target>Exclude all</target> -<source>Icon size:</source> -<target>Icon size:</target> +<source>Show icons:</source> +<target>Show icons:</target> <source>Small</source> <target>Small</target> @@ -918,6 +909,9 @@ Exclude: \stuff\temp\* <source>Configuration saved!</source> <target>Configuration saved!</target> +<source>Never save changes</source> +<target>Never save changes</target> + <source>Save changes to current configuration?</source> <target>Save changes to current configuration?</target> @@ -1029,9 +1023,6 @@ Exclude: \stuff\temp\* <source>Error writing file:</source> <target>Error writing file:</target> -<source>Batch file created successfully!</source> -<target>Batch file created successfully!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1110,6 +1101,9 @@ Exclude: \stuff\temp\* <source>This year</source> <target>This year</target> +<source>Last x days</source> +<target>Last x days</target> + <source>Byte</source> <target>Byte</target> @@ -1119,11 +1113,8 @@ Exclude: \stuff\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>Filter: All pairs</target> - -<source>Filter: Single pair</source> -<target>Filter: Single pair</target> +<source>Filter</source> +<target>Filter</target> <source>Direct</source> <target>Direct</target> @@ -1149,8 +1140,8 @@ Exclude: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- Other side's counterpart to %dir</target> -<source>Restore all hidden dialogs?</source> -<target>Restore all hidden dialogs?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>Make hidden dialogs and warning messages visible again?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1326,8 +1317,8 @@ Exclude: \stuff\temp\* <source>Preparing synchronization...</source> <target>Preparing synchronisation...</target> -<source>Memory allocation failed!</source> -<target>Memory allocation failed!</target> +<source>Out of memory!</source> +<target>Out of memory!</target> <source>File %x has an invalid date!</source> <target>File %x has an invalid date!</target> @@ -1482,11 +1473,11 @@ Exclude: \stuff\temp\* <source>Generating database...</source> <target>Generating database...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>Nothing to synchronise according to configuration!</target> +<source>Nothing to synchronize!</source> +<target>Nothing to synchronise!</target> -<source>Error copying locked file %x!</source> -<target>Error copying locked file %x!</target> +<source>Unable to copy locked file %x!</source> +<target>Unable to copy locked file %x!</target> <source>Data verification error: Source and target file have different content!</source> <target>Data verification error: Source and target file have different content!</target> diff --git a/BUILD/Languages/finnish.lng b/BUILD/Languages/finnish.lng index 29cfcb60..aaaf3d35 100644 --- a/BUILD/Languages/finnish.lng +++ b/BUILD/Languages/finnish.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Määritä suodin</target> -<source>Customize columns</source> -<target>Sovita sarake</target> - <source>Global settings</source> <target>Yleiset asetukset</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Selaa</target> -<source>Error reading from synchronization database:</source> -<target>Virhe lukiessa täsmäyksen tietokantaa:</target> - -<source>Error writing to synchronization database:</source> -<target>Virhe kirjottaessa täsmäyksen tietokantaa:</target> - <source>Invalid command line: %x</source> <target>Virheellinen komentokehote: %x</target> +<source>Info</source> +<target>Info</target> + +<source>Fatal Error</source> +<target>Kohtalokas virhe</target> + <source>Windows Error Code %x:</source> <target>Windows virhekoodi %x:</target> @@ -139,15 +136,21 @@ <pluralform>%x tavua</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Virhe lukiessa täsmäyksen tietokantaa:</target> + +<source>Error writing to synchronization database:</source> +<target>Virhe kirjottaessa täsmäyksen tietokantaa:</target> + +<source>Incompatible synchronization database format:</source> +<target>Täsmäytyksen tietokannan muoto on virheellinen:</target> + <source>Initial synchronization:</source> <target>Ensi täsmäytys:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>Jokin FreeFileSynk tietokannan tiedostoista puuttuu vielä:</target> -<source>Incompatible synchronization database format:</source> -<target>Täsmäytyksen tietokannan muoto on virheellinen:</target> - <source>Database files do not share a common synchronization session:</source> <target>Kannan tiedostot ovat eri sessioista:</target> @@ -172,12 +175,6 @@ <pluralform>%x s</pluralform> </target> -<source>Info</source> -<target>Info</target> - -<source>Fatal Error</source> -<target>Kohtalokas virhe</target> - <source>Error reading file:</source> <target>Virhe lukiessa tiedostoa:</target> @@ -202,11 +199,14 @@ <source>Error parsing configuration file:</source> <target>Virhe jäsentäessä asetustiedostoa:</target> -<source>Error moving to Recycle Bin:</source> -<target>Virhe siirtäessä Roskakoriin:</target> +<source>Configuration loaded partially only:</source> +<target>Asetukset ladattiin vain osittain:</target> + +<source>Unable to move %x to the Recycle Bin!</source> +<target>Ei voitu siirtää %x Roskakoriin!</target> -<source>Could not load a required DLL:</source> -<target>Tarvittu DLL ei lataudu:</target> +<source>Cannot load file %x.</source> +<target>Tiedostoa %x ei voida ladata.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>Virhe kutsuttaessa Volume Shadow Services!</target> @@ -214,10 +214,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>WOW64 varjokopiointia ei tueta. Käytä FreeFileSync 64-bittistä versiota.</target> -<source>Could not determine volume name for file:</source> -<target>Levyasemaa ei tunnistettu tiedostolle:</target> +<source>Cannot determine volume name for file:</source> +<target>Asemaa ei tunnisteta tiedostolle:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>Osan nimi %x ei esiinny tiedostonimessä %y!</target> <source>/sec</source> @@ -226,8 +226,8 @@ <source>File does not exist:</source> <target>Tiedosto puuttuu:</target> -<source>Could not read values for the following XML nodes:</source> -<target>Tietoja lukeminen epäonnistui, XML jäsen:</target> +<source>Cannot read the following XML elements:</source> +<target>XML elementit lukukelvottimia:</target> <source>S&ave configuration...</source> <target>Asetukset t&allennetaan...</target> @@ -409,7 +409,7 @@ Komento suoritetaan kun: <target>Koko polku</target> <source>Name</source> -<target></target> +<target>Nimi</target> <source>Relative path</source> <target>Suhteellinen polku</target> @@ -433,19 +433,19 @@ Komento suoritetaan kun: <target>Vedä ja pudota</target> <source>Close progress dialog</source> -<target></target> +<target>Sulje etenämän dialoogi</target> <source>Shut down</source> -<target></target> +<target>Sulje</target> <source>Log off</source> -<target></target> +<target>Kirjaudu ulos</target> <source>Standby</source> -<target></target> +<target>Lepotila</target> <source>Hibernate</source> -<target></target> +<target>Hybernaatiotila</target> <source>1. &Compare</source> <target>1. &Vertaa</target> @@ -453,9 +453,6 @@ Komento suoritetaan kun: <source>2. &Synchronize...</source> <target>2. &Täsmäytä...</target> -<source>S&witch view</source> -<target>Vaihda &näkymää</target> - <source>&New</source> <target>&Uusi</target> @@ -543,17 +540,17 @@ Komento suoritetaan kun: <source>Speed:</source> <target>Nopeus:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Aikaa jäljellä:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Kulunut aika:</target> <source>Batch job</source> <target>Eräajo</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Luo eräajotiedosto automaattiselle täsmäykselle. Käynnistä tuplaklikillä tai suorita komentokehoitteessa: FreeFileSync.exe <ffs_batch file>. Voidaan ajastaa käyttöjärjestelmässä (Tehtävien ajoitus).</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>Luo eräajotiedosto automatisoidaksesi täsmäytyksen. Käynnistä tupla-klikkaamalla tai suorita komento: FreeFileSync.exe SyncJob.ffs_batch. Voit ajastaa eräajo Tehtävien ajoitus -toiminnolla.</target> <source>Help</source> <target>Ohje</target> @@ -567,14 +564,11 @@ Komento suoritetaan kun: <source>Right</source> <target>Oikea</target> -<source>Overview</source> -<target>Yleiskatsaus</target> - <source>Status feedback</source> <target>Tilan palaute</target> <source>Show progress dialog</source> -<target></target> +<target>Näytä etenemisen asetukset</target> <source>Error handling</source> <target>Virhe käsitellessä</target> @@ -616,7 +610,7 @@ Komento suoritetaan kun: <target>Poistotapa</target> <source>On completion:</source> -<target></target> +<target>Kun valmis</target> <source>Configuration</source> <target>Asetukset</target> @@ -691,7 +685,7 @@ on sama <target>Koodikieli on C++ käyttäen:</target> <source>Feedback and suggestions are welcome</source> -<target></target> +<target>Palaute ja uudet ideat ovat mieluisia</target> <source>Homepage</source> <target>Kotisivu</target> @@ -714,8 +708,8 @@ on sama <source>Published under the GNU General Public License</source> <target>Julkaistu lisenssillä GNU General Public License</target> -<source>Ignore subsequent errors</source> -<target>Jätä toistuvia virheitä huomiotta</target> +<source>Ignore further errors</source> +<target>Hylkää toistuvat virheviestit</target> <source>Hide further error messages during the current process</source> <target>Piilota toistuvat virheet tässä suorituksessa</target> @@ -738,22 +732,22 @@ on sama <source>&No</source> <target>&Ei</target> +<source>Use Recycle Bin</source> +<target>Käytä Roskakoria</target> + <source>Delete on both sides</source> <target>Poista molemmilta puolilta</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Poista molemmilta puolilta vaikka tiedosto valittu vain toisella puolella</target> -<source>Use Recycle Bin</source> -<target>Käytä Roskakoria</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Täsmäykseen valitaan vain ne tiedostot/hakemistot jotka täyttävät kaikkia kriteerejä. -HUOM: Nimetty suodin on oltava määritelty relatiivisesti(!) päähakemistoon nähden. +Vain ne tiedostot jotka täyttää kaikkia suotimia täsmennetään. +HUOM: Tiedostonimet oltava suhteellisia hakemistoon! </target> <source>Hints:</source> @@ -789,20 +783,20 @@ Sulje pois: \stuff\temp\* <source>Exclude</source> <target>Sulje pois</target> -<source>Minimum file size</source> -<target>Tiedoston pienin koko</target> +<source>Time span</source> +<target>Aikajana</target> -<source>Maximum file size</source> -<target>Tiedoston suurin koko</target> +<source>File size</source> +<target>Tiedosto koko</target> -<source>&Default</source> -<target>&Vakio</target> +<source>Minimum</source> +<target>Pienin</target> -<source>Move column up</source> -<target>Siirrä sarake ylös</target> +<source>Maximum</source> +<target>Enintäin</target> -<source>Move column down</source> -<target>Siirrä sarake alas</target> +<source>&Default</source> +<target>&Vakio</target> <source>Transactional file copy</source> <target>Transaktio pohjainen kopiointi</target> @@ -822,14 +816,8 @@ Sulje pois: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Siirrä tiedosto- ja hakemisto-oikeuksia (Vaatii Järjestelmävalvojan oikeuksia)</target> -<source>Hidden dialogs:</source> -<target>Piilotetut ikkunat:</target> - -<source>Reset</source> -<target>Palauta</target> - -<source>Show hidden dialogs</source> -<target>Näytä piilotetut ikkunat</target> +<source>Restore hidden dialogs</source> +<target>Palauta piilotetut käskyt</target> <source>External applications</source> <target>Ulkopuolinen sovellus</target> @@ -861,8 +849,8 @@ Sulje pois: \stuff\temp\* <source>Folder pairs</source> <target>Hakemistoparit</target> -<source>Compressed view</source> -<target></target> +<source>Overview</source> +<target>Yleiskatsaus</target> <source>Select view</source> <target>Valitse näkymä</target> @@ -886,13 +874,13 @@ Sulje pois: \stuff\temp\* <target>Poista</target> <source>Include all</source> -<target></target> +<target>Valitse kaikki</target> <source>Exclude all</source> -<target></target> +<target>Hylkää kaikki</target> -<source>Icon size:</source> -<target>Koko, kuvake:</target> +<source>Show icons:</source> +<target>Näytä kuvakkeet:</target> <source>Small</source> <target>Pieni</target> @@ -907,7 +895,7 @@ Sulje pois: \stuff\temp\* <target>Valitse aikajana...</target> <source>Default view</source> -<target></target> +<target>Oletusnäkymä</target> <source>Show "%x"</source> <target>Näytä "%x"</target> @@ -918,6 +906,9 @@ Sulje pois: \stuff\temp\* <source>Configuration saved!</source> <target>Asetukset tallennettu!</target> +<source>Never save changes</source> +<target>Muutoksia hylätään aina</target> + <source>Save changes to current configuration?</source> <target>Tallenna asetuksiin tehdyt muutokset?</target> @@ -1029,9 +1020,6 @@ Sulje pois: \stuff\temp\* <source>Error writing file:</source> <target>Virhe kirjottaessa tiedostoa:</target> -<source>Batch file created successfully!</source> -<target>Eräajotiedoston luonti onnistui!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1110,6 +1098,9 @@ Sulje pois: \stuff\temp\* <source>This year</source> <target>Tänä vuonna</target> +<source>Last x days</source> +<target>Viimeiset x päivää</target> + <source>Byte</source> <target>tavua</target> @@ -1119,11 +1110,8 @@ Sulje pois: \stuff\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>Suodata: Kaikki parit</target> - -<source>Filter: Single pair</source> -<target>Suodata: Yksi pari</target> +<source>Filter</source> +<target>Suodin</target> <source>Direct</source> <target>Suoraan</target> @@ -1149,8 +1137,8 @@ Sulje pois: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- Toisen puolen vastaavuus on %dir</target> -<source>Restore all hidden dialogs?</source> -<target>Palauta piilotetut ikkunat?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>Näytetäänkö piiloitetut käskyt ja viestit?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1189,10 +1177,10 @@ Sulje pois: \stuff\temp\* <target>Siirrä tiedostot aikaleimattuun hakemistoon</target> <source>Files</source> -<target></target> +<target>Tiedostot</target> <source>Percentage</source> -<target></target> +<target>Prosenttia</target> <source>%x TB</source> <target>%x TB</target> @@ -1281,9 +1269,6 @@ Sulje pois: \stuff\temp\* <source>Error copying file:</source> <target>Virhe kopioitaessa tiedostoa:</target> -<source>Error opening file:</source> -<target>Virhe avatessa tiedostoa:</target> - <source>Error traversing directory:</source> <target>Virhe hakemistoa läpikäydessä:</target> @@ -1324,10 +1309,10 @@ Sulje pois: \stuff\temp\* <target>Hakemistot riippuvuussuhteessa! Aseta täsmäyssääntöjä varovasti:</target> <source>Preparing synchronization...</source> -<target></target> +<target>Täsmäytys alustetaan...</target> -<source>Memory allocation failed!</source> -<target>Muistin varaus epäonnistui!</target> +<source>Out of memory!</source> +<target>Muisti loppui!</target> <source>File %x has an invalid date!</source> <target>Tiedostolla %x on virheellinen päiväys!</target> @@ -1378,7 +1363,7 @@ Sulje pois: \stuff\temp\* <target>Ylikirjoita oikea tiedosto/hakemista vasemanpuolisella</target> <source>Overwrite right file/folder with left one</source> -<target>Ylikirjoita vasen tiedosto/hakemista oikeannpuolisella</target> +<target>Ylikirjoita oikea tiedosto/hakemista oikeannpuolisella</target> <source>Do nothing</source> <target>Älä tee mitään</target> @@ -1444,7 +1429,7 @@ Sulje pois: \stuff\temp\* <target>Kohdehakemisto ei saa olla tyhjä!</target> <source>Directory for file versioning was not supplied!</source> -<target></target> +<target>Versioinnin hakemisto antamatta!</target> <source>Source directory does not exist anymore:</source> <target>Lähdehakemisto puuttuu:</target> @@ -1482,11 +1467,11 @@ Sulje pois: \stuff\temp\* <source>Generating database...</source> <target>Luodaan tietokantaa...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>Asetusten mukaan ei löydy täsmäytettävää!</target> +<source>Nothing to synchronize!</source> +<target>Ei mitään täsmäytettävää!</target> -<source>Error copying locked file %x!</source> -<target>Virhe kopioitaessa lukittua tiedostoa %x!</target> +<source>Unable to copy locked file %x!</source> +<target>Kopioimatta, lukittu tiedosto %x</target> <source>Data verification error: Source and target file have different content!</source> <target>Tiedon varmennusvirhe: Lähteellä ja kohteella on eri sisältö!</target> diff --git a/BUILD/Languages/french.lng b/BUILD/Languages/french.lng index bf7620ba..cd613d6b 100644 --- a/BUILD/Languages/french.lng +++ b/BUILD/Languages/french.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Configuration des filtres</target> -<source>Customize columns</source> -<target>Personnaliser les colonnes</target> - <source>Global settings</source> <target>Paramètres généraux</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Parcourir</target> -<source>Error reading from synchronization database:</source> -<target>Erreur lors de la lecture de la base de données de synchro :</target> - -<source>Error writing to synchronization database:</source> -<target>Erreur lors de l'écriture de la base de données de synchro :</target> - <source>Invalid command line: %x</source> <target>Ligne de commande incorrecte : %x</target> +<source>Info</source> +<target>Info</target> + +<source>Fatal Error</source> +<target>Erreur Fatale</target> + <source>Windows Error Code %x:</source> <target>Code erreur Windows %x :</target> @@ -139,15 +136,21 @@ <pluralform>%x octets</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Erreur lors de la lecture de la base de données de synchro :</target> + +<source>Error writing to synchronization database:</source> +<target>Erreur lors de l'écriture de la base de données de synchro :</target> + +<source>Incompatible synchronization database format:</source> +<target>Format de la base de données de synchro incompatible :</target> + <source>Initial synchronization:</source> <target>Première synchronisation :</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>L'un des fichiers de la base de données FreeFileSync n'existe plus :</target> -<source>Incompatible synchronization database format:</source> -<target>Format de la base de données de synchro incompatible :</target> - <source>Database files do not share a common synchronization session:</source> <target>Les fichiers de la base de données ne font pas partie de la même session de synchronisation</target> @@ -172,12 +175,6 @@ <pluralform>%x sec</pluralform> </target> -<source>Info</source> -<target>Info</target> - -<source>Fatal Error</source> -<target>Erreur Fatale</target> - <source>Error reading file:</source> <target>Erreur lors de la lecture du fichier :</target> @@ -202,11 +199,14 @@ <source>Error parsing configuration file:</source> <target>Erreur lors de l'analyse du fichier de configuration :</target> -<source>Error moving to Recycle Bin:</source> -<target>Erreur lors du déplacement dans la Corbeille :</target> +<source>Configuration loaded partially only:</source> +<target>Seule une partie de la configuration a été chargée :</target> -<source>Could not load a required DLL:</source> -<target>Impossible de charger une DLL :</target> +<source>Unable to move %x to the Recycle Bin!</source> +<target>Impossible de déplacer %x dans la Corbeille !</target> + +<source>Cannot load file %x.</source> +<target>Impossible de charger le fichier %x.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>Erreur lors de l'accès au Volume Shadow Copy Service !</target> @@ -214,10 +214,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>La copie en tâche de fond sur WOW64 n'est pas possible. Utilisez pour cela la version 64 bits de FreeFileSync.</target> -<source>Could not determine volume name for file:</source> -<target>Impossible de trouver le nom de volume pour le fichier :</target> +<source>Cannot determine volume name for file:</source> +<target>Impossible de trouver le nom du volume du fichier :</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>Le nom de volume %x ne fait pas partie du nom de fichier %y !</target> <source>/sec</source> @@ -226,8 +226,8 @@ <source>File does not exist:</source> <target>Le fichier n'existe pas :</target> -<source>Could not read values for the following XML nodes:</source> -<target>Impossible de lire les valeurs des noeuds XML suivants :</target> +<source>Cannot read the following XML elements:</source> +<target>Impossible de lire les données XML suivantes :</target> <source>S&ave configuration...</source> <target>S&auvegarder la configuration...</target> @@ -343,13 +343,13 @@ La ligne de commande est exécutée chaque fois que : <target>Personnaliser</target> <source>FreeFileSync batch file</source> -<target>FreeFileSync fichier de commandes</target> +<target>fichier batch FreeFileSync</target> <source>FreeFileSync configuration</source> <target>FreeFileSync configuration</target> <source>FreeFileSync Batch Job</source> -<target>FreeFileSync Fichier de commandes</target> +<target>Traitement batch FreeFileSync</target> <source>Unable to create log file!</source> <target>Impossible de créer un fichier log !</target> @@ -540,17 +540,17 @@ La ligne de commande est exécutée chaque fois que : <source>Speed:</source> <target>Vitesse :</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Temps restant :</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Temps écoulé :</target> <source>Batch job</source> -<target>Fichier de commandes</target> +<target>Traitement batch</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Créer un fichier batch pour la synchronisation automatique. Pour lancer le mode batch il suffit de double-cliquer sur le fichier ou d'exécuter sur la ligne de commande : FreeFileSync.exe <fichier ffs_batch>. Vous pouvez aussi paramètrer le traitement dans le planificateur de tâches de votre système d'exploitation.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>Crée un fichier batch et une synchronisation automatique. Pour démarrer en mode batch double-cliquez sur ce fichier ou exécutez la commande : FreeFileSync.exe SyncJob.ffs_batch. Vous pouvez aussi utilisez le planificateur de tâches de votre système.</target> <source>Help</source> <target>Aide</target> @@ -564,14 +564,11 @@ La ligne de commande est exécutée chaque fois que : <source>Right</source> <target>Droite</target> -<source>Overview</source> -<target>Présentation</target> - <source>Status feedback</source> <target>Retour d'informations</target> <source>Show progress dialog</source> -<target>Montrer la fenêtre de prograssion</target> +<target>Montrer la fenêtre de progression</target> <source>Error handling</source> <target>Erreur de gestion de fichiers</target> @@ -711,8 +708,8 @@ est identique <source>Published under the GNU General Public License</source> <target>Publié sous licence GNU General Public License</target> -<source>Ignore subsequent errors</source> -<target>Ignorer les erreurs ultérieures</target> +<source>Ignore further errors</source> +<target>Ignorer les erreurs suivantes</target> <source>Hide further error messages during the current process</source> <target>Masquer les messages d'erreur suivants pendant le traitement</target> @@ -735,22 +732,22 @@ est identique <source>&No</source> <target>&Non</target> +<source>Use Recycle Bin</source> +<target>Utiliser la Corbeille</target> + <source>Delete on both sides</source> <target>Suppression des deux côtés</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Suppression des deux côtés même si le fichier n'est sélectionné que d'un seul côté</target> -<source>Use Recycle Bin</source> -<target>Utiliser la Corbeille</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Seuls les fichiers / répertoires qui correspondent à tous les paramètres de filtrage seront sélectionnés pour la synchronisation. -Note: Le définition du filtre doit être relative (!) aux répertoires principaux de la synchronisation. +Seuls les fichiers correspondant à tous les paramètres de filtrage seront synchronisés. +Attention : les noms de fichiers doivent être relatifs aux répertoires de base ! </target> <source>Hints:</source> @@ -786,20 +783,20 @@ Exclude: \stuff\temp\* <source>Exclude</source> <target>Exclure</target> -<source>Minimum file size</source> -<target>Taille minimale du fichier</target> +<source>Time span</source> +<target>Durée</target> -<source>Maximum file size</source> -<target>Taille maximale du fichier</target> +<source>File size</source> +<target>Taille du fichier</target> -<source>&Default</source> -<target>&Défaut</target> +<source>Minimum</source> +<target>Minimum</target> -<source>Move column up</source> -<target>Déplacer la colonne vers le haut</target> +<source>Maximum</source> +<target>Maximum</target> -<source>Move column down</source> -<target>Déplacer la colonne vers le bas</target> +<source>&Default</source> +<target>&Défaut</target> <source>Transactional file copy</source> <target>Copie de fichiers transactionnelle</target> @@ -819,13 +816,7 @@ Exclude: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Transfert des attributs système des fichiers et des répertoires (avec les droits administrateur)</target> -<source>Hidden dialogs:</source> -<target>Boîtes de dialogue masquées :</target> - -<source>Reset</source> -<target>Réinitialiser</target> - -<source>Show hidden dialogs</source> +<source>Restore hidden dialogs</source> <target>Afficher les boîtes de dialogue masquées</target> <source>External applications</source> @@ -858,8 +849,8 @@ Exclude: \stuff\temp\* <source>Folder pairs</source> <target>Paires de dossiers</target> -<source>Compressed view</source> -<target>Vue compressé</target> +<source>Overview</source> +<target>Présentation</target> <source>Select view</source> <target>Choisissez une vue</target> @@ -888,8 +879,8 @@ Exclude: \stuff\temp\* <source>Exclude all</source> <target>Exclure tout</target> -<source>Icon size:</source> -<target>Taille des icônes :</target> +<source>Show icons:</source> +<target>Afficher les icones :</target> <source>Small</source> <target>Petit</target> @@ -915,6 +906,9 @@ Exclude: \stuff\temp\* <source>Configuration saved!</source> <target>Configuration enregistrée !</target> +<source>Never save changes</source> +<target>Ne jamais enregistrer les modifications</target> + <source>Save changes to current configuration?</source> <target>Voulez-vous enregistrer les modifications dans la configuration actuelle ?</target> @@ -1026,9 +1020,6 @@ Exclude: \stuff\temp\* <source>Error writing file:</source> <target>Erreur lors de l'écriture du fichier :</target> -<source>Batch file created successfully!</source> -<target>Fichier de traitement batch créé avec succès !</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1107,6 +1098,9 @@ Exclude: \stuff\temp\* <source>This year</source> <target>Cette année</target> +<source>Last x days</source> +<target>Derniers x jours</target> + <source>Byte</source> <target>Octet</target> @@ -1116,11 +1110,8 @@ Exclude: \stuff\temp\* <source>MB</source> <target>Mo</target> -<source>Filter: All pairs</source> -<target>Filtre : Toutes les paires</target> - -<source>Filter: Single pair</source> -<target>Filtre : Une seule paire</target> +<source>Filter</source> +<target>Filtre</target> <source>Direct</source> <target>Direct</target> @@ -1146,8 +1137,8 @@ Exclude: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- équivalent de %dir de l'autre côté</target> -<source>Restore all hidden dialogs?</source> -<target>Restaurer toutes les boîtes de dialogue cachées ?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>Rendre de nouveau visibles les boîtes de dialogue et les messages d'avertissement ?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1278,9 +1269,6 @@ Exclude: \stuff\temp\* <source>Error copying file:</source> <target>Erreur lors de la copie du fichier :</target> -<source>Error opening file:</source> -<target>Erreur lors de l'ouverture du fichier :</target> - <source>Error traversing directory:</source> <target>Erreur lors du parcours du répertoire :</target> @@ -1323,8 +1311,8 @@ Exclude: \stuff\temp\* <source>Preparing synchronization...</source> <target>Synchronisation en cours de préparation ...</target> -<source>Memory allocation failed!</source> -<target>Erreur d'allocation de mémoire!</target> +<source>Out of memory!</source> +<target>Mémoire insuffisante !</target> <source>File %x has an invalid date!</source> <target>Le fichier %x a une date invalide !</target> @@ -1479,11 +1467,11 @@ Exclude: \stuff\temp\* <source>Generating database...</source> <target>Génération de la base de données...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>Rien à synchroniser dans cette configuration !</target> +<source>Nothing to synchronize!</source> +<target>Rien à synchroniser !</target> -<source>Error copying locked file %x!</source> -<target>Erreur lors de la copie du fichier verrouillé %x !</target> +<source>Unable to copy locked file %x!</source> +<target>Impossible de copier le fichier verrouillé %x !</target> <source>Data verification error: Source and target file have different content!</source> <target>Erreur lors du contrôle des données : Les fichiers source et destination ont des contenus différents !</target> diff --git a/BUILD/Languages/german.lng b/BUILD/Languages/german.lng index 6603115e..b671f599 100644 --- a/BUILD/Languages/german.lng +++ b/BUILD/Languages/german.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Konfiguriere Filter</target> -<source>Customize columns</source> -<target>Spalten anpassen</target> - <source>Global settings</source> <target>Globale Einstellungen</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Auswählen</target> -<source>Error reading from synchronization database:</source> -<target>Fehler beim Lesen der Synchronisationsdatenbank:</target> - -<source>Error writing to synchronization database:</source> -<target>Fehler beim Schreiben der Synchronisationsdatenbank:</target> - <source>Invalid command line: %x</source> <target>Ungültige Befehlszeile: %x</target> +<source>Info</source> +<target>Info</target> + +<source>Fatal Error</source> +<target>Schwerer Fehler</target> + <source>Windows Error Code %x:</source> <target>Windows Fehlercode %x:</target> @@ -139,15 +136,21 @@ <pluralform>%x Bytes</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Fehler beim Lesen der Synchronisationsdatenbank:</target> + +<source>Error writing to synchronization database:</source> +<target>Fehler beim Schreiben der Synchronisationsdatenbank:</target> + +<source>Incompatible synchronization database format:</source> +<target>Inkompatibles Datenbankformat:</target> + <source>Initial synchronization:</source> <target>Erstmalige Synchronisation:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>Eine der FreeFileSync Datenbankdateien existiert noch nicht:</target> -<source>Incompatible synchronization database format:</source> -<target>Inkompatibles Datenbankformat:</target> - <source>Database files do not share a common synchronization session:</source> <target>Die Datenbankdateien enthalten keine gemeinsame Synchronisationssitzung:</target> @@ -172,12 +175,6 @@ <pluralform>%x Sek.</pluralform> </target> -<source>Info</source> -<target>Info</target> - -<source>Fatal Error</source> -<target>Schwerer Fehler</target> - <source>Error reading file:</source> <target>Fehler beim Lesen der Datei:</target> @@ -202,11 +199,14 @@ <source>Error parsing configuration file:</source> <target>Fehler beim Auswerten der Konfigurationsdatei:</target> -<source>Error moving to Recycle Bin:</source> -<target>Fehler beim Verschieben in den Papierkorb:</target> +<source>Configuration loaded partially only:</source> +<target>Die Konfiguration wurde nur teilweise geladen:</target> -<source>Could not load a required DLL:</source> -<target>Eine benötigte DLL konnte nicht geladen werden:</target> +<source>Unable to move %x to the Recycle Bin!</source> +<target>%x kann nicht in den Papierkorb verschoben werden!</target> + +<source>Cannot load file %x.</source> +<target>Die Datei %x kann nicht geladen werden.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>Fehler beim Zugriff auf den Volumenschattenkopiedienst!</target> @@ -214,10 +214,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>Das Erstellen von Schattenkopien unter WOW64 wird nicht unterstützt. Bitte benutzen Sie die FreeFileSync 64-Bit Version.</target> -<source>Could not determine volume name for file:</source> -<target>Der Laufwerksname für folgende Datei konnte nicht ermittelt werden:</target> +<source>Cannot determine volume name for file:</source> +<target>Laufwerksname der Datei kann nicht ermittelt werden:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>Laufwerksname %x ist kein Teil des Dateinamens %y!</target> <source>/sec</source> @@ -226,8 +226,8 @@ <source>File does not exist:</source> <target>Die Datei existiert nicht:</target> -<source>Could not read values for the following XML nodes:</source> -<target>Die folgenden XML Knoten konnten nicht gelesen werden:</target> +<source>Cannot read the following XML elements:</source> +<target>Die folgenden XML-Elemente können nicht gelesen werden:</target> <source>S&ave configuration...</source> <target>Konfiguration s&peichern...</target> @@ -453,9 +453,6 @@ Die Befehlszeile wird ausgeführt wenn: <source>2. &Synchronize...</source> <target>2. &Synchronisieren...</target> -<source>S&witch view</source> -<target>Ansicht &wechseln</target> - <source>&New</source> <target>&Neu</target> @@ -543,17 +540,17 @@ Die Befehlszeile wird ausgeführt wenn: <source>Speed:</source> <target>Geschwindigkeit:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Verbleibende Zeit:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Vergangene Zeit:</target> <source>Batch job</source> <target>Batch-Job</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Erzeuge eine Batchdatei für die automatisierte Synchronisation. Um den Batchmodus zu starten, einfach auf die Datei doppelklicken oder über die Befehlszeile ausführen: FreeFileSync.exe <ffs_batch-Datei>. Dies kann auch in den Taskplaner des Betriebssystems eingetragen werden.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>Erzeuge eine Batchdatei für die automatisierte Synchronisation. Um den Batchmodus zu starten, einfach auf diese Datei doppelklicken oder den Befehl ausführen: FreeFileSync.exe SyncJob.ffs_batch. Dies kann auch in den Taskplaner des Betriebssystems eingetragen werden.</target> <source>Help</source> <target>Hilfe</target> @@ -567,8 +564,8 @@ Die Befehlszeile wird ausgeführt wenn: <source>Right</source> <target>Rechts</target> -<source>Overview</source> -<target>Übersicht</target> +<source>Sync setttings</source> +<target>Synchronisationseinstellungen</target> <source>Status feedback</source> <target>Statusrückmeldung</target> @@ -714,8 +711,8 @@ gleich ist <source>Published under the GNU General Public License</source> <target>Veröffentlicht unter der Allgemeinen Öffentlichen GNU-Lizenz</target> -<source>Ignore subsequent errors</source> -<target>Nachfolgende Fehler ignorieren</target> +<source>Ignore further errors</source> +<target>Weitere Fehler ignorieren</target> <source>Hide further error messages during the current process</source> <target>Weitere Fehlermeldungen während des laufenden Prozesses ausblenden</target> @@ -738,22 +735,22 @@ gleich ist <source>&No</source> <target>&Nein</target> +<source>Use Recycle Bin</source> +<target>Papierkorb verwenden</target> + <source>Delete on both sides</source> <target>Auf beiden Seiten löschen</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Lösche auf beiden Seiten, auch wenn die Datei nur auf einer Seite markiert ist</target> -<source>Use Recycle Bin</source> -<target>Papierkorb verwenden</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Für die Synchronisation werden nur Dateien/Verzeichnisse berücksichtigt, die zu allen Filtereinstellungen passen. -Achtung: Der Namensfilter muss relativ zu den Hauptsynchronisationsverzeichnissen eingegeben werden. +Nur Dateien, die zu allen Filtereinstellungen passen, werden synchronisiert. +Achtung: Dateinamen müssen relativ zu den Basisverzeichnissen sein! </target> <source>Hints:</source> @@ -789,20 +786,20 @@ Ausschließen: \stuff\temp\* <source>Exclude</source> <target>Ausschließen</target> -<source>Minimum file size</source> -<target>Minimale Dateigröße</target> +<source>Time span</source> +<target>Zeitspanne</target> -<source>Maximum file size</source> -<target>Maximale Dateigröße</target> +<source>File size</source> +<target>Dateigröße</target> -<source>&Default</source> -<target>&Standard</target> +<source>Minimum</source> +<target>Minimum</target> -<source>Move column up</source> -<target>Spalte nach oben verschieben</target> +<source>Maximum</source> +<target>Maximum</target> -<source>Move column down</source> -<target>Spalte nach unten verschieben</target> +<source>&Default</source> +<target>&Standard</target> <source>Transactional file copy</source> <target>Dateien als Transaktion kopieren</target> @@ -822,14 +819,8 @@ Ausschließen: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Übertrage Datei- und Verzeichnisberechtigungen (Benötigt Administratorrechte)</target> -<source>Hidden dialogs:</source> -<target>Versteckte Dialoge:</target> - -<source>Reset</source> -<target>Zurücksetzen</target> - -<source>Show hidden dialogs</source> -<target>Zeige versteckte Dialoge</target> +<source>Restore hidden dialogs</source> +<target>Versteckte Dialoge wiederherstellen</target> <source>External applications</source> <target>Externe Anwendungen</target> @@ -861,8 +852,8 @@ Ausschließen: \stuff\temp\* <source>Folder pairs</source> <target>Verzeichnispaare</target> -<source>Compressed view</source> -<target>Komprimierte Ansicht</target> +<source>Overview</source> +<target>Übersicht</target> <source>Select view</source> <target>Ansicht auswählen</target> @@ -891,8 +882,8 @@ Ausschließen: \stuff\temp\* <source>Exclude all</source> <target>Alle ausschließen</target> -<source>Icon size:</source> -<target>Symbolgröße</target> +<source>Show icons:</source> +<target>Symbole anzeigen:</target> <source>Small</source> <target>Klein</target> @@ -918,6 +909,9 @@ Ausschließen: \stuff\temp\* <source>Configuration saved!</source> <target>Konfiguration gespeichert!</target> +<source>Never save changes</source> +<target>Änderungen niemals speichern</target> + <source>Save changes to current configuration?</source> <target>Änderungen der aktuellen Konfiguration sichern?</target> @@ -1029,9 +1023,6 @@ Ausschließen: \stuff\temp\* <source>Error writing file:</source> <target>Fehler beim Schreiben der Datei:</target> -<source>Batch file created successfully!</source> -<target>Batchdatei wurde erfolgreich erstellt!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1110,6 +1101,9 @@ Ausschließen: \stuff\temp\* <source>This year</source> <target>Dieses Jahr</target> +<source>Last x days</source> +<target>Letzte x Tage</target> + <source>Byte</source> <target>Byte</target> @@ -1119,11 +1113,8 @@ Ausschließen: \stuff\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>Filter: Alle Verzeichnispaare</target> - -<source>Filter: Single pair</source> -<target>Filter: Einzelnes Verzeichnispaar</target> +<source>Filter</source> +<target>Filter</target> <source>Direct</source> <target>Direkt</target> @@ -1149,8 +1140,8 @@ Ausschließen: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- Entsprechung der anderen Seite zu %dir</target> -<source>Restore all hidden dialogs?</source> -<target>Alle versteckten Dialoge wieder sichtbar machen?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>Versteckte Dialoge und Warnungen wieder sichtbar machen?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1321,13 +1312,13 @@ Ausschließen: \stuff\temp\* <target>Das Verzeichnis existiert nicht:</target> <source>Directories are dependent! Be careful when setting up synchronization rules:</source> -<target>Die Verzeichnisse sind voneinander abhängig! Achtung beim Festlegen der Synchronisationseinstellungen:</target> +<target>Die Verzeichnisse sind voneinander abhängig! Achtung beim Festlegen der Synchronisationsregeln:</target> <source>Preparing synchronization...</source> <target>Bereite Synchronisation vor...</target> -<source>Memory allocation failed!</source> -<target>Speicherallokation fehlgeschlagen!</target> +<source>Out of memory!</source> +<target>Nicht genügend Arbeitsspeicher!</target> <source>File %x has an invalid date!</source> <target>Die Datei %x hat ein ungültiges Datum!</target> @@ -1474,7 +1465,7 @@ Ausschließen: \stuff\temp\* <target>Der Papierkorb ist auf nachfolgenden Verzeichnissen nicht verfügbar! Die Dateien werden stattdessen permanent gelöscht:</target> <source>A directory will be modified which is part of multiple folder pairs! Please review synchronization settings!</source> -<target>Es wird ein Verzeichnis verändert werden, das Teil mehrerer Verzeichnispaare ist! Bitte die Synchronisationseinstellungen prüfen!</target> +<target>Ein Verzeichnis wird verändert werden, das Teil mehrerer Verzeichnispaare ist! Bitte überprüfen Sie die Synchronisationseinstellungen!</target> <source>Processing folder pair:</source> <target>Bearbeite Verzeichnispaar:</target> @@ -1482,11 +1473,11 @@ Ausschließen: \stuff\temp\* <source>Generating database...</source> <target>Erzeuge Synchronisationsdatenbank...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>Nichts zu synchronisieren gemäß den aktuellen Einstellungen!</target> +<source>Nothing to synchronize!</source> +<target>Nichts zu synchronisieren!</target> -<source>Error copying locked file %x!</source> -<target>Fehler beim Kopieren der gesperrten Datei %x!</target> +<source>Unable to copy locked file %x!</source> +<target>Die gesperrte Datei %x kann nicht kopiert werden!</target> <source>Data verification error: Source and target file have different content!</source> <target>Verifizierungsfehler: Quell- und Zieldatei haben unterschiedlichen Inhalt!</target> diff --git a/BUILD/Languages/greek.lng b/BUILD/Languages/greek.lng index 3e436b26..f2bc3878 100644 --- a/BUILD/Languages/greek.lng +++ b/BUILD/Languages/greek.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Ρύθμιση του φίλτρου</target> -<source>Customize columns</source> -<target>Προσαρμογή στηλών</target> - <source>Global settings</source> <target>Γενικές ρυθμίσεις</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Αναζήτηση</target> -<source>Error reading from synchronization database:</source> -<target>Σφάλμα κατά την ανάγνωση από τη βάση δεδομένων συγχρονισμού:</target> - -<source>Error writing to synchronization database:</source> -<target>Σφάλμα κατά την εγγραφή στη βάση δεδομένων συγχρονισμού:</target> - <source>Invalid command line: %x</source> <target>Σφάλμα στη γραμμή εντολών: %x</target> +<source>Info</source> +<target>Πληροφορία</target> + +<source>Fatal Error</source> +<target>Σημαντικό Σφάλμα</target> + <source>Windows Error Code %x:</source> <target>Κωδικός Σφάλματος των Windows %x:</target> @@ -139,15 +136,21 @@ <pluralform>%x Bytes</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Σφάλμα κατά την ανάγνωση από τη βάση δεδομένων συγχρονισμού:</target> + +<source>Error writing to synchronization database:</source> +<target>Σφάλμα κατά την εγγραφή στη βάση δεδομένων συγχρονισμού:</target> + +<source>Incompatible synchronization database format:</source> +<target>Η μορφή της βάσης δεδομένων συγχρονισμού δεν είναι συμβατή:</target> + <source>Initial synchronization:</source> <target>Αρχικός συγχρονισμός:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>Μια από τις βάσεις δεδομένων του FreeFileSync δεν υπάρχει ακόμα:</target> -<source>Incompatible synchronization database format:</source> -<target>Η μορφή της βάσης δεδομένων συγχρονισμού δεν είναι συμβατή:</target> - <source>Database files do not share a common synchronization session:</source> <target>Οι βάσεις δεδομένων δεν έχουν δημιουργηθεί από τον ίδιο συγχρονισμό:</target> @@ -172,12 +175,6 @@ <pluralform>%x δ/λεπτα</pluralform> </target> -<source>Info</source> -<target>Πληροφορία</target> - -<source>Fatal Error</source> -<target>Σημαντικό Σφάλμα</target> - <source>Error reading file:</source> <target>Σφάλμα κατά την ανάγνωση του αρχείου:</target> @@ -202,11 +199,14 @@ <source>Error parsing configuration file:</source> <target>Σφάλμα κατά την ανάλυση του αρχείου διάταξης:</target> -<source>Error moving to Recycle Bin:</source> -<target>Σφάλμα κατά τη μεταφορά στον Κάδο Ανακύκλωσης:</target> +<source>Configuration loaded partially only:</source> +<target>Μόνο ένα τμήμα του αρχείου διάταξης φορτώθηκε:</target> -<source>Could not load a required DLL:</source> -<target>Δεν φορτώθηκε μια απαιτούμενη βιβλιοθήκη DLL:</target> +<source>Unable to move %x to the Recycle Bin!</source> +<target>Δεν ήταν δυνατό να μεταφερθεί το %x στον Κάδο Ανακύκλωσης!</target> + +<source>Cannot load file %x.</source> +<target>Το αρχείο %x δεν ήταν δυνατόν να φορτωθεί.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>Σφάλμα κατά την πρόσβαση στην υπηρεσία Volume Shadow Copy!</target> @@ -214,10 +214,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>Δεν είναι δυνατή η δημιουργία σκιώδους αντίγραφου σε WOW64. Χρησιμοποιείστε την 64-bit έκδοση του FreeFileSync.</target> -<source>Could not determine volume name for file:</source> -<target>Δεν ήταν δυνατό να προσδιοριστεί το όνομα τόμου για το αρχείο:</target> +<source>Cannot determine volume name for file:</source> +<target>Δεν ήταν δυνατό να βρεθεί το όνομα τόμου για το αρχείο:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>Το όνομα τόμου %x δεν είναι μέρος του ονόματος του αρχείου %y!</target> <source>/sec</source> @@ -226,8 +226,8 @@ <source>File does not exist:</source> <target>Το αρχείο δεν υπάρχει:</target> -<source>Could not read values for the following XML nodes:</source> -<target>Δεν αναγνώστηκαν τιμές για τους ακόλουθους κόμβους XML:</target> +<source>Cannot read the following XML elements:</source> +<target>Δεν ήταν δυνατό να αναγνωσθούν τα ακόλουθα στοιχεία XML:</target> <source>S&ave configuration...</source> <target>Α&ποθήκευση διάταξης...</target> @@ -540,17 +540,17 @@ The command line is executed each time: <source>Speed:</source> <target>Ταχύτητα:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Απομένει χρόνος:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Πέρασε χρόνος:</target> <source>Batch job</source> <target>Δέσμη ενεργειών</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Δημιουργία ενός αρχείου δέσμης ενεργειών για αυτόματο συγχρονισμό. Για την έναρξη σε λειτουργία δέσμης, απλά κάντε διπλό κλικ στο αρχείο ή εκτελέστε το μέσω της γραμμής εντολών: FreeFileSync.exe <αρχείο δέσμης>. Αυτή η λειτουργία μπορεί να προγραμματιστεί και στο χρονοδιάγραμμα εργασιών του λειτουργικού σας συστήματος.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>Δημιουργία μιας δέσμης ενεργειών που αυτοματοποιεί το συγχρονισμό. Για να ξεκινήσετε τη λειτουργία δέσμης, απλώς κάντε διπλό κλικ στο αρχείο δέσμης ή πληκτρολογείστε την εντολή: FreeFileSync.exe SyncJob.ffs_batch. Επίσης η ενέργεια αυτή μπορεί να προγραμματιστεί στο χρονοδιάγραμμα εργασιών του υπολογιστή σας.</target> <source>Help</source> <target>Βοήθεια</target> @@ -564,9 +564,6 @@ The command line is executed each time: <source>Right</source> <target>Δεξιά</target> -<source>Overview</source> -<target>Σύνοψη</target> - <source>Status feedback</source> <target>Αναφορά κατάστασης</target> @@ -711,8 +708,8 @@ is the same <source>Published under the GNU General Public License</source> <target>Διανέμεται υπό την Γενική Άδεια Δημόσιας Χρήσης GNU</target> -<source>Ignore subsequent errors</source> -<target>Παράβλεψη των επόμενων σφαλμάτων</target> +<source>Ignore further errors</source> +<target>Αγνόηση επόμενων σφαλμάτων</target> <source>Hide further error messages during the current process</source> <target>Απόκρυψη επόμενων μηνυμάτων σφάλματος στην τρέχουσα διαδικασία</target> @@ -735,22 +732,22 @@ is the same <source>&No</source> <target>&Όχι</target> +<source>Use Recycle Bin</source> +<target>Χρήση του Κάδου Ανακύκλωσης</target> + <source>Delete on both sides</source> <target>Διαγραφή και στις δυο πλευρές</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Διαγραφή και στις δυο πλευρές, ακόμα κι αν το αρχείο έχει επιλεχθεί μόνο στη μια πλευρά</target> -<source>Use Recycle Bin</source> -<target>Χρήση του Κάδου Ανακύκλωσης</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Μόνον αρχεία/υποκατάλογοι που ταιριάζουν με όλες τις ρυθμίσεις φίλτρου θα επιλεχθούν για συγχρονισμό. -Σημείωση: Το φίλτρο ονόματος πρέπει να οριστεί σε σχέση(!) με τους κύριους υποκαταλόγους συγχρονισμού. +Θα συγχρονιστούν μόνον όσα αρχεία πληρούν όλες τις απαιτήσεις των φίλτρων. +Σημείωση: Πρέπει να χρησιμοποιούνται οι σχετικές διαδρομές των αρχείων ως προς τους υποκαταλόγους που συγχρονίζονται. </target> <source>Hints:</source> @@ -786,20 +783,20 @@ Exclude: \stuff\temp\* <source>Exclude</source> <target>Εξαίρεση</target> -<source>Minimum file size</source> -<target>Ελάχιστο μέγεθος αρχείου</target> +<source>Time span</source> +<target>Εύρος χρόνου</target> -<source>Maximum file size</source> -<target>Μέγιστο μέγεθος αρχείου</target> +<source>File size</source> +<target>Μέγεθος αρχείου</target> -<source>&Default</source> -<target>&Προεπιλογή</target> +<source>Minimum</source> +<target>Ελάχιστο</target> -<source>Move column up</source> -<target>Μετακίνηση της στήλης πάνω</target> +<source>Maximum</source> +<target>Μέγιστο</target> -<source>Move column down</source> -<target>Μετακίνηση της στήλης κάτω</target> +<source>&Default</source> +<target>&Προεπιλογή</target> <source>Transactional file copy</source> <target>Συνδιαλλακτική αντιγραφή αρχείων</target> @@ -819,14 +816,8 @@ Exclude: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Μεταφορά των αδειών για τα αρχεία και τους υποκαταλόγους (Απαιτεί δικαιώματα Aministrator)</target> -<source>Hidden dialogs:</source> -<target>Κρυμμένα παράθυρα διαλόγου:</target> - -<source>Reset</source> -<target>Επανεμφάνιση</target> - -<source>Show hidden dialogs</source> -<target>Επανεμφάνιση των κρυμμένων παραθύρων διαλόγου</target> +<source>Restore hidden dialogs</source> +<target>Επανεμφάνιση κρυμμένων μηνυμάτων</target> <source>External applications</source> <target>Εξωτερικές εφαρμογές</target> @@ -858,8 +849,8 @@ Exclude: \stuff\temp\* <source>Folder pairs</source> <target>Ζεύγη υποκαταλόγων</target> -<source>Compressed view</source> -<target>Συμπιεσμένη εμφάνιση</target> +<source>Overview</source> +<target>Σύνοψη</target> <source>Select view</source> <target>Επιλογή εμφάνισης</target> @@ -888,8 +879,8 @@ Exclude: \stuff\temp\* <source>Exclude all</source> <target>Εξαίρεση όλων</target> -<source>Icon size:</source> -<target>Μέγεθος εικονιδίων:</target> +<source>Show icons:</source> +<target>Εμφάνιση εικονιδίων:</target> <source>Small</source> <target>Μικρό</target> @@ -915,6 +906,9 @@ Exclude: \stuff\temp\* <source>Configuration saved!</source> <target>Η διάταξη αποθηκεύτηκε!</target> +<source>Never save changes</source> +<target>Να μην αποθηκεύονται οι αλλαγές</target> + <source>Save changes to current configuration?</source> <target>Να αποθηκευτούν οι αλλαγές στην τρέχουσα διάταξη;</target> @@ -1026,9 +1020,6 @@ Exclude: \stuff\temp\* <source>Error writing file:</source> <target>Σφάλμα κατά την εγγραφή του αρχείου:</target> -<source>Batch file created successfully!</source> -<target>Το αρχείο δέσμης ενεργειών δημιουργήθηκε επιτυχώς!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1107,6 +1098,9 @@ Exclude: \stuff\temp\* <source>This year</source> <target>Αυτό το έτος</target> +<source>Last x days</source> +<target>Τελευταίες x ημέρες</target> + <source>Byte</source> <target>Byte</target> @@ -1116,11 +1110,8 @@ Exclude: \stuff\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>Φίλτρο: Όλα τα ζεύγη</target> - -<source>Filter: Single pair</source> -<target>Φίλτρο: Ένα ζεύγος</target> +<source>Filter</source> +<target>Φίλτρο</target> <source>Direct</source> <target>Ως δεσμό</target> @@ -1146,8 +1137,8 @@ Exclude: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- Ο αντίστοιχος %dir της άλλης πλευράς</target> -<source>Restore all hidden dialogs?</source> -<target>Επανεμφάνιση των κρυμμένων παραθύρων διαλόγου;</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>Να φαίνονται τα παράθυρα και οι αναφορές σφαλμάτων που είχατε διαλέξει να μην εμφανίζονται;</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1278,9 +1269,6 @@ Exclude: \stuff\temp\* <source>Error copying file:</source> <target>Σφάλμα κατά την αντιγραφή του αρχείου:</target> -<source>Error opening file:</source> -<target>Σφάλμα κατά το άνοιγμα του αρχείου:</target> - <source>Error traversing directory:</source> <target>Σφάλμα κατά την ανάλυση του υποκαταλόγου:</target> @@ -1323,8 +1311,8 @@ Exclude: \stuff\temp\* <source>Preparing synchronization...</source> <target>Προετοιμασία του συγχρονισμού...</target> -<source>Memory allocation failed!</source> -<target>Η δέσμευση χώρου μνήμης απέτυχε!</target> +<source>Out of memory!</source> +<target>Ανεπαρκής μνήμη!</target> <source>File %x has an invalid date!</source> <target>Το αρχείο %x δεν έχει έγκυρη ημερομηνία!</target> @@ -1479,11 +1467,11 @@ Exclude: \stuff\temp\* <source>Generating database...</source> <target>Δημιουργία βάσης δεδομένων...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>Τίποτα προς συγχρονισμό με βάση τη διάταξη!</target> +<source>Nothing to synchronize!</source> +<target>Δεν υπάρχει τίποτα προς συγχρονισμό!</target> -<source>Error copying locked file %x!</source> -<target>Σφάλμα κατά την αντιγραφή του κλειδωμένου αρχείου %x !</target> +<source>Unable to copy locked file %x!</source> +<target>Δεν ήταν δυνατό να αντιγραφεί το κλειδωμένο αρχείο %x!</target> <source>Data verification error: Source and target file have different content!</source> <target>Σφάλμα επικύρωσης δεδομένων: Τα αρχεία προέλευσης και προορισμού έχουν διαφορετικό περιεχόμενο!</target> diff --git a/BUILD/Languages/hebrew.lng b/BUILD/Languages/hebrew.lng index 8122b0b1..a55fd05f 100644 --- a/BUILD/Languages/hebrew.lng +++ b/BUILD/Languages/hebrew.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>תצורת מסנן</target> -<source>Customize columns</source> -<target>סדר עמודות</target> - <source>Global settings</source> <target>משתנים גלובליים</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>עיין</target> -<source>Error reading from synchronization database:</source> -<target>שגיאה בקריאה מבסיס הנתונים של הסנכרון:</target> - -<source>Error writing to synchronization database:</source> -<target>שגיאה ברישום לבסיס נתוני סנכרון:</target> - <source>Invalid command line: %x</source> <target>שורת פקודה בלתי חוקית: %x</target> +<source>Info</source> +<target>מידע</target> + +<source>Fatal Error</source> +<target>שגיאה פטלית</target> + <source>Windows Error Code %x:</source> <target>קוד שגיאת חלונות %x:</target> @@ -139,15 +136,21 @@ <pluralform>%x בייט</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>שגיאה בקריאה מבסיס הנתונים של הסנכרון:</target> + +<source>Error writing to synchronization database:</source> +<target>שגיאה ברישום לבסיס נתוני סנכרון:</target> + +<source>Incompatible synchronization database format:</source> +<target>מסד נתונים של הסנכרון לא תואם:</target> + <source>Initial synchronization:</source> <target>סנכרון ראשוני:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>אחד מקובצי בסיס הנתונים הבא עדיין לא קיים</target> -<source>Incompatible synchronization database format:</source> -<target>מסד נתונים של הסנכרון לא תואם:</target> - <source>Database files do not share a common synchronization session:</source> <target>קבצי בסיס הנתונים אינם חולקים ארוע סנכרון משותף:</target> @@ -172,12 +175,6 @@ <pluralform>%x שניות</pluralform> </target> -<source>Info</source> -<target>מידע</target> - -<source>Fatal Error</source> -<target>שגיאה פטלית</target> - <source>Error reading file:</source> <target>שגיאה בקריאת קובץ:</target> @@ -202,11 +199,14 @@ <source>Error parsing configuration file:</source> <target>שגיאה בניתוח קובץ תצורה:</target> -<source>Error moving to Recycle Bin:</source> -<target>שגיאה בהעברה לסל המיחזור:</target> +<source>Configuration loaded partially only:</source> +<target>תצורה נטענה חלקית בלבד:</target> + +<source>Unable to move %x to the Recycle Bin!</source> +<target>לא יכול להעביר את %x לסל המיחזור!</target> -<source>Could not load a required DLL:</source> -<target>:נדרש DLL לא יכל לטעון</target> +<source>Cannot load file %x.</source> +<target>לא יכול לטעון קובץ %x!</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>שגיאה בגישה לשרות Volume Shadow Copy Service</target> @@ -214,11 +214,11 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>לא נתמכת בגרסה זאת אנא התקן גרסה 64 WOW64 העתקת צל ב</target> -<source>Could not determine volume name for file:</source> -<target>לא יכול לקבוע שם כרך לקובץ:</target> +<source>Cannot determine volume name for file:</source> +<target>לא יכול לקבוע שם כונן עבור קובץ:</target> -<source>Volume name %x not part of filename %y!</source> -<target>כנונן %x לא בנתיב של קובץ %y!</target> +<source>Volume name %x not part of file name %y!</source> +<target>ככונן %x לא בנתיב של קובץ %y!</target> <source>/sec</source> <target>/שנ</target> @@ -226,8 +226,8 @@ <source>File does not exist:</source> <target>קובץ לא קיים:</target> -<source>Could not read values for the following XML nodes:</source> -<target>XML לא יכול לקרא ערכים מצמתי :</target> +<source>Cannot read the following XML elements:</source> +<target>לא יכול לקרוא את שמות צמתי XML:</target> <source>S&ave configuration...</source> <target>&שמור תצורה...</target> @@ -453,9 +453,6 @@ The command line is executed each time: <source>2. &Synchronize...</source> <target>2. &סנכרן...</target> -<source>S&witch view</source> -<target>החל&ף תצוגה</target> - <source>&New</source> <target>&חדש</target> @@ -543,17 +540,17 @@ The command line is executed each time: <source>Speed:</source> <target>מהירות:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>זמן נותר:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>זמן עבר:</target> <source>Batch job</source> <target>עבודת אצווה</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>צור קובץ אצווה לסינכרון אוטומטי. הפעל באמצעות הקשה כפולה על הקובץ או באמצעות שורת פקודה: FreeFileSync <ffs_batch_file>. ההפעלה ניתנת לתזמון במתזמן המשימות של המערכת.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>צור קובץ אצווה ומכן הסינכרון. הפעל באמצעות הקשה כפולה על שם הקובץ או הפעל שורת פקודה: FreeFileSync.exe <ffs_batch file>. ההפעלה ניתנת לתזמון במתזמן המשימות של מערכת ההפעלה.</target> <source>Help</source> <target>עזרה</target> @@ -567,9 +564,6 @@ The command line is executed each time: <source>Right</source> <target>שמאל</target> -<source>Overview</source> -<target>מבט כללי</target> - <source>Status feedback</source> <target>משוב מצב</target> @@ -714,8 +708,8 @@ is the same <source>Published under the GNU General Public License</source> <target>מפורסם במסגרת GNU General Public License</target> -<source>Ignore subsequent errors</source> -<target>התעלם משגיאות נישנות</target> +<source>Ignore further errors</source> +<target>התעלם משגיאות נוספות</target> <source>Hide further error messages during the current process</source> <target>הסתר הודעות שגיאה נוספות בהמשך התהליך הנוכחי</target> @@ -738,22 +732,22 @@ is the same <source>&No</source> <target>&לא</target> +<source>Use Recycle Bin</source> +<target>השתמש בסל המיחזור</target> + <source>Delete on both sides</source> <target>מחק בשני הצדדים</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>מחק בשני הצדדים אף אם הקובץ נבחר בצד אחד בלבד</target> -<source>Use Recycle Bin</source> -<target>השתמש בסל המיחזור</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -רק קבצים\מחיצות המתאימים לכל הגדרות המסנן יסומנו לסינכרון. -הערה: השם לסינון חייב להיות מוגדר באוםן יחסי (!) למחיצות הראשיות לסינכרון. +רק קבצים המתאימים לכל הגדרות המסנן יסונכרנו. +הערה: שמות קבצים חייבים להיות מוגדרים באופן יחסי למחיצות הראשיות! </target> <source>Hints:</source> @@ -789,20 +783,20 @@ Exclude: \stuff\temp\* <source>Exclude</source> <target>אל תכלול</target> -<source>Minimum file size</source> -<target>גודל קובץ מינימלי</target> +<source>Time span</source> +<target>תחום זמן</target> -<source>Maximum file size</source> -<target>גודל קובץ מקסימלי</target> +<source>File size</source> +<target>גודל קובץ</target> -<source>&Default</source> -<target>&ברירת מחדל</target> +<source>Minimum</source> +<target>מינימום</target> -<source>Move column up</source> -<target>העלה עמודה</target> +<source>Maximum</source> +<target>מקסימום</target> -<source>Move column down</source> -<target>הורד עמודה</target> +<source>&Default</source> +<target>&ברירת מחדל</target> <source>Transactional file copy</source> <target>העתקת קובץ בעסקה</target> @@ -822,14 +816,8 @@ Exclude: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>העבר הרשאות קבצים ומחיצות (דורש הרשאות מנהל מערכת)</target> -<source>Hidden dialogs:</source> -<target>דיאלוגים מוסתרים:</target> - -<source>Reset</source> -<target>אפס</target> - -<source>Show hidden dialogs</source> -<target>הראה דיאלוגים נסתרים</target> +<source>Restore hidden dialogs</source> +<target>שחזר דיאלוגים מוסתרים</target> <source>External applications</source> <target>תוכנה חיצונית</target> @@ -861,8 +849,8 @@ Exclude: \stuff\temp\* <source>Folder pairs</source> <target>זוגות מחיצות</target> -<source>Compressed view</source> -<target>תצוגה מכווצת</target> +<source>Overview</source> +<target>מבט כללי</target> <source>Select view</source> <target>בחר תצוגה</target> @@ -891,8 +879,8 @@ Exclude: \stuff\temp\* <source>Exclude all</source> <target>הוצא מן הכלל הכל</target> -<source>Icon size:</source> -<target>גודל סמל:</target> +<source>Show icons:</source> +<target>הצג סמלים:</target> <source>Small</source> <target>קטן</target> @@ -918,6 +906,9 @@ Exclude: \stuff\temp\* <source>Configuration saved!</source> <target>תצורה נשמרה!</target> +<source>Never save changes</source> +<target>אל תשמור שינויים לעולם</target> + <source>Save changes to current configuration?</source> <target>שמור שינויים לתצורה נוכחית?</target> @@ -1029,9 +1020,6 @@ Exclude: \stuff\temp\* <source>Error writing file:</source> <target>שגיאה בכתיבת קובץ:</target> -<source>Batch file created successfully!</source> -<target>קובץ אצווה נוצר בהצלחה!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1110,6 +1098,9 @@ Exclude: \stuff\temp\* <source>This year</source> <target>בשנה הנוכחית</target> +<source>Last x days</source> +<target>x ימים אחרונים</target> + <source>Byte</source> <target>בייט</target> @@ -1119,11 +1110,8 @@ Exclude: \stuff\temp\* <source>MB</source> <target>מגה-בייט</target> -<source>Filter: All pairs</source> -<target>כל הזוגות :מסונן</target> - -<source>Filter: Single pair</source> -<target>זוג אחד :מסונן</target> +<source>Filter</source> +<target>מסנן</target> <source>Direct</source> <target>כוון</target> @@ -1149,8 +1137,8 @@ Exclude: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- הצד השני מקביל ל- %dir</target> -<source>Restore all hidden dialogs?</source> -<target>שחזר כל הדיאלוגים הנסתרים?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>להפוך דיאלוגים מוסתרים לגלויים שוב?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1281,9 +1269,6 @@ Exclude: \stuff\temp\* <source>Error copying file:</source> <target>שגיאה בהעתקת קובץ:</target> -<source>Error opening file:</source> -<target>שגיאה בפתיחת קובץ:</target> - <source>Error traversing directory:</source> <target>שגיאה בהצלבת מחיצות</target> @@ -1326,8 +1311,8 @@ Exclude: \stuff\temp\* <source>Preparing synchronization...</source> <target>מכין סינכרון...</target> -<source>Memory allocation failed!</source> -<target>הקצאת זכרון נכשלה!</target> +<source>Out of memory!</source> +<target>תם הזכרון!</target> <source>File %x has an invalid date!</source> <target>קובץ %x מכיל תאריך שגוי!</target> @@ -1482,11 +1467,11 @@ Exclude: \stuff\temp\* <source>Generating database...</source> <target>מיצר בסיס נתונים...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>אין מה לסנכרן ע"פ הקונפיגורציה!</target> +<source>Nothing to synchronize!</source> +<target>אין מה לסנכרן!</target> -<source>Error copying locked file %x!</source> -<target>שגיאה בהעתקת קובץ נעול %x!</target> +<source>Unable to copy locked file %x!</source> +<target>לא ניתן להעתיק קובץ נעול %x!</target> <source>Data verification error: Source and target file have different content!</source> <target>שגיאה של אימות נתונים קובץ מקור ומטרה בעלי תכולת נתונים שונה!</target> diff --git a/BUILD/Languages/hungarian.lng b/BUILD/Languages/hungarian.lng index 07738505..12c7ffb7 100644 --- a/BUILD/Languages/hungarian.lng +++ b/BUILD/Languages/hungarian.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Szűrő beállítása</target> -<source>Customize columns</source> -<target>Oszlopok testreszabása</target> - <source>Global settings</source> <target>Globális beállítások</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Tallózás</target> -<source>Error reading from synchronization database:</source> -<target>Hiba történt a szinkronizációs adatbázis olvasása közben:</target> - -<source>Error writing to synchronization database:</source> -<target>Hiba történt a szinkronizációs adatbázis írása közben:</target> - <source>Invalid command line: %x</source> <target>Érvénytelen parancssor: %x</target> +<source>Info</source> +<target>Információ</target> + +<source>Fatal Error</source> +<target>Kritikus hiba</target> + <source>Windows Error Code %x:</source> <target>Windows hibakód %x:</target> @@ -139,15 +136,21 @@ <pluralform>%x Bájt</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Hiba történt a szinkronizációs adatbázis olvasása közben:</target> + +<source>Error writing to synchronization database:</source> +<target>Hiba történt a szinkronizációs adatbázis írása közben:</target> + +<source>Incompatible synchronization database format:</source> +<target>Inkompatibilis szinkronizációs adatbázis formátum:</target> + <source>Initial synchronization:</source> <target>Első szinkronizáció:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>A FreeFileSync egyik adatbázisfájlja nem létezik:</target> -<source>Incompatible synchronization database format:</source> -<target>Inkompatibilis szinkronizációs adatbázis formátum:</target> - <source>Database files do not share a common synchronization session:</source> <target>Az adatbázisfájlok nem osztoznak egy közös szinkronizációs munkameneten:</target> @@ -172,12 +175,6 @@ <pluralform>%x másodperc</pluralform> </target> -<source>Info</source> -<target>Információ</target> - -<source>Fatal Error</source> -<target>Kritikus hiba</target> - <source>Error reading file:</source> <target>A fájl olvasása sikertelen:</target> @@ -202,11 +199,14 @@ <source>Error parsing configuration file:</source> <target>A beállításokat tartalmazó fájl feldolgozása sikertelen:</target> -<source>Error moving to Recycle Bin:</source> -<target>A Lomtárba (Recycle Bin) mozgatás sikertelen:</target> +<source>Configuration loaded partially only:</source> +<target>A beállításokat csak részben sikerült betölteni:</target> -<source>Could not load a required DLL:</source> -<target>A szükséges DLL betöltése sikertelen:</target> +<source>Unable to move %x to the Recycle Bin!</source> +<target>%x Lomtárba helyezése sikertelen!</target> + +<source>Cannot load file %x.</source> +<target>%x fájl betöltése sikertelen.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>Hiba történt a Volume Shadow Copy szolgáltatás elérése közben!</target> @@ -214,10 +214,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>A Shadow Copy a WOW64-en nem támogatott. Kérjük, használja a 64-bites FreeFileSync-et.</target> -<source>Could not determine volume name for file:</source> -<target>A következő fájlnak nem lehet meghatározni a kötetnevét:</target> +<source>Cannot determine volume name for file:</source> +<target>Nem lehet meghatározni a kötetnevet a következő fájlhoz:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>A(z) %x kötetnevet nem tartalmazza a(z) %y fájlnév!</target> <source>/sec</source> @@ -226,8 +226,8 @@ <source>File does not exist:</source> <target>A következő fájl nem létezik:</target> -<source>Could not read values for the following XML nodes:</source> -<target>A következő XML-csomópontok értékének beolvasása sikertelen:</target> +<source>Cannot read the following XML elements:</source> +<target>A következő XML elemek olvasása sikertelen:</target> <source>S&ave configuration...</source> <target>Beállítások mentés&e...</target> @@ -540,17 +540,17 @@ A parancssor végrehajtódik minden alkalommal, ha: <source>Speed:</source> <target>Sebesség:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Hátralévő idő:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Eltelt idő:</target> <source>Batch job</source> <target>Kötegelt feladat</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Kötegelt feladat fájl létrehozása automatikus szinkronizációhoz. Kötegelt módban történő indításhoz duplán kell kattintani a fájlon, vagy végre kell hajttatni a parancssorból: FreeFileSync.exe <kötegelt feladat fájl>. Az operációs rendszer feladatütemezőjével ez akár ütemezhető is.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>Kötegelt feladat fájl létrehozása és automatikus szinkronizálás. A kötegelt feladat módban való indításhoz csak egyszerűen kattints duplát a fájlon vagy futtasd a következő parancsot: FreeFileSync.exe SzinkFeladat.ffs_batch. Ez ütemezhető is az operációs rendszer ütemezőjének a segítségével.</target> <source>Help</source> <target>Súgó</target> @@ -564,9 +564,6 @@ A parancssor végrehajtódik minden alkalommal, ha: <source>Right</source> <target>Jobb oldal</target> -<source>Overview</source> -<target>Összefoglaló</target> - <source>Status feedback</source> <target>Státusz visszajelzés</target> @@ -712,8 +709,8 @@ a következő személyeknek: <source>Published under the GNU General Public License</source> <target>Kiadva a GNU General Public License alatt</target> -<source>Ignore subsequent errors</source> -<target>Későbbi hibák figyelmen kívül hagyása</target> +<source>Ignore further errors</source> +<target>További hibák figyelmen kívül hagyása</target> <source>Hide further error messages during the current process</source> <target>A további hibaüzenetek elrejtése az aktuális folyamat során</target> @@ -736,22 +733,22 @@ a következő személyeknek: <source>&No</source> <target>&Nem</target> +<source>Use Recycle Bin</source> +<target>Lomtár (Recycle Bin) használata</target> + <source>Delete on both sides</source> <target>Törlés mindkét oldalon</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Törlés mindkét oldalon, még akkor is, ha csak egyik oldalon lett kijelölve</target> -<source>Use Recycle Bin</source> -<target>Lomtár (Recycle Bin) használata</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Csak azok a fájlok/mappák lesznek kiválasztva a szinkronizáláshoz, amelyek minden szűrőbeállításnak megfelelnek. -Megjegyzés: A névszűrésnek relatívnak(!) kell lennie a fő szinkronizációs mappához képest. +Csak azok a fájlok lesznek szinkronizálva, amelyek megfelelnek az összes szűrő beállításnak. +Megjegyzés: A fájlneveknek relatívnak kell lenniük az alap mappához viszonyítva! </target> <source>Hints:</source> @@ -787,20 +784,20 @@ Kizárni: \stuff\temp\* <source>Exclude</source> <target>Kizárni</target> -<source>Minimum file size</source> -<target>Legkisebb fájlméret</target> +<source>Time span</source> +<target>Időtartam</target> -<source>Maximum file size</source> -<target>Legnagyobb fájlméret</target> +<source>File size</source> +<target>Fájlméret</target> -<source>&Default</source> -<target>&Alapértelmezett</target> +<source>Minimum</source> +<target>Minimum</target> -<source>Move column up</source> -<target>Oszlop mozgatása felfelé</target> +<source>Maximum</source> +<target>Maximum</target> -<source>Move column down</source> -<target>Oszlop mozgatása lefelé</target> +<source>&Default</source> +<target>&Alapértelmezett</target> <source>Transactional file copy</source> <target>Tranzakciós fájlmásolás</target> @@ -820,14 +817,8 @@ Kizárni: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Fájlok és mappák jogosultságainak átvitele (Adminisztrátori jogok szükségesek)</target> -<source>Hidden dialogs:</source> -<target>Rejtett párbeszédablakok:</target> - -<source>Reset</source> -<target>Helyreállítás</target> - -<source>Show hidden dialogs</source> -<target>Rejtett párbeszédablakok mutatása</target> +<source>Restore hidden dialogs</source> +<target>Rejtett párbeszédablakok visszaállítása</target> <source>External applications</source> <target>Külső alkalmazások</target> @@ -859,8 +850,8 @@ Kizárni: \stuff\temp\* <source>Folder pairs</source> <target>Mappa párok</target> -<source>Compressed view</source> -<target>Tömörített nézet</target> +<source>Overview</source> +<target>Összefoglaló</target> <source>Select view</source> <target>Nézet kiválasztása</target> @@ -889,8 +880,8 @@ Kizárni: \stuff\temp\* <source>Exclude all</source> <target>Kizárni az összeset</target> -<source>Icon size:</source> -<target>Ikon mérete:</target> +<source>Show icons:</source> +<target>Ikonok mutatása:</target> <source>Small</source> <target>Kicsi</target> @@ -916,8 +907,11 @@ Kizárni: \stuff\temp\* <source>Configuration saved!</source> <target>Beállítások elmentve!</target> +<source>Never save changes</source> +<target>Változtatások figyelmen kívül hagyása</target> + <source>Save changes to current configuration?</source> -<target>Mentsük a beállítások változásait?</target> +<target>Mentsük az aktuális beállítások változásait?</target> <source>Configuration loaded!</source> <target>Beállítások betöltve!</target> @@ -1027,9 +1021,6 @@ Kizárni: \stuff\temp\* <source>Error writing file:</source> <target>A fájl írása sikertelen:</target> -<source>Batch file created successfully!</source> -<target>A kötegelt feladat fájl létrehozása sikerült!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1108,6 +1099,9 @@ Kizárni: \stuff\temp\* <source>This year</source> <target>Idei</target> +<source>Last x days</source> +<target>Utolsó x nap</target> + <source>Byte</source> <target>Bájt</target> @@ -1117,11 +1111,8 @@ Kizárni: \stuff\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>Szűrő: Minden pár</target> - -<source>Filter: Single pair</source> -<target>Szűrő: Egy pár</target> +<source>Filter</source> +<target>Szűrő</target> <source>Direct</source> <target>Közvetlen</target> @@ -1147,8 +1138,8 @@ Kizárni: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- A %dir másik oldalon szereplő párja</target> -<source>Restore all hidden dialogs?</source> -<target>Az összes rejtett párbeszédablakot visszaállítsuk?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>A rejtett párbeszédablakok és figyelmeztető üzenetek újra legyenek láthatóak?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1279,9 +1270,6 @@ Kizárni: \stuff\temp\* <source>Error copying file:</source> <target>A fájl másolása sikertelen:</target> -<source>Error opening file:</source> -<target>A fájl megnyitása sikertelen:</target> - <source>Error traversing directory:</source> <target>A mappa átnézése sikertelen:</target> @@ -1324,8 +1312,8 @@ Kizárni: \stuff\temp\* <source>Preparing synchronization...</source> <target>Szinkronizálás előkészítése...</target> -<source>Memory allocation failed!</source> -<target>Sikertelen memóriafoglalás!</target> +<source>Out of memory!</source> +<target>Elfogyott a szabad memória!</target> <source>File %x has an invalid date!</source> <target>A(z) %x fájlnak érvénytelen a dátuma!</target> @@ -1480,11 +1468,11 @@ Kizárni: \stuff\temp\* <source>Generating database...</source> <target>Adatbázis generálása...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>A beállításoknak megfelelően nincs mit szinkronizálni!</target> +<source>Nothing to synchronize!</source> +<target>Nincs mit szinkronizálni!</target> -<source>Error copying locked file %x!</source> -<target>Hiba történt a(z) %x zárolt fájl másolása közben!</target> +<source>Unable to copy locked file %x!</source> +<target>A zárolt %x fájl másolása sikertelen!</target> <source>Data verification error: Source and target file have different content!</source> <target>Adatellenőrzési hiba: A forrás és cél fájl tartalma különbözik!</target> diff --git a/BUILD/Languages/italian.lng b/BUILD/Languages/italian.lng index c7775fc8..1ba11fea 100644 --- a/BUILD/Languages/italian.lng +++ b/BUILD/Languages/italian.lng @@ -8,19 +8,19 @@ </header> <source>Searching for directory %x...</source> -<target>Ricerca directory %x in corso...</target> +<target>Ricerca cartella %x in corso...</target> <source>Show in Explorer</source> <target>Mostra in Esplora Risorse</target> <source>Open with default application</source> -<target>Apri con applicazione di default</target> +<target>Apri con applicazione predefinita</target> <source>Browse directory</source> <target>Sfoglia cartelle</target> <source>RealtimeSync - Automated Synchronization</source> -<target>RealtimeSync - Sincronizzazione Automatizzata</target> +<target>RealtimeSync - Sincronizzazione automatizzata</target> <source>Select alternate comparison settings</source> <target>Seleziona impostazioni di comparazione alternative</target> @@ -38,10 +38,10 @@ <target>Rimuovi impostazioni alternative</target> <source>Clear filter settings</source> -<target>Pulisci impostazioni filtro</target> +<target>Azzera impostazioni filtro</target> <source>Create a batch job</source> -<target>Creazione di un job batch</target> +<target>Creazione di un attività batch</target> <source>Synchronization settings</source> <target>Parametri di sincronizzazione</target> @@ -50,7 +50,7 @@ <target>Impostazioni di comparazione</target> <source>About</source> -<target>A proposito di</target> +<target>Info su</target> <source>Error</source> <target>Errore</target> @@ -67,14 +67,11 @@ <source>Configure filter</source> <target>Configurazione dei filtri</target> -<source>Customize columns</source> -<target>Personalizza colonne</target> - <source>Global settings</source> <target>Preferenze</target> <source>Synchronization Preview</source> -<target>Anteprima Sincronizzazione</target> +<target>Anteprima sincronizzazione</target> <source>Find</source> <target>Trova</target> @@ -83,13 +80,13 @@ <target>Seleziona intervallo di tempo</target> <source>Show pop-up</source> -<target>Mostra pop-up</target> +<target>Mostra popup</target> <source>Show pop-up on errors or warnings</source> -<target>Mostra pop-up di errori o avvisi</target> +<target>Mostra popup di errori o avviso</target> <source>Ignore errors</source> -<target>Ignora gli errori</target> +<target>Ignora errori</target> <source>Hide all error and warning messages</source> <target>Nascondi tutti gli errori e i messaggi d'avviso</target> @@ -103,20 +100,20 @@ <source>Browse</source> <target>Sfoglia</target> -<source>Error reading from synchronization database:</source> -<target>Errore in lettura dal database di sincronizzione:</target> - -<source>Error writing to synchronization database:</source> -<target>Errore in scrittura sul database di sincronizzazione:</target> - <source>Invalid command line: %x</source> <target>Linea di comando non valida: %x</target> +<source>Info</source> +<target>Info</target> + +<source>Fatal Error</source> +<target>Errore fatale</target> + <source>Windows Error Code %x:</source> -<target>Errore Windows Codice %x:</target> +<target>Windows - Errore codice %x:</target> <source>Linux Error Code %x:</source> -<target>Errore Linux Codice %x:</target> +<target>Linux - Errore codice %x:</target> <source>Error resolving symbolic link:</source> <target>Errore nella risoluzione di collegamento simbolico:</target> @@ -139,29 +136,35 @@ <pluralform>%x Byte</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Errore in lettura dal database di sincronizzione:</target> + +<source>Error writing to synchronization database:</source> +<target>Errore in scrittura sul database di sincronizzazione:</target> + +<source>Incompatible synchronization database format:</source> +<target>Formato database di sincronizzazione incompatibile:</target> + <source>Initial synchronization:</source> <target>Prima sincronizzazione:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>Un file database di FreeFileSync non è ancora stato creato:</target> -<source>Incompatible synchronization database format:</source> -<target>Formato database di sincronizzazione incompatibile:</target> - <source>Database files do not share a common synchronization session:</source> <target>I file database non condividono una comune sessione di sincronizzazione:</target> <source>An exception occurred!</source> -<target>Si è verificato un problema!</target> +<target>Si è verificato una ececzione!</target> <source>Error reading file attributes:</source> <target>Errore di lettura degli attributi file:</target> <source>Waiting while directory is locked (%x)...</source> -<target>Attendi mentre la directory è bloccata (%x)...</target> +<target>Attendi mentre la cartella è bloccata (%x)...</target> <source>Error setting directory lock:</source> -<target>Errore nell'impostazione del blocco directory:</target> +<target>Errore nell'impostazione del blocco cartella:</target> <source> <pluralform>1 sec</pluralform> @@ -172,17 +175,11 @@ <pluralform>%x sec</pluralform> </target> -<source>Info</source> -<target>Info</target> - -<source>Fatal Error</source> -<target>Errore Fatale</target> - <source>Error reading file:</source> <target>Errore durante la lettura del file:</target> <source>Scanning:</source> -<target>Analisi in corso:</target> +<target>Analisi di:</target> <source>Encoding extended time information: %x</source> <target>Codifica estesa informazioni orario: %x</target> @@ -192,8 +189,8 @@ <pluralform>[%x Threads]</pluralform> </source> <target> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>[1 thread]</pluralform> +<pluralform>[%x threads]</pluralform> </target> <source>Invalid FreeFileSync config file!</source> @@ -202,22 +199,25 @@ <source>Error parsing configuration file:</source> <target>Errore nell'analisi del file di configurazione:</target> -<source>Error moving to Recycle Bin:</source> -<target>Errore durante lo spostamento nel Cestino:</target> +<source>Configuration loaded partially only:</source> +<target>Configurazione caricata solo parzialmente:</target> + +<source>Unable to move %x to the Recycle Bin!</source> +<target>Impossibile spostare %x nel Cestino!</target> -<source>Could not load a required DLL:</source> -<target>Impossibile caricare una DLL richiesta:</target> +<source>Cannot load file %x.</source> +<target>Impossibile caricare il file %x.</target> <source>Error accessing Volume Shadow Copy Service!</source> -<target>Errore in accesso al Servizio Volume Shadow Copy</target> +<target>Errore in accesso al servizio Volume Shadow Copy</target> <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> -<target>La creazione di copie shadow su WOW64 non e' supportata. Utilizzare FreeFileSync in versione 64-bit.</target> +<target>La creazione di copie shadow su WOW64 non e' supportata. Utilizzare FreeFileSync in versione 64 bit.</target> -<source>Could not determine volume name for file:</source> -<target>Impossibile determinare il nome volume per il file:</target> +<source>Cannot determine volume name for file:</source> +<target>Impossibile determinare il nome volume per il il file:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>Il nome volume %x non è parte del nome file %y!</target> <source>/sec</source> @@ -226,14 +226,14 @@ <source>File does not exist:</source> <target>Il file non esiste:</target> -<source>Could not read values for the following XML nodes:</source> -<target>Impossibile leggere i valori per i seguenti nodi XML:</target> +<source>Cannot read the following XML elements:</source> +<target>Impossibile leggere i seguenti elementi XML:</target> <source>S&ave configuration...</source> -<target>S&alva la configurazione...</target> +<target>S&alva configurazione...</target> <source>&Load configuration...</source> -<target>&Carica la configurazione...</target> +<target>&Carica configurazione...</target> <source>&Quit</source> <target>&Esci</target> @@ -248,7 +248,7 @@ <target>&Informazioni...</target> <source>&Help</source> -<target>&Aiuto</target> +<target>&?</target> <source>Usage:</source> <target>Uso:</target> @@ -274,7 +274,7 @@ La linea di comando è eseguita ogni volta che: </target> <source>Directories to watch</source> -<target>Directory da controllare</target> +<target>Cartelle da controllare</target> <source>Add folder</source> <target>Aggiungi cartella</target> @@ -298,7 +298,7 @@ La linea di comando è eseguita ogni volta che: <target>Avvia</target> <source>(Build: %x)</source> -<target>(Build: %x)</target> +<target>(Versione: %x)</target> <source>RealtimeSync configuration</source> <target>Configurazione di RealtimeSync</target> @@ -316,13 +316,13 @@ La linea di comando è eseguita ogni volta che: <target>Monitoraggio attivo...</target> <source>Waiting for missing directories...</source> -<target>In attesa delle directory mancanti...</target> +<target>In attesa delle cartelle mancanti...</target> <source>A directory input field is empty.</source> -<target>Un campo directory di input è vuoto.</target> +<target>Un campo cartella di input è vuoto.</target> <source>Logging</source> -<target>Logging</target> +<target>Registo attività</target> <source>File time and size</source> <target>Ora e dimensione file</target> @@ -343,16 +343,16 @@ La linea di comando è eseguita ogni volta che: <target>Personalizza</target> <source>FreeFileSync batch file</source> -<target>FreeFileSync batch file</target> +<target>FreeFileSync file batch</target> <source>FreeFileSync configuration</source> <target>Configurazione di FreeFileSync</target> <source>FreeFileSync Batch Job</source> -<target>FreeFileSync Batch Job</target> +<target>FreeFileSync job attività</target> <source>Unable to create log file!</source> -<target>Impossibile creaer il file di log!</target> +<target>Impossibile creare il file del registro attività!</target> <source>Batch execution</source> <target>Esecuzione in batch</target> @@ -367,7 +367,7 @@ La linea di comando è eseguita ogni volta che: <target>Sincronizzazione abortita!</target> <source>Synchronization completed with errors!</source> -<target>Sincronizzazione terminata con errori!</target> +<target>Sincronizzazione completata con errori!</target> <source>Synchronization completed successfully!</source> <target>Sincronizzazione completata con successo!</target> @@ -385,7 +385,7 @@ La linea di comando è eseguita ogni volta che: <target>E' disponibile una nuova versione di FreeFileSync:</target> <source>Download now?</source> -<target>Scaricare ora?</target> +<target>Scaricarla ora?</target> <source>Information</source> <target>Informazioni</target> @@ -397,13 +397,13 @@ La linea di comando è eseguita ogni volta che: <target>Vuoi che FreeFileSync controlli automaticamente gli aggiornamenti ogni settimana?</target> <source>(Requires an Internet connection!)</source> -<target>(Richiede una connessione Internet!)</target> +<target>(Richiede una connessione internet!)</target> <source><Symlink></source> <target><Symlink></target> <source><Directory></source> -<target><Directory></target> +<target><Cartella></target> <source>Full path</source> <target>Percorso completo</target> @@ -415,7 +415,7 @@ La linea di comando è eseguita ogni volta che: <target>Percorso relativo</target> <source>Directory</source> -<target>Directory</target> +<target>Cartella</target> <source>Size</source> <target>Dimensione</target> @@ -466,10 +466,10 @@ La linea di comando è eseguita ogni volta che: <target>&Preferenze...</target> <source>&Create batch job...</source> -<target>&Crea un job in batch...</target> +<target>&Crea una attività batch...</target> <source>&Export file list...</source> -<target>&Esporta la lista dei file...</target> +<target>&Esporta l'elenco dei file...</target> <source>&Advanced</source> <target>&Avanzate</target> @@ -502,13 +502,13 @@ La linea di comando è eseguita ogni volta che: <target>Inverti i lati</target> <source>Save current configuration to file</source> -<target>Salva su file la configurazione corrente</target> +<target>Salva la configurazione corrente in un file</target> <source>Load configuration from file</source> <target>Carica configurazione da file</target> <source>Last used configurations (press DEL to remove from list)</source> -<target>Ultima configurazione utilizzata (premi DEL per rimuovere dalla lista)</target> +<target>Ultima configurazione utilizzata (premi CANC per rimuovere dall'elenco)</target> <source>Hide excluded items</source> <target>Nascondi oggetti esclusi</target> @@ -540,23 +540,23 @@ La linea di comando è eseguita ogni volta che: <source>Speed:</source> <target>Velocita':</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Tempo rimanente:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Tempo trascorso:</target> <source>Batch job</source> -<target>Batch job</target> +<target>Attivitò batch</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Crea un batch file per una sincronizzazione automatizzata. Per partire in modalità batch è sufficiente fare doppio click sul file o eseguire da linea di comando: FreeFileSync.exe <ffs_batch file>. Puoi anche schedulare l'esecuzione nelle operazioni pianificate del suo sistema operativo.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>Crea un file batch e automatizza la sincronizzazione. Per lanciare in modalità batch fai semplicemente doppio-click su questo file o esegui da linea di comando: FreeFileSync.exe SyncJob.ffs_batch. Puoi anche schedularlo nelle operazioni pianificate del tuo sistema.</target> <source>Help</source> -<target>Aiuto</target> +<target>?</target> <source>Filter files</source> -<target>Filtro dei files</target> +<target>Filtro dei file</target> <source>Left</source> <target>Sinistra</target> @@ -564,9 +564,6 @@ La linea di comando è eseguita ogni volta che: <source>Right</source> <target>Destra</target> -<source>Overview</source> -<target>Controllo generale</target> - <source>Status feedback</source> <target>Feedback di stato</target> @@ -577,13 +574,13 @@ La linea di comando è eseguita ogni volta che: <target>Gestione degli errori</target> <source>Maximum number of log files:</source> -<target>Numero massimo di log files:</target> +<target>Numero massimo di file registro:</target> <source>Select log file directory:</source> -<target>Seleziona cartella per il file di log:</target> +<target>Seleziona cartella per il file di registro:</target> <source>Batch settings</source> -<target>Impostazioni Batch</target> +<target>Impostazioni batch</target> <source>&Save</source> <target>&Salva</target> @@ -595,13 +592,13 @@ La linea di comando è eseguita ogni volta che: <target>&Annulla</target> <source>Select variant:</source> -<target>Selezionare una variante:</target> +<target>Seleziona una variante:</target> <source>Identify and propagate changes on both sides using a database. Deletions, renaming and conflicts are detected automatically.</source> <target>Identifica e propaga modifiche su entrambi i lati usando un database. Cancellazioni, ridenominazioni e conflitti sono rilevati automaticamente.</target> <source>Mirror backup of left folder. Right folder is modified to exactly match left folder after synchronization.</source> -<target>Mirror backup della cartella di sinistra. La cartella destra verrà modificata per corrispondere esattamente alla cartella di sinistra dopo la sincronizzazione.</target> +<target>Backup mirror della cartella di sinistra. La cartella destra verrà modificata per corrispondere esattamente alla cartella di sinistra dopo la sincronizzazione.</target> <source>Copy new or updated files to right folder.</source> <target>Copia file nuovi o aggiornati nella cartella di destra.</target> @@ -631,16 +628,16 @@ La linea di comando è eseguita ogni volta che: <target>File/cartella esiste solo sul lato destro</target> <source>Left file is newer</source> -<target>File di sinistra è più recente</target> +<target>Il file di sinistra è più recente</target> <source>Right file is newer</source> -<target>File di destra è più recente</target> +<target>Il file di destra è più recente</target> <source>Files have different content</source> <target>I file hanno differente contenuto</target> <source>Conflict/file cannot be categorized</source> -<target>Conflitti/file non possono essere categorizzati</target> +<target>I conflitti/file non possono essere categorizzati</target> <source>&OK</source> <target>&OK</target> @@ -673,10 +670,10 @@ I file sono considerati identici se </target> <source>Symbolic Link handling</source> -<target>Gestione Link Simbolico</target> +<target>Gestione link simbolico</target> <source>Synchronizing...</source> -<target>Sincronizzazione in corso...</target> +<target>Sincronizzazione...</target> <source>Items processed:</source> <target>Elementi processati:</target> @@ -711,8 +708,8 @@ I file sono considerati identici se <source>Published under the GNU General Public License</source> <target>Pubblicato sotto licenza GNU General Public</target> -<source>Ignore subsequent errors</source> -<target>Ignora gli errori successivi</target> +<source>Ignore further errors</source> +<target>Ignora i prossimi errori</target> <source>Hide further error messages during the current process</source> <target>Non mostrare i successivi messaggi d'errore durante il processo corrente</target> @@ -735,29 +732,29 @@ I file sono considerati identici se <source>&No</source> <target>&No</target> +<source>Use Recycle Bin</source> +<target>Usa il Cestino</target> + <source>Delete on both sides</source> -<target>Cancella su entrambi i lati</target> +<target>Elimina su entrambi i lati</target> <source>Delete on both sides even if the file is selected on one side only</source> -<target>Cancella su entrambi i lati anche se il file è selezionato su un solo lato.</target> - -<source>Use Recycle Bin</source> -<target>Usa il Cestino</target> +<target>Elimina su entrambi i lati anche se il file è selezionato su un solo lato.</target> <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Solo file/cartelle che corrispondono a tutti i filtri impostati saranno selezionati per la sincronizzazione. -Nota: Il nome filtro deve essere specificato relativo(!) nelle directory principali di sincronizzazione. +Solo i file che corrispondono esattamente a tutti i filtri impostati verrranno sincronizzati. +Nota: I nomi dei file devono essere relativi alle cartelle di appartenenza! </target> <source>Hints:</source> <target>Consigli:</target> <source>1. Enter relative file or directory names separated by ';' or a new line.</source> -<target>1. Inserisci i nomi relativi di file o directory separati da ';' o su una nuova riga.</target> +<target>1. Inserisci i nomi relativi di file o cartella separati da ';' o su una nuova riga.</target> <source>2. Use wildcard characters '*' and '?'.</source> <target>2. Sono ammessi i caratteri generici '*' e '?'.</target> @@ -786,47 +783,41 @@ Escludi: \stuff\temp\* <source>Exclude</source> <target>Escludi</target> -<source>Minimum file size</source> -<target>Dimensione minima file</target> +<source>Time span</source> +<target>Intervallo di tempo</target> -<source>Maximum file size</source> -<target>Dimensione massima file</target> +<source>File size</source> +<target>Dimensione file</target> -<source>&Default</source> -<target>&Default</target> +<source>Minimum</source> +<target>Minimo</target> -<source>Move column up</source> -<target>Sposta colonna su'</target> +<source>Maximum</source> +<target>Massimo</target> -<source>Move column down</source> -<target>Sposta colonna giu'</target> +<source>&Default</source> +<target>&Predefinito</target> <source>Transactional file copy</source> <target>Copia transazionale file</target> <source>Write to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of fatal error.</source> -<target>Scrivi su un file temporaneo (*.ffs_tmp) prima di rinominarlo. Ciò garantisce uno stato consistente anche in caso di errore fatale.</target> +<target>Scrivi in un file temporaneo (*.ffs_tmp) prima di rinominarlo. Ciò garantisce uno stato consistente anche in caso di errore fatale.</target> <source>Copy locked files</source> <target>Copia file bloccati</target> <source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Copia file condivisi o bloccati usando il Servizio Volume Shadow Copy (Richiede diritti di Administrator)</target> +<target>Copia file condivisi o bloccati usando il Servizio Volume Shadow Copy (richiede diritti di amministarzione)</target> <source>Copy file access permissions</source> <target>Copia permessi di accesso file</target> <source>Transfer file and directory permissions (Requires Administrator rights)</source> -<target>Trasferisci file e permessi sulle cartelle (Richiede diritti di Administrator)</target> - -<source>Hidden dialogs:</source> -<target>Messaggi nascosti:</target> - -<source>Reset</source> -<target>Reset</target> +<target>Trasferisci permessi file cartelle (richiede diritti di amministrazione)</target> -<source>Show hidden dialogs</source> -<target>Mostra messaggi nascosti</target> +<source>Restore hidden dialogs</source> +<target>Ripristina i messaggi nascosti</target> <source>External applications</source> <target>Applicazioni esterne</target> @@ -841,7 +832,7 @@ Escludi: \stuff\temp\* <target>Statistiche</target> <source>Find what:</source> -<target>Trova cosa:</target> +<target>Trova questo:</target> <source>Match case</source> <target>Corrispondenza</target> @@ -858,8 +849,8 @@ Escludi: \stuff\temp\* <source>Folder pairs</source> <target>Coppia di cartelle</target> -<source>Compressed view</source> -<target>Vista compressa</target> +<source>Overview</source> +<target>Anteprima</target> <source>Select view</source> <target>Seleziona vista</target> @@ -880,7 +871,7 @@ Escludi: \stuff\temp\* <target><selezione multipla></target> <source>Delete</source> -<target>Cancella</target> +<target>Elimina</target> <source>Include all</source> <target>Includi tutto</target> @@ -888,17 +879,17 @@ Escludi: \stuff\temp\* <source>Exclude all</source> <target>Escludi tutto</target> -<source>Icon size:</source> -<target>Dimensione icona:</target> +<source>Show icons:</source> +<target>Mostra icone:</target> <source>Small</source> -<target>Piccola</target> +<target>Piccole</target> <source>Medium</source> -<target>Media</target> +<target>Medie</target> <source>Large</source> -<target>Grande</target> +<target>Grandi</target> <source>Select time span...</source> <target>Seleziona intervallo di tempo...</target> @@ -915,6 +906,9 @@ Escludi: \stuff\temp\* <source>Configuration saved!</source> <target>Configurazione salvata!</target> +<source>Never save changes</source> +<target>Non salvare mai le modifiche</target> + <source>Save changes to current configuration?</source> <target>Salvare i cambiamenti alla configurazione corrente?</target> @@ -922,7 +916,7 @@ Escludi: \stuff\temp\* <target>Configurazione caricata!</target> <source>Folder Comparison and Synchronization</source> -<target>Comparazione di Cartelle e Sincronizzazione</target> +<target>Comparazione di cartelle e sincronizzazione</target> <source>Hide files that exist on left side only</source> <target>Nascondi i file esistenti solo a sinistra</target> @@ -1009,26 +1003,23 @@ Escludi: \stuff\temp\* <target>Mostra file che non saranno copiati</target> <source>All directories in sync!</source> -<target>Tutte le directory in sync!</target> +<target>Tutte le cartelle sincronizzate!</target> <source>Please run a Compare first before synchronizing!</source> -<target>Prima di sincronizzare effettua una Comparazione!</target> +<target>Prima di sincronizzare effettua una comparazione!</target> <source>Comma separated list</source> -<target>Lista di elementi separati da virgola</target> +<target>Elenco elementi separati da virgola</target> <source>Legend</source> <target>Legenda</target> <source>File list exported!</source> -<target>Lista dei file esportata!</target> +<target>Elenco file esportato!</target> <source>Error writing file:</source> <target>Errore durante la scrittura del file:</target> -<source>Batch file created successfully!</source> -<target>Creazione batch file riuscita!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1061,12 +1052,12 @@ Escludi: \stuff\temp\* <pluralform>%x of %y rows in view</pluralform> </source> <target> -<pluralform>%x di 1 riga in vista</pluralform> -<pluralform>%x di %y righe in vista</pluralform> +<pluralform>%x di 1 riga nella vista</pluralform> +<pluralform>%x di %y righe nella vista</pluralform> </target> <source>Scanning...</source> -<target>Scansione in corso...</target> +<target>Scansione...</target> <source>Comparing content...</source> <target>Comparazione contenuto...</target> @@ -1075,13 +1066,13 @@ Escludi: \stuff\temp\* <target>In pausa</target> <source>Aborted</source> -<target>Abbandono riuscito</target> +<target>Interrotto</target> <source>Completed</source> <target>Completato</target> <source>Abort requested: Waiting for current operation to finish...</source> -<target>Abbandono richiesto: in attesa della fine dell'operazione in corso...</target> +<target>Selezionata interruazione: conclusione dell'operazione...</target> <source>Pause</source> <target>Pausa</target> @@ -1107,6 +1098,9 @@ Escludi: \stuff\temp\* <source>This year</source> <target>Quest'anno</target> +<source>Last x days</source> +<target>Ultimi x giorni</target> + <source>Byte</source> <target>Byte</target> @@ -1116,11 +1110,8 @@ Escludi: \stuff\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>Filtro: Tutte le coppie</target> - -<source>Filter: Single pair</source> -<target>Filtro: Singola coppia</target> +<source>Filter</source> +<target>Filtro</target> <source>Direct</source> <target>Diretto</target> @@ -1135,27 +1126,27 @@ Escludi: \stuff\temp\* <target>Integra applicazioni esterne nel menu contestuale. Sono disponibili le seguenti macro:</target> <source>- full file or directory name</source> -<target>- file completo o nome directory</target> +<target>- file completo o nome cartella</target> <source>- directory part only</source> -<target>- solo parte di directory</target> +<target>- solo parte di cartella</target> <source>- Other side's counterpart to %name</source> -<target>- L'altro lato e' equivalente a %name</target> +<target>- l'altro lato e' equivalente a %name</target> <source>- Other side's counterpart to %dir</source> -<target>- L'altro lato e' equivalente a %dir</target> +<target>- l'altro lato e' equivalente a %dir</target> -<source>Restore all hidden dialogs?</source> -<target>Ripristinare tutti i dialoghi nascosti?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>Vuoi rendere nuovamente visibili i dialoghi nascosti e i messaggi d'avviso?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> <pluralform>Do you really want to move the following %x objects to the Recycle Bin?</pluralform> </source> <target> -<pluralform>Vuoi veramente spostare il seguente oggetto nel Cestino?</pluralform> -<pluralform>Vuoi veramente spostare i seguenti %x oggetti nel Cestino?</pluralform> +<pluralform>Vuoi spostare il seguente oggetto nel Cestino?</pluralform> +<pluralform>Vuoi spostare i seguenti %x oggetti nel Cestino?</pluralform> </target> <source> @@ -1163,30 +1154,30 @@ Escludi: \stuff\temp\* <pluralform>Do you really want to delete the following %x objects?</pluralform> </source> <target> -<pluralform>Vuoi veramente cancellare il seguente oggetto?</pluralform> -<pluralform>Vuoi veramente cancellare i seguenti %x oggetti?</pluralform> +<pluralform>Eliminare il seguente elemento?</pluralform> +<pluralform>Eliminare i seguenti %x elementi?</pluralform> </target> <source>Leave as unresolved conflict</source> <target>Lascia come conflitti irrisolti</target> <source>Delete permanently</source> -<target>Cancella definitivamente</target> +<target>Elimina definitivamente</target> <source>Delete or overwrite files permanently</source> -<target>Cancella o sovrascrivi file definitivamente</target> +<target>Elimina o sovrascrivi file definitivamente</target> <source>Use Recycle Bin when deleting or overwriting files</source> -<target>Usa il Cestino quando si cancella o sovrascrive un file</target> +<target>Usa il Cestino quando si elimina o sovrascrive un file</target> <source>Versioning</source> -<target>Versioning</target> +<target>Versione</target> <source>Move files into a time-stamped subdirectory</source> -<target>Sposta file in una sotto-cartella datata</target> +<target>Sposta file in una sotto cartella datata</target> <source>Files</source> -<target>Files</target> +<target>File</target> <source>Percentage</source> <target>Percentuale</target> @@ -1228,10 +1219,10 @@ Escludi: \stuff\temp\* </target> <source>Could not initialize directory monitoring:</source> -<target>Monitoraggio directory non inizializzabile:</target> +<target>Monitoraggio cartella non inizializzabile:</target> <source>Error when monitoring directories.</source> -<target>Errore durante il monitoraggio directory.</target> +<target>Errore durante il monitoraggio cartella.</target> <source>Conversion error:</source> <target>Errore di conversione:</target> @@ -1249,10 +1240,10 @@ Escludi: \stuff\temp\* <target>Errore nello spostamento directory:</target> <source>Target directory already existing!</source> -<target>Directory di destinazione già esistente!</target> +<target>Cartella di destinazione già esistente!</target> <source>Error deleting directory:</source> -<target>Errore durante l'eliminazione delle directory:</target> +<target>Errore durante l'eliminazione delle cartella:</target> <source>Error changing modification time:</source> <target>Errore durante la modifica della data:</target> @@ -1270,7 +1261,7 @@ Escludi: \stuff\temp\* <target>Errore durante la copia dei permessi su file:</target> <source>Error creating directory:</source> -<target>Errore durante la creazione della directory:</target> +<target>Errore durante la creazione della cartella:</target> <source>Error copying symbolic link:</source> <target>Errore durante la copia del link simbolico:</target> @@ -1278,14 +1269,11 @@ Escludi: \stuff\temp\* <source>Error copying file:</source> <target>Errore durante la copia del file:</target> -<source>Error opening file:</source> -<target>Errore in apertura file:</target> - <source>Error traversing directory:</source> -<target>Errore nel percorso della directory:</target> +<target>Errore nello spostamento cartella:</target> <source>Endless loop when traversing directory:</source> -<target>Loop senza fine attraverso le directory:</target> +<target>Loop senza fine nello spostamento cartella:</target> <source>Error setting privilege:</source> <target>Errore nell'impostazione dei privilegi:</target> @@ -1306,25 +1294,25 @@ Escludi: \stuff\temp\* <target>Il file non era processato nell'ultima sincronizzazione!</target> <source>Setting default synchronization directions: Old files will be overwritten with newer files.</source> -<target>Imposta direzioni di sincronizzazione di default: I vecchi file saranno sovrascritti dai nuovi.</target> +<target>Imposta direzioni di sincronizzazione dpredefinite: i vecchi file saranno sovrascritti dai nuovi.</target> <source>The file does not contain a valid configuration:</source> <target>Il file non contiene una configurazione valida</target> <source>You can ignore this error to consider the directory as empty.</source> -<target>Puoi ignorare questo errore per considerare la directory come vuota.</target> +<target>Puoi ignorare questo errore per considerare la cartella come vuota.</target> <source>Directory does not exist:</source> -<target>La directory non esiste:</target> +<target>La cartella non esiste:</target> <source>Directories are dependent! Be careful when setting up synchronization rules:</source> -<target>Le directory sono dipendenti! Fai attenzione quando configuri le regole di sincronizzazione:</target> +<target>Le cartelle sono dipendenti! Fai attenzione quando configuri le regole di sincronizzazione:</target> <source>Preparing synchronization...</source> <target>Preparazione sincronizzazione...</target> -<source>Memory allocation failed!</source> -<target>Allocazione di memoria fallita!</target> +<source>Out of memory!</source> +<target>Memoria insufficiente!</target> <source>File %x has an invalid date!</source> <target>Il file %x ha una data non valida!</target> @@ -1336,7 +1324,7 @@ Escludi: \stuff\temp\* <target>I file %x hanno la stessa data ma dimensione diversa!</target> <source>Symlinks %x have the same date but a different target!</source> -<target>Symlinks %x hanno stessa data ma differente target!</target> +<target>I link simbolici %x hanno stessa data ma differente target!</target> <source>Comparing content of files %x</source> <target>Comparazione contenuto del file %x</target> @@ -1345,7 +1333,7 @@ Escludi: \stuff\temp\* <target>Comparazione file in base al contenuto fallita.</target> <source>Generating file list...</source> -<target>Generazione lista dei file...</target> +<target>Generazione elenco file...</target> <source>Both sides are equal</source> <target>Entrambi i lati sono uguali</target> @@ -1396,25 +1384,25 @@ Escludi: \stuff\temp\* <target>Eliminazione cartella %x</target> <source>Deleting symbolic link %x</source> -<target>Cancellazione link simbolico %x in corso</target> +<target>Eliminazione link simbolico %x</target> <source>Moving file %x to recycle bin</source> -<target>Spostamento file %x nel cestino in corso</target> +<target>Spostamento file %x nel Cestino</target> <source>Moving folder %x to recycle bin</source> -<target>Spostamento cartella %x nel cestino in corso</target> +<target>Spostamento cartella %x nel Cestino</target> <source>Moving symbolic link %x to recycle bin</source> -<target>Spostamento link simbolico %x nel cestino in corso</target> +<target>Spostamento link simbolico %x nel Cestino</target> <source>Moving file %x to %y</source> -<target>Spostamento file %x su %y</target> +<target>Spostamento file %x in %y</target> <source>Moving folder %x to %y</source> -<target>Spostamento cartella %x su %y</target> +<target>Spostamento cartella %x in %y</target> <source>Moving symbolic link %x to %y</source> -<target>Spostamento link simbolico %x su %y</target> +<target>Spostamento link simbolico %x in %y</target> <source>Creating file %x</source> <target>Creazione file %x</target> @@ -1432,19 +1420,19 @@ Escludi: \stuff\temp\* <target>Sovrascrittura link simbolico %x</target> <source>Verifying file %x</source> -<target>Verifica di file %x</target> +<target>Verifica file %x</target> <source>Updating attributes of %x</source> <target>Aggiornamento attributi di %x</target> <source>Target directory name must not be empty!</source> -<target>Il nome della cartella di destinazione non può essere nullo!</target> +<target>Il nome della cartella di destinazione non può essere vuoto!</target> <source>Directory for file versioning was not supplied!</source> <target>Non è stata indicata una cartella per il file delle versioni!</target> <source>Source directory does not exist anymore:</source> -<target>La directory sorgente non è più esistente:</target> +<target>La cartella sorgente non esiste più:</target> <source>Unresolved conflicts existing!</source> <target>Sono presenti conflitti irrisolti!</target> @@ -1456,7 +1444,7 @@ Escludi: \stuff\temp\* <target>Riscontrate differenze significative:</target> <source>More than 50% of the total number of files will be copied or deleted!</source> -<target>Piu' del 50% del totale dei files saranno copiati o cancellati!</target> +<target>Piu' del 50% del totale dei file saranno copiati o cancellati!</target> <source>Not enough free disk space available in:</source> <target>Spazio libero su disco insufficiente in:</target> @@ -1471,7 +1459,7 @@ Escludi: \stuff\temp\* <target>Cestino non disponibile per i seguenti percorsi! I file verranno cancellati in modo permanente:</target> <source>A directory will be modified which is part of multiple folder pairs! Please review synchronization settings!</source> -<target>Una directory che fa parte di più coppie di cartelle sarà modificata! Ricontrolla le impostazioni di sincronizzazione!</target> +<target>Una cartella che fa parte di più coppie di cartelle sarà modificata! Ricontrolla le impostazioni di sincronizzazione!</target> <source>Processing folder pair:</source> <target>Elaborazione coppia di cartelle:</target> @@ -1479,12 +1467,12 @@ Escludi: \stuff\temp\* <source>Generating database...</source> <target>Generazione database...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>Niente da sincronizzare in questa configurazione!</target> +<source>Nothing to synchronize!</source> +<target>Non c'è nulla da sincronizzare!</target> -<source>Error copying locked file %x!</source> -<target>Errore durante la copia del file bloccato %x!</target> +<source>Unable to copy locked file %x!</source> +<target>Impossibile copiare il file bloccato %x!</target> <source>Data verification error: Source and target file have different content!</source> -<target>Errore in verifica data: I file sorgente e destinazione hanno differente contenuto!</target> +<target>Errore nella verifica data: i file sorgente e destinazione hanno differente contenuto!</target> diff --git a/BUILD/Languages/japanese.lng b/BUILD/Languages/japanese.lng index 7bcd766c..9f04e478 100644 --- a/BUILD/Languages/japanese.lng +++ b/BUILD/Languages/japanese.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>フィルター設定</target> -<source>Customize columns</source> -<target>列の調整</target> - <source>Global settings</source> <target>全般的な設定</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>参照</target> -<source>Error reading from synchronization database:</source> -<target>同期データベースからの読み込みエラー:</target> - -<source>Error writing to synchronization database:</source> -<target>同期データベースへの書き込みエラー:</target> - <source>Invalid command line: %x</source> <target>無効なコマンドライン: %x</target> +<source>Info</source> +<target>情報</target> + +<source>Fatal Error</source> +<target>致命的なエラー</target> + <source>Windows Error Code %x:</source> <target>Windows エラーコード %x:</target> @@ -138,15 +135,21 @@ <pluralform>%x バイト</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>同期データベースからの読み込みエラー:</target> + +<source>Error writing to synchronization database:</source> +<target>同期データベースへの書き込みエラー:</target> + +<source>Incompatible synchronization database format:</source> +<target>同期データベースの書式に互換性がありません:</target> + <source>Initial synchronization:</source> <target>同期処理の初期化:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>FreeFileSync データベースファイルが存在しません:</target> -<source>Incompatible synchronization database format:</source> -<target>同期データベースの書式に互換性がありません:</target> - <source>Database files do not share a common synchronization session:</source> <target>データベースファイルは一般的な同期セッションを共有しません:</target> @@ -170,12 +173,6 @@ <pluralform>%x 秒.</pluralform> </target> -<source>Info</source> -<target>情報</target> - -<source>Fatal Error</source> -<target>致命的なエラー</target> - <source>Error reading file:</source> <target>ファイル読み込みエラー:</target> @@ -199,11 +196,14 @@ <source>Error parsing configuration file:</source> <target>構成ファイルの構文に誤りがあります:</target> -<source>Error moving to Recycle Bin:</source> -<target>ゴミ箱への移動に失敗:</target> +<source>Configuration loaded partially only:</source> +<target>部分的のみ読み込まれた構成:</target> -<source>Could not load a required DLL:</source> -<target>必要なDLLを読み込めません:</target> +<source>Unable to move %x to the Recycle Bin!</source> +<target>%x をゴミ箱に移動できません!</target> + +<source>Cannot load file %x.</source> +<target>ファイル %x を読み込めません.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>ボリュームシャドウ・コピーサービスにアクセス出来ません!</target> @@ -211,10 +211,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>WOW64 では、ボリュームシャドウコピーに対応していません、FreeFileSync 64-bit 版をお試しください。</target> -<source>Could not determine volume name for file:</source> -<target>ファイルのボリューム名が決定されていません:</target> +<source>Cannot determine volume name for file:</source> +<target>ファイルのボリューム名を解決出来ません:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>ボリューム名 %x にファイル名 %y はありません!</target> <source>/sec</source> @@ -223,8 +223,8 @@ <source>File does not exist:</source> <target>ファイルが存在しません:</target> -<source>Could not read values for the following XML nodes:</source> -<target>以下の XMLノードの値を読み込むことが出来ません:</target> +<source>Cannot read the following XML elements:</source> +<target>次の XML要素を読み込めません:</target> <source>S&ave configuration...</source> <target>構成設定を保存(&A)...</target> @@ -450,9 +450,6 @@ The command line is executed each time: <source>2. &Synchronize...</source> <target>2. 同期処理(&S)...</target> -<source>S&witch view</source> -<target>表示切り替え(&W)</target> - <source>&New</source> <target>新規(&N)</target> @@ -540,17 +537,17 @@ The command line is executed each time: <source>Speed:</source> <target>速度:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>残り時間:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>経過時間:</target> <source>Batch job</source> <target>一括処理</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>同期を自動的に実行する一括バッチファイルを作成します。実行方法はファイルをダブルクリックするか、コマンドライン経由で実行します - 例: FreeFileSync.exe <ffs_batch file>. この処理はあなたのシステムのタスクスケジューラでも実行可能です。</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>一括バッチファイルを作成して、同期を自動化します、開始方法はバッチファイルをダブルクリックするか次のコマンドを実行します:FreeFileSync.exe SyncJob.ffs_batch. またこの操作はシステムのタスクから実行することも出来ます.</target> <source>Help</source> <target>ヘルプ</target> @@ -564,8 +561,8 @@ The command line is executed each time: <source>Right</source> <target>右側</target> -<source>Overview</source> -<target>概要</target> +<source>Sync setttings</source> +<target>同期設定</target> <source>Status feedback</source> <target>状態 フィードバック</target> @@ -711,7 +708,7 @@ is the same <source>Published under the GNU General Public License</source> <target>GNU 一般共有使用許諾に基づき公開されています</target> -<source>Ignore subsequent errors</source> +<source>Ignore further errors</source> <target>以降のエラーを無視</target> <source>Hide further error messages during the current process</source> @@ -735,22 +732,22 @@ is the same <source>&No</source> <target>いいえ(&N)</target> +<source>Use Recycle Bin</source> +<target>ゴミ箱を使用</target> + <source>Delete on both sides</source> <target>両方を削除</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>片側のペインのみ選択されている場合でも両方を削除する</target> -<source>Use Recycle Bin</source> -<target>ゴミ箱を使用</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -すべてのフィルター設定に適合するファイル/ディレクトリのみが同期対象に選択されます。 -注意: 名前フィルターは、メイン同期ディレクトリと同様の名前に適用 +すべてのフィルターに合致するファイルのみが同期されます. +注意: ファイル名は基準ディレクトリに比例する必要があります! </target> <source>Hints:</source> @@ -786,20 +783,20 @@ Exclude: \stuff\temp\* <source>Exclude</source> <target>除外</target> -<source>Minimum file size</source> -<target>最小ファイルサイズ</target> +<source>Time span</source> +<target>時間間隔</target> -<source>Maximum file size</source> -<target>最大ファイルサイズ</target> +<source>File size</source> +<target>ファイルサイズ</target> -<source>&Default</source> -<target>デフォルト(&D)</target> +<source>Minimum</source> +<target>最小</target> -<source>Move column up</source> -<target>列を上に移動</target> +<source>Maximum</source> +<target>最大</target> -<source>Move column down</source> -<target>列を下に移動</target> +<source>&Default</source> +<target>デフォルト(&D)</target> <source>Transactional file copy</source> <target>トランザクション・コピーを使用</target> @@ -819,14 +816,8 @@ Exclude: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>ファイルとディレクトリのパーミッション転送(管理者権限が必要)</target> -<source>Hidden dialogs:</source> -<target>ダイアログを隠す:</target> - -<source>Reset</source> -<target>リセット</target> - -<source>Show hidden dialogs</source> -<target>非表示ダイアログを表示</target> +<source>Restore hidden dialogs</source> +<target>隠したダイアログを復帰</target> <source>External applications</source> <target>外部アプリケーション</target> @@ -858,8 +849,8 @@ Exclude: \stuff\temp\* <source>Folder pairs</source> <target>フォルダ・ペア</target> -<source>Compressed view</source> -<target>簡易表示</target> +<source>Overview</source> +<target>概要</target> <source>Select view</source> <target>表示選択</target> @@ -888,8 +879,8 @@ Exclude: \stuff\temp\* <source>Exclude all</source> <target>すべて除外</target> -<source>Icon size:</source> -<target>アイコンサイズ:</target> +<source>Show icons:</source> +<target>アイコン表示:</target> <source>Small</source> <target>小</target> @@ -915,6 +906,9 @@ Exclude: \stuff\temp\* <source>Configuration saved!</source> <target>構成設定は保存されました!</target> +<source>Never save changes</source> +<target>変更を保存しない</target> + <source>Save changes to current configuration?</source> <target>現在の構成の変更を保存しますか?</target> @@ -1026,9 +1020,6 @@ Exclude: \stuff\temp\* <source>Error writing file:</source> <target>ファイル書き込みエラー:</target> -<source>Batch file created successfully!</source> -<target>バッチファイルが作成されました!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1103,6 +1094,9 @@ Exclude: \stuff\temp\* <source>This year</source> <target>この年</target> +<source>Last x days</source> +<target>最後の x 日</target> + <source>Byte</source> <target>バイト</target> @@ -1112,11 +1106,8 @@ Exclude: \stuff\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>フィルター:すべてのペア</target> - -<source>Filter: Single pair</source> -<target>フィルター:単一ペア</target> +<source>Filter</source> +<target>フィルター</target> <source>Direct</source> <target>方向</target> @@ -1142,8 +1133,8 @@ Exclude: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- %dir の反対側の対象</target> -<source>Restore all hidden dialogs?</source> -<target>非表示ダイアログをすべて戻しますか?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>現在隠されたダイアログと警告メッセージを再表示しますか?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1314,8 +1305,8 @@ Exclude: \stuff\temp\* <source>Preparing synchronization...</source> <target>同期処理の準備中...</target> -<source>Memory allocation failed!</source> -<target>メモリ割り当てに失敗!</target> +<source>Out of memory!</source> +<target>メモリが足りません!</target> <source>File %x has an invalid date!</source> <target>ファイル %x の日付は無効なものです!</target> @@ -1470,11 +1461,11 @@ Exclude: \stuff\temp\* <source>Generating database...</source> <target>データベースを作成中...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>構成設定に対応する同期がみつかりません!</target> +<source>Nothing to synchronize!</source> +<target>同期対象がありません!</target> -<source>Error copying locked file %x!</source> -<target>コピーに失敗! ファイル%x はロックされています!</target> +<source>Unable to copy locked file %x!</source> +<target>ファイル %x はコピーできません!</target> <source>Data verification error: Source and target file have different content!</source> <target>データ検証エラー: ソースと対象ファイルに異なる内容が含まれています!</target> diff --git a/BUILD/Languages/korean.lng b/BUILD/Languages/korean.lng index 29aa46e9..36a10add 100644 --- a/BUILD/Languages/korean.lng +++ b/BUILD/Languages/korean.lng @@ -14,7 +14,7 @@ <target>탐색기에 표시</target> <source>Open with default application</source> -<target>기본값 애플리케이션으로 열기</target> +<target>기본값 응용 프로그램으로 열기</target> <source>Browse directory</source> <target>디렉토리 찾아보기</target> @@ -50,7 +50,7 @@ <target>비교 설정</target> <source>About</source> -<target>상세정보</target> +<target>상세 정보</target> <source>Error</source> <target>오류</target> @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>필터 설정</target> -<source>Customize columns</source> -<target>개인 설정 - 열(세로칸) 조정</target> - <source>Global settings</source> <target>전체 설정</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>찾아보기</target> -<source>Error reading from synchronization database:</source> -<target>동기화 데이터베이스로부터 읽어 들이던 중 발생한 오류 :</target> - -<source>Error writing to synchronization database:</source> -<target>동기화 데이터베이스에 쓰던 중 발생한 오류 :</target> - <source>Invalid command line: %x</source> <target>잘못된 명령줄 : %x</target> +<source>Info</source> +<target>정보</target> + +<source>Fatal Error</source> +<target>치명적 오류</target> + <source>Windows Error Code %x:</source> <target>윈도우 에러 코드 %x:</target> @@ -138,15 +135,21 @@ <pluralform>%x 바이트</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>동기화 데이터베이스로부터 읽어 들이던 중 발생한 오류 :</target> + +<source>Error writing to synchronization database:</source> +<target>동기화 데이터베이스에 쓰던 중 발생한 오류 :</target> + +<source>Incompatible synchronization database format:</source> +<target>호환되지 않는 동기화 데이터베이스 형식 :</target> + <source>Initial synchronization:</source> <target>초기 동기화 :</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>FreeFileSync 데이터베이스 파일 중 하나가 아직 존재하지 않습니다 :</target> -<source>Incompatible synchronization database format:</source> -<target>호환되지 않는 동기화 데이터베이스 형식 :</target> - <source>Database files do not share a common synchronization session:</source> <target>데이터베이스 파일이 공통 동기화 세션을 공유하지 않습니다 :</target> @@ -170,12 +173,6 @@ <pluralform>%x초</pluralform> </target> -<source>Info</source> -<target>정보</target> - -<source>Fatal Error</source> -<target>치명적 오류</target> - <source>Error reading file:</source> <target>파일을 읽던 중 발생한 오류 :</target> @@ -199,11 +196,14 @@ <source>Error parsing configuration file:</source> <target>설정파일 분석 중 발생한 오류 :</target> -<source>Error moving to Recycle Bin:</source> -<target>휴지통으로 이동 중 발생한 오류 :</target> +<source>Configuration loaded partially only:</source> +<target>구성이 부분적으로만 로드 됐습니다 :</target> + +<source>Unable to move %x to the Recycle Bin!</source> +<target>%x 을(를) 휴지통으로 이동할 수 없습니다!</target> -<source>Could not load a required DLL:</source> -<target>필요한 DLL을 로드할 수 없습니다 :</target> +<source>Cannot load file %x.</source> +<target>파일 %x 을(를) 로드할 수 없습니다.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>볼륨 섀도 복사본 서비스에 액세스하던 중 오류 발생!</target> @@ -211,10 +211,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>WOW64 에서의 Shadow Copy 는 지원하지 않습니다. FreeFileSync 64-bit 버전을 사용하세요.</target> -<source>Could not determine volume name for file:</source> -<target>파일 볼륨 이름을 결정할 수 없습니다 :</target> +<source>Cannot determine volume name for file:</source> +<target>파일의 볼륨 이름을 결정할 수 없습니다 :</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>볼륨 이름 %x 이(가) 파일 이름 %y 의 일부가 아닙니다!</target> <source>/sec</source> @@ -223,8 +223,8 @@ <source>File does not exist:</source> <target>파일이 존재하지 않습니다 :</target> -<source>Could not read values for the following XML nodes:</source> -<target>다음 XML 노드 값을 읽어 들일 수 없습니다 :</target> +<source>Cannot read the following XML elements:</source> +<target>다음 XML 요소를 읽을 수 없습니다 :</target> <source>S&ave configuration...</source> <target>설정 저장</target> @@ -266,7 +266,7 @@ The command line is executed each time: </source> <target> 명령줄은 다음과 같은 경우에 매번 실행 됩니다: -- 모든 디렉토리가 사용 가능할 경우 (예. USB 스틱 삽입시) +- 모든 디렉토리가 사용 가능할 경우 (예 : USB 스틱 삽입시) - 해당 디렉토리 또는 서브디렉토리 내의 파일이 변경될 경우 </target> @@ -319,7 +319,7 @@ The command line is executed each time: <target>디렉토리 입력 필드가 비어 있습니다.</target> <source>Logging</source> -<target>로그 중</target> +<target>로깅</target> <source>File time and size</source> <target>파일 시간 및 크기</target> @@ -508,7 +508,7 @@ The command line is executed each time: <target>마지막으로 사용한 설정 (DEL 키를 누르면 리스트에서 삭제)</target> <source>Hide excluded items</source> -<target>제외 아이템 숨기기</target> +<target>제외된 항목 숨기기</target> <source>Hide filtered or temporarily excluded files</source> <target>필터링 되거나 임시 제외될 파일 숨기기</target> @@ -529,25 +529,25 @@ The command line is executed each time: <target>작업 :</target> <source>Items found:</source> -<target>발견된 요소 :</target> +<target>발견된 항목 :</target> <source>Items remaining:</source> -<target>남은 요소 :</target> +<target>남은 항목 :</target> <source>Speed:</source> <target>속도 :</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>남은 시간 :</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>경과 시간 :</target> <source>Batch job</source> <target>일괄 작업</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>자동 동기화를 위한 일괄 파일 생성. 일괄모드 시작을 원할 경우, 해당 파일을 더블클릭하거나 명령줄: FreeFileSync.exe <ffs_batch file>을 실행하십시오. 이 작업은 운영체제 작업관리 기능에서도 예약 가능합니다.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>일괄 파일 생성 및 자동 동기화. 배치모드 시작은 본 파일을 더블클릭하거나 다음 명령을 실행 : FreeFileSync.exe SyncJob.ffs_batch. 이 작업은 운영체제 작업관리 기능에서도 예약 가능합니다.</target> <source>Help</source> <target>도움말</target> @@ -561,8 +561,8 @@ The command line is executed each time: <source>Right</source> <target>우측</target> -<source>Overview</source> -<target>개요</target> +<source>Sync setttings</source> +<target>싱크(동기화) 설정</target> <source>Status feedback</source> <target>상태 피드백</target> @@ -676,7 +676,7 @@ is the same <target>동기화 작업 중...</target> <source>Items processed:</source> -<target>처리된 요소 :</target> +<target>처리된 항목 :</target> <source>&Pause</source> <target>일시정지(&P)</target> @@ -708,8 +708,8 @@ is the same <source>Published under the GNU General Public License</source> <target>GNU 일반 공용 라이센스에 의한 출시</target> -<source>Ignore subsequent errors</source> -<target>이후 일어나는 오류 무시</target> +<source>Ignore further errors</source> +<target>더 이상의 오류는 무시</target> <source>Hide further error messages during the current process</source> <target>현재 처리과정 동안 추가오류 메세지 숨기기</target> @@ -732,22 +732,22 @@ is the same <source>&No</source> <target>아니오(&N)</target> +<source>Use Recycle Bin</source> +<target>휴지통 사용</target> + <source>Delete on both sides</source> <target>양측 모두 삭제</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>어느 한쪽의 파일만 선택하더라도 양측 모두 삭제</target> -<source>Use Recycle Bin</source> -<target>휴지통 사용</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -모든 필터 설정과 일치하는 파일/디렉토리 만을 동기화 대상으로 선택합니다. -참고 : 메인 동기화 디렉토리와 대비하여 필터 이름을 지정해야 합니다. +모든 필터 설정과 일치하는 파일만 동기화 됩니다. +참고 : 파일 이름은 기본 디렉토리와 상응해야 합니다! </target> <source>Hints:</source> @@ -783,20 +783,20 @@ Exclude: \stuff\temp\* <source>Exclude</source> <target>제외</target> -<source>Minimum file size</source> -<target>최소 파일 크기</target> +<source>Time span</source> +<target>시간간격(타임스팬)</target> -<source>Maximum file size</source> -<target>최대 파일 크기</target> +<source>File size</source> +<target>파일 크기</target> -<source>&Default</source> -<target>기본 설정/값(&D)</target> +<source>Minimum</source> +<target>최소</target> -<source>Move column up</source> -<target>열 위로 이동</target> +<source>Maximum</source> +<target>최대</target> -<source>Move column down</source> -<target>열 아래로 이동</target> +<source>&Default</source> +<target>기본 설정/값(&D)</target> <source>Transactional file copy</source> <target>트랜잭션 파일 복사</target> @@ -816,17 +816,11 @@ Exclude: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>파일 및 디렉토리 권한 전송 (관리자 권한이 필요함)</target> -<source>Hidden dialogs:</source> -<target>다이얼로그 숨기기</target> - -<source>Reset</source> -<target>리셋</target> - -<source>Show hidden dialogs</source> -<target>숨긴 다이얼로그 표시</target> +<source>Restore hidden dialogs</source> +<target>숨겨진 대화창 복원</target> <source>External applications</source> -<target>외부 애플리케이션</target> +<target>외부 응용 프로그램</target> <source>Description</source> <target>설명</target> @@ -855,8 +849,8 @@ Exclude: \stuff\temp\* <source>Folder pairs</source> <target>폴더 페어(짝)</target> -<source>Compressed view</source> -<target>압축 보기</target> +<source>Overview</source> +<target>개요</target> <source>Select view</source> <target>보기 선택</target> @@ -885,8 +879,8 @@ Exclude: \stuff\temp\* <source>Exclude all</source> <target>모두 제외</target> -<source>Icon size:</source> -<target>아이콘 크기</target> +<source>Show icons:</source> +<target>아이콘 표시 :</target> <source>Small</source> <target>작게</target> @@ -912,6 +906,9 @@ Exclude: \stuff\temp\* <source>Configuration saved!</source> <target>설정 저장 완료!</target> +<source>Never save changes</source> +<target>변경사항 절대 저장 안 함.</target> + <source>Save changes to current configuration?</source> <target>현재 설정의 변경 내용을 저장하시겠습니까?</target> @@ -1023,9 +1020,6 @@ Exclude: \stuff\temp\* <source>Error writing file:</source> <target>파일을 쓰던 중 발생한 오류 :</target> -<source>Batch file created successfully!</source> -<target>일괄 파일이 성공적으로 생성 됐습니다!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1100,6 +1094,9 @@ Exclude: \stuff\temp\* <source>This year</source> <target>올해</target> +<source>Last x days</source> +<target>최근 x일</target> + <source>Byte</source> <target>바이트</target> @@ -1109,11 +1106,8 @@ Exclude: \stuff\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>필터 : 모든 페어(짝)</target> - -<source>Filter: Single pair</source> -<target>필터 : 단일 페어(짝)</target> +<source>Filter</source> +<target>필터</target> <source>Direct</source> <target>다이렉트</target> @@ -1125,7 +1119,7 @@ Exclude: \stuff\temp\* <target>NTFS 권한 복사</target> <source>Integrate external applications into context menu. The following macros are available:</source> -<target>외부 애플리케이션을 Context Menu에 통합. 다음 매크로가 사용 가능합니다 :</target> +<target>외부 응용 프로그램을 Context Menu에 통합. 다음 매크로가 사용 가능합니다 :</target> <source>- full file or directory name</source> <target>- 전체 파일 또는 디렉토리 이름</target> @@ -1139,8 +1133,8 @@ Exclude: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- %dir 의 반대측 대상</target> -<source>Restore all hidden dialogs?</source> -<target>모든 숨긴 다이얼로그를 복원 하시겠습니까?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>숨겨진 대화창이나 경고 메세지를 다시 보이게 하시겠습니까?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1311,8 +1305,8 @@ Exclude: \stuff\temp\* <source>Preparing synchronization...</source> <target>동기화 준비 중...</target> -<source>Memory allocation failed!</source> -<target>메모리 할당 실패!</target> +<source>Out of memory!</source> +<target>메모리 부족!</target> <source>File %x has an invalid date!</source> <target>파일 %x 의 날짜가 유효하지 않습니다!</target> @@ -1467,11 +1461,11 @@ Exclude: \stuff\temp\* <source>Generating database...</source> <target>데이터베이스 생성 중...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>구성 설정에 따라 동기화 할 내용이 없습니다!</target> +<source>Nothing to synchronize!</source> +<target>동기화 할 항목이 없습니다!</target> -<source>Error copying locked file %x!</source> -<target>복사 실패! 파일 %x 에 락이 걸려 있습니다.</target> +<source>Unable to copy locked file %x!</source> +<target>잠겨진 파일 %x 을(를) 복사할 수 없습니다!</target> <source>Data verification error: Source and target file have different content!</source> <target>데이터 확인 오류 : 소스 및 타겟 파일의 내용이 다릅니다!</target> diff --git a/BUILD/Languages/polish.lng b/BUILD/Languages/polish.lng index b646108a..44381d46 100644 --- a/BUILD/Languages/polish.lng +++ b/BUILD/Languages/polish.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Konfiguruj filtr</target> -<source>Customize columns</source> -<target>Dostosuj kolumny</target> - <source>Global settings</source> <target>Ustawienia programu</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Przeglądaj</target> -<source>Error reading from synchronization database:</source> -<target>Błąd odczytu z bazy danych synchronizacji:</target> - -<source>Error writing to synchronization database:</source> -<target>Błąd zapisu do bazy danych synchronizacji:</target> - <source>Invalid command line: %x</source> <target>Nieprawidłowa komenda: %x</target> +<source>Info</source> +<target>Info</target> + +<source>Fatal Error</source> +<target>Błąd krytyczny</target> + <source>Windows Error Code %x:</source> <target>Błąd systemu Windows %x:</target> @@ -140,15 +137,21 @@ <pluralform>%x Bajtów</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Błąd odczytu z bazy danych synchronizacji:</target> + +<source>Error writing to synchronization database:</source> +<target>Błąd zapisu do bazy danych synchronizacji:</target> + +<source>Incompatible synchronization database format:</source> +<target>Niepoprawny format bazy danych dla synchronizacji:</target> + <source>Initial synchronization:</source> <target>Wstępna synchronizacja:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>Jeden z plików bazy danych FreeFileSync nie istnieje:</target> -<source>Incompatible synchronization database format:</source> -<target>Niepoprawny format bazy danych dla synchronizacji:</target> - <source>Database files do not share a common synchronization session:</source> <target>Pliki danych nie współdzielą wspólnej sesji synchronizacji:</target> @@ -174,12 +177,6 @@ <pluralform>%x sekund</pluralform> </target> -<source>Info</source> -<target>Info</target> - -<source>Fatal Error</source> -<target>Błąd krytyczny</target> - <source>Error reading file:</source> <target>Błąd odczytu pliku:</target> @@ -205,11 +202,14 @@ <source>Error parsing configuration file:</source> <target>Błąd parsowania pliku konfiguracyjnego:</target> -<source>Error moving to Recycle Bin:</source> -<target>Błąd podczas przenoszenia do kosza:</target> +<source>Configuration loaded partially only:</source> +<target></target> -<source>Could not load a required DLL:</source> -<target>Nie można załadować wymaganej biblioteki DLL:</target> +<source>Unable to move %x to the Recycle Bin!</source> +<target></target> + +<source>Cannot load file %x.</source> +<target></target> <source>Error accessing Volume Shadow Copy Service!</source> <target>Błąd podczas dostępdu do usługi Volume Shadow Copy!</target> @@ -217,10 +217,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>Tworzenie Shadow Copies dla WOW64 nie jest obsługiwane. Zainstaluj 64 bitową wersję FreeFileSync.</target> -<source>Could not determine volume name for file:</source> -<target>Nie można określić nazwy dysku dla pliku:</target> +<source>Cannot determine volume name for file:</source> +<target></target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>Dysk %x nie jest częścią pliku %y!</target> <source>/sec</source> @@ -229,8 +229,8 @@ <source>File does not exist:</source> <target>Plik nie istnieje:</target> -<source>Could not read values for the following XML nodes:</source> -<target>Nie można odczytać wartości dla danych gałęzi XML:</target> +<source>Cannot read the following XML elements:</source> +<target></target> <source>S&ave configuration...</source> <target>Z&apisz konfigurację...</target> @@ -543,17 +543,17 @@ Komenda jest wykonwywana za każdym razem gdy: <source>Speed:</source> <target>Prędkość:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Pozostały czas:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Czas:</target> <source>Batch job</source> <target>Plik wsadowy</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Utwórz plik wsadowy do automatycznej synchronizacji. Aby uruchomić zadanie w trybie wsadowym, kliknij dwa razy na plik. Możesz je również wywołać z konsoli poleceniem FreeFileSync.exe <ffs_batch file>. Plik wsadowy może być również wywoływany przez planer zadań w Twoim systemie.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target></target> <source>Help</source> <target>Pomoc</target> @@ -567,8 +567,8 @@ Komenda jest wykonwywana za każdym razem gdy: <source>Right</source> <target>Prawy</target> -<source>Overview</source> -<target>Przegląd</target> +<source>Sync setttings</source> +<target></target> <source>Status feedback</source> <target>Opinia statusu</target> @@ -714,8 +714,8 @@ jest identyczna <source>Published under the GNU General Public License</source> <target>Udostępnione na zasadach licencji GNU General Public License</target> -<source>Ignore subsequent errors</source> -<target>Ignoruj kolejne błędy</target> +<source>Ignore further errors</source> +<target></target> <source>Hide further error messages during the current process</source> <target>Ukryj kolejne informacje o błędach dla tego zadania</target> @@ -738,23 +738,20 @@ jest identyczna <source>&No</source> <target>&Nie</target> +<source>Use Recycle Bin</source> +<target>Użyj kosza</target> + <source>Delete on both sides</source> <target>Usuń po obu stronach</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Usuń po obu stronach nawet jeżeli plik zaznaczony jest tylko po jednej stronie</target> -<source>Use Recycle Bin</source> -<target>Użyj kosza</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> -<target> -Tylko pliki i katalogi, które spełniły wszystkie kryteria filtrów będą poddane synchronizacji. -Uwaga: Podana nazwa musi być relatywną ścieżką względem synchronizowanych katalogów. -</target> +<target></target> <source>Hints:</source> <target>Wskazówki:</target> @@ -789,20 +786,20 @@ Wyklucz: \moje\temp\* <source>Exclude</source> <target>Wyklucz</target> -<source>Minimum file size</source> -<target>Minimalny rozmiar pliku</target> +<source>Time span</source> +<target></target> -<source>Maximum file size</source> -<target>Maksymalny rozmiar pliku</target> +<source>File size</source> +<target></target> -<source>&Default</source> -<target>&Domyślne</target> +<source>Minimum</source> +<target></target> -<source>Move column up</source> -<target>Przesuń kolumnę do góry</target> +<source>Maximum</source> +<target></target> -<source>Move column down</source> -<target>Przesuń kolumnę w dół</target> +<source>&Default</source> +<target>&Domyślne</target> <source>Transactional file copy</source> <target>Transakcyjne kopiowanie pliku</target> @@ -822,14 +819,8 @@ Wyklucz: \moje\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Transfer uprawnień plików i katalogów (Wymaga uprawnień Administratora)</target> -<source>Hidden dialogs:</source> -<target>Ukryte dialogi:</target> - -<source>Reset</source> -<target>Resetuj</target> - -<source>Show hidden dialogs</source> -<target>Pokaż ukryte dialogi</target> +<source>Restore hidden dialogs</source> +<target></target> <source>External applications</source> <target>Aplikacje zewnętrzne</target> @@ -861,8 +852,8 @@ Wyklucz: \moje\temp\* <source>Folder pairs</source> <target>Pary folderów</target> -<source>Compressed view</source> -<target>Widok skompresowany</target> +<source>Overview</source> +<target>Przegląd</target> <source>Select view</source> <target>Określ widok</target> @@ -891,8 +882,8 @@ Wyklucz: \moje\temp\* <source>Exclude all</source> <target>Odznacz wszystko</target> -<source>Icon size:</source> -<target>Rozmiar ikony:</target> +<source>Show icons:</source> +<target></target> <source>Small</source> <target>Mały</target> @@ -918,6 +909,9 @@ Wyklucz: \moje\temp\* <source>Configuration saved!</source> <target>Konfiguracja zapisana!</target> +<source>Never save changes</source> +<target></target> + <source>Save changes to current configuration?</source> <target>Zapisać zmiany obecnej konfiguracji?</target> @@ -1029,9 +1023,6 @@ Wyklucz: \moje\temp\* <source>Error writing file:</source> <target>Błąd zapisu pliku:</target> -<source>Batch file created successfully!</source> -<target>Plik wsadowy utworzony pomyślnie!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1114,6 +1105,9 @@ Wyklucz: \moje\temp\* <source>This year</source> <target>W tym roku</target> +<source>Last x days</source> +<target></target> + <source>Byte</source> <target>Bajtów</target> @@ -1123,11 +1117,8 @@ Wyklucz: \moje\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>Filtr: Wszystkie pary</target> - -<source>Filter: Single pair</source> -<target>Filtr: Pojedyńcza para</target> +<source>Filter</source> +<target></target> <source>Direct</source> <target>Bezpośrednio</target> @@ -1153,8 +1144,8 @@ Wyklucz: \moje\temp\* <source>- Other side's counterpart to %dir</source> <target>- Odpowiednik %dir</target> -<source>Restore all hidden dialogs?</source> -<target>Przywrócić wszystkie ukryte dialogi?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target></target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1335,8 +1326,8 @@ Wyklucz: \moje\temp\* <source>Preparing synchronization...</source> <target>Przygotowywanie synchronizacji...</target> -<source>Memory allocation failed!</source> -<target>Błąd alokacji zasobów!</target> +<source>Out of memory!</source> +<target></target> <source>File %x has an invalid date!</source> <target>Plik %x ma nieprawidłową datę!</target> @@ -1491,11 +1482,11 @@ Wyklucz: \moje\temp\* <source>Generating database...</source> <target>Generowanie bazy danych...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>Brak elementów do synchronizacji!</target> +<source>Nothing to synchronize!</source> +<target></target> -<source>Error copying locked file %x!</source> -<target>Błąd podczas kopiowania zablokowanego pliku %x!</target> +<source>Unable to copy locked file %x!</source> +<target></target> <source>Data verification error: Source and target file have different content!</source> <target>Błąd weryfikacji danych: Plik źródłowy i docelowy różnią się zawartością!</target> diff --git a/BUILD/Languages/portuguese.lng b/BUILD/Languages/portuguese.lng index 515711d1..3bbf2d40 100644 --- a/BUILD/Languages/portuguese.lng +++ b/BUILD/Languages/portuguese.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Configurar filtros</target> -<source>Customize columns</source> -<target>Personalizar colunas</target> - <source>Global settings</source> <target>Opções</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Procurar</target> -<source>Error reading from synchronization database:</source> -<target>Erro ao ler a base de dados de sincronização:</target> - -<source>Error writing to synchronization database:</source> -<target>Erro na escrita da base de dados de sincronização:</target> - <source>Invalid command line: %x</source> <target>Linha de comando inválida: %x</target> +<source>Info</source> +<target>Info</target> + +<source>Fatal Error</source> +<target>Erro crítico</target> + <source>Windows Error Code %x:</source> <target>Código de erro do Windows %x:</target> @@ -139,15 +136,21 @@ <pluralform>%x Bytes</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Erro ao ler a base de dados de sincronização:</target> + +<source>Error writing to synchronization database:</source> +<target>Erro na escrita da base de dados de sincronização:</target> + +<source>Incompatible synchronization database format:</source> +<target>Formato de base de dados de sincronização incompatível:</target> + <source>Initial synchronization:</source> <target>Sincronização inicial:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>Um dos ficheiros da base de dados não existe:</target> -<source>Incompatible synchronization database format:</source> -<target>Formato de base de dados de sincronização incompatível:</target> - <source>Database files do not share a common synchronization session:</source> <target>Bases de dados não partilham a mesma sessão de sincronização:</target> @@ -172,12 +175,6 @@ <pluralform>%x segs</pluralform> </target> -<source>Info</source> -<target>Info</target> - -<source>Fatal Error</source> -<target>Erro crítico</target> - <source>Error reading file:</source> <target>Erro de leitura de ficheiro:</target> @@ -202,11 +199,14 @@ <source>Error parsing configuration file:</source> <target>Erro de leitura do ficheiro de configuração:</target> -<source>Error moving to Recycle Bin:</source> -<target>Erro ao mover para a Reciclagem:</target> +<source>Configuration loaded partially only:</source> +<target>Configuração carregada parcialmente:</target> -<source>Could not load a required DLL:</source> -<target>Não foi possível carregar a DLL:</target> +<source>Unable to move %x to the Recycle Bin!</source> +<target>Não é possível mover %x para a Reciclagem!</target> + +<source>Cannot load file %x.</source> +<target>Não é possível carregar o ficheiro %x.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>Erro no acesso ao serviço Volume Shadow Copy!</target> @@ -214,10 +214,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>Fazer cópias fantasma em WOW64 não é suportado. Por favor usar a versão 64-bit.</target> -<source>Could not determine volume name for file:</source> -<target>Não é possível determinar o nome do volume para o ficheiro:</target> +<source>Cannot determine volume name for file:</source> +<target>Não é possível obter o nome do volume para o ficheiro:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>Nome do volume %x não faz parte do ficheiro %y!</target> <source>/sec</source> @@ -226,8 +226,8 @@ <source>File does not exist:</source> <target>O ficheiro não existe:</target> -<source>Could not read values for the following XML nodes:</source> -<target>Não foi possível ler os valores dos seguintes nós XML:</target> +<source>Cannot read the following XML elements:</source> +<target>Não é possível ler os elementos XML:</target> <source>S&ave configuration...</source> <target>G&uardar a configuração...</target> @@ -540,17 +540,17 @@ A linha de comandos é executada cada vez que: <source>Speed:</source> <target>Velocidade:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Tempo restante:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Tempo passado:</target> <source>Batch job</source> <target>Ficheiro Batch</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Criar ficheiro batch para sincronização automática. Para iniciar em modo batch, faço duplo-clique sobre o ficheiro ou execute via linha de comando: FreeFileSync.exe <ficheiro ffs_batch>. Também pode ser programado no gestor de tarefas do sistema operativo.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>Criar um ficheiro batch e automatizar a sincronização. Para iniciar o batch, fazer duplo-clique no ficheiro ou correr o comando: FreeFileSync.exe SyncJob.ffs_batch. Também pode ser adicionado no planeador de tarefas do sistema.</target> <source>Help</source> <target>Ajuda</target> @@ -564,9 +564,6 @@ A linha de comandos é executada cada vez que: <source>Right</source> <target>Direita</target> -<source>Overview</source> -<target>Vista</target> - <source>Status feedback</source> <target>Retorno de estado</target> @@ -710,8 +707,8 @@ Os ficheiros são considerados iguais se <source>Published under the GNU General Public License</source> <target>Publicado sobre GNU General Public License</target> -<source>Ignore subsequent errors</source> -<target>Ignorar erros subsequentes</target> +<source>Ignore further errors</source> +<target>Ignorar erros seguintes</target> <source>Hide further error messages during the current process</source> <target>Ocultar próximas mensagens de erro durante este processo</target> @@ -734,22 +731,22 @@ Os ficheiros são considerados iguais se <source>&No</source> <target>&Não</target> +<source>Use Recycle Bin</source> +<target>Utilizar Reciclagem</target> + <source>Delete on both sides</source> <target>Eliminar em ambos os lados</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Eliminar em ambos os lados mesmo se o ficheiro só está seleccionado num lado</target> -<source>Use Recycle Bin</source> -<target>Utilizar Reciclagem</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Apenas ficheiros/directórios que coincidam com as opções de filtros vão ser selecionados para sincronização. -Nota: Os filtros devem ser especificados em relação aos directórios principais de sincronização. +Apenas ficheiros que condigam com todos os filtros serão sincronizados. +Nota: Nome dos ficheiros tem que ser relativo aos diretórios base! </target> <source>Hints:</source> @@ -785,20 +782,20 @@ Excluir: \stuff\temp\* <source>Exclude</source> <target>Excluir</target> -<source>Minimum file size</source> -<target>Tamanho ficheiro mínimo</target> +<source>Time span</source> +<target>Intervalo de tempo</target> -<source>Maximum file size</source> -<target>Tamanho ficheiro máximo</target> +<source>File size</source> +<target>Tamanho ficheiro</target> -<source>&Default</source> -<target>&Config. Iniciais</target> +<source>Minimum</source> +<target>Mínimo</target> -<source>Move column up</source> -<target>Mover coluna para cima</target> +<source>Maximum</source> +<target>Máximo</target> -<source>Move column down</source> -<target>Mover coluna para baixo</target> +<source>&Default</source> +<target>&Config. Iniciais</target> <source>Transactional file copy</source> <target>Copia ficheiro transacional</target> @@ -818,14 +815,8 @@ Excluir: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Transferir ficheiro e permissões (Requer direitos de administrador)</target> -<source>Hidden dialogs:</source> -<target>Diálogos ocultos:</target> - -<source>Reset</source> -<target>Reiniciar</target> - -<source>Show hidden dialogs</source> -<target>Mostrar diálogos ocultos</target> +<source>Restore hidden dialogs</source> +<target>Restaurar diálogos escondidos</target> <source>External applications</source> <target>Aplicações externas</target> @@ -857,8 +848,8 @@ Excluir: \stuff\temp\* <source>Folder pairs</source> <target>Par de directório</target> -<source>Compressed view</source> -<target>Vista compacta</target> +<source>Overview</source> +<target>Vista</target> <source>Select view</source> <target>Seleccionar vista</target> @@ -876,7 +867,7 @@ Excluir: \stuff\temp\* <target>Excluir por filtro:</target> <source><multiple selection></source> -<target><selecção múltipla></target> +<target><seleção múltipla></target> <source>Delete</source> <target>Eliminar</target> @@ -887,8 +878,8 @@ Excluir: \stuff\temp\* <source>Exclude all</source> <target>Excluir tudo</target> -<source>Icon size:</source> -<target>Tamanho ícone:</target> +<source>Show icons:</source> +<target>Mostrar ícones:</target> <source>Small</source> <target>Pequeno</target> @@ -914,6 +905,9 @@ Excluir: \stuff\temp\* <source>Configuration saved!</source> <target>Configuração guardada!</target> +<source>Never save changes</source> +<target>Nunca guardar alterações</target> + <source>Save changes to current configuration?</source> <target>Guardar alterações à configuração?</target> @@ -1025,9 +1019,6 @@ Excluir: \stuff\temp\* <source>Error writing file:</source> <target>Erro de escrita no ficheiro:</target> -<source>Batch file created successfully!</source> -<target>Ficheiro batch criado com sucesso!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1106,6 +1097,9 @@ Excluir: \stuff\temp\* <source>This year</source> <target>Este ano</target> +<source>Last x days</source> +<target>Últimos x dias</target> + <source>Byte</source> <target>Byte</target> @@ -1115,11 +1109,8 @@ Excluir: \stuff\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>Filtro: Todos os pares</target> - -<source>Filter: Single pair</source> -<target>Filtro: Par simples</target> +<source>Filter</source> +<target>Filtro</target> <source>Direct</source> <target>Direto</target> @@ -1145,8 +1136,8 @@ Excluir: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- Contrapartida de %dir</target> -<source>Restore all hidden dialogs?</source> -<target>Restaurar os diálogos escondidos?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>Tornar visíveis diálogos e mensagens de aviso novamente?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1277,9 +1268,6 @@ Excluir: \stuff\temp\* <source>Error copying file:</source> <target>Erro ao copiar ficheiro:</target> -<source>Error opening file:</source> -<target>Erro ao abrir ficheiro:</target> - <source>Error traversing directory:</source> <target>Erro ao percorrer a pasta:</target> @@ -1322,8 +1310,8 @@ Excluir: \stuff\temp\* <source>Preparing synchronization...</source> <target>A preparar sincronização...</target> -<source>Memory allocation failed!</source> -<target>Alocação de memória falhou!</target> +<source>Out of memory!</source> +<target>Sem memória disponível!</target> <source>File %x has an invalid date!</source> <target>Ficheiro %x tem data inválida!</target> @@ -1478,11 +1466,11 @@ Excluir: \stuff\temp\* <source>Generating database...</source> <target>A gerar base de dados...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>Nada a sincronizar de acordo com a configuração!</target> +<source>Nothing to synchronize!</source> +<target>Nada a sincronizar!</target> -<source>Error copying locked file %x!</source> -<target>Erro ao copiar ficheiro bloqueado %x!</target> +<source>Unable to copy locked file %x!</source> +<target>Não é possível copiar o ficheiro bloqueado %x!</target> <source>Data verification error: Source and target file have different content!</source> <target>Erro na verificação de dados: ficheiro fonte e de destino têm conteúdo diferente!</target> diff --git a/BUILD/Languages/portuguese_br.lng b/BUILD/Languages/portuguese_br.lng index ad2c2f2c..9d91309a 100644 --- a/BUILD/Languages/portuguese_br.lng +++ b/BUILD/Languages/portuguese_br.lng @@ -41,7 +41,7 @@ <target>Limpar configurações do filtro</target> <source>Create a batch job</source> -<target>Criar arquivo batch</target> +<target>Criar arquivo de lote</target> <source>Synchronization settings</source> <target>Parâmetros de sincronização</target> @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Configurar filtros</target> -<source>Customize columns</source> -<target>Personalizar colunas</target> - <source>Global settings</source> <target>Configurações</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Procurar</target> -<source>Error reading from synchronization database:</source> -<target>Erro ao ler do banco de dados de sincronização:</target> - -<source>Error writing to synchronization database:</source> -<target>Erro ao escrever no banco de dados de sincronização:</target> - <source>Invalid command line: %x</source> <target>Linha de comando inválida: %x</target> +<source>Info</source> +<target>Informações</target> + +<source>Fatal Error</source> +<target>Erro fatal</target> + <source>Windows Error Code %x:</source> <target>Código de Erro do Windows %x:</target> @@ -125,7 +122,7 @@ <target>%x MB</target> <source>%x KB</source> -<target>%x KB</target> +<target>%x kB</target> <source>%x GB</source> <target>%x GB</target> @@ -139,15 +136,21 @@ <pluralform>%x Bytes</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Erro ao ler do banco de dados de sincronização:</target> + +<source>Error writing to synchronization database:</source> +<target>Erro ao escrever no banco de dados de sincronização:</target> + +<source>Incompatible synchronization database format:</source> +<target>Formato de banco de dados de sincronização incompatível:</target> + <source>Initial synchronization:</source> <target>Sincronização inicial:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>Um dos arquivos de banco de dados do FreeFileSync ainda não existe:</target> -<source>Incompatible synchronization database format:</source> -<target>Formato de banco de dados de sincronização incompatível:</target> - <source>Database files do not share a common synchronization session:</source> <target>Arquivos de banco de dados não compartilham uma sessão de sincronização comum:</target> @@ -172,12 +175,6 @@ <pluralform>%x seg</pluralform> </target> -<source>Info</source> -<target>Informações</target> - -<source>Fatal Error</source> -<target>Erro fatal</target> - <source>Error reading file:</source> <target>Erro ao ler arquivo:</target> @@ -202,11 +199,14 @@ <source>Error parsing configuration file:</source> <target>Erro de leitura do arquivo de configuração:</target> -<source>Error moving to Recycle Bin:</source> -<target>Erro ao mover para a Lixeira:</target> +<source>Configuration loaded partially only:</source> +<target>A configuração foi carregada parcialmente apenas:</target> + +<source>Unable to move %x to the Recycle Bin!</source> +<target>Não foi possível mover %x para a Lixeira!</target> -<source>Could not load a required DLL:</source> -<target>Não foi possível carregar uma DLL requerida:</target> +<source>Cannot load file %x.</source> +<target>Não foi possível carregar o aquivo %x.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>Erro ao acessar o Serviço de Cópia de Sombra de Volume!</target> @@ -214,10 +214,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>Cópias de sombra no WOW64 não são suportadas. Por favor use a versão 64-bits do FreeFileSync.</target> -<source>Could not determine volume name for file:</source> +<source>Cannot determine volume name for file:</source> <target>Não foi possível determinar o nome do volume para o arquivo:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>Nome do volume %x não é parte do arquivo %y!</target> <source>/sec</source> @@ -226,8 +226,8 @@ <source>File does not exist:</source> <target>O arquivo não existe:</target> -<source>Could not read values for the following XML nodes:</source> -<target>Não foi possível ler os valores para os seguintes nós XML:</target> +<source>Cannot read the following XML elements:</source> +<target>Não foi possível ler os seguintes elementos XML:</target> <source>S&ave configuration...</source> <target>S&alvar configuração...</target> @@ -322,7 +322,7 @@ A linha de comando é executada cada vez que: <target>Um campo de entrada de diretório está vazio.</target> <source>Logging</source> -<target>Log</target> +<target>Ver Log</target> <source>File time and size</source> <target>Data e tamanho do arquivo</target> @@ -343,19 +343,19 @@ A linha de comando é executada cada vez que: <target>Personalizado</target> <source>FreeFileSync batch file</source> -<target>FreeFileSync arquivo batch</target> +<target>Arquivo de lote do FreeFileSync</target> <source>FreeFileSync configuration</source> <target>FreeFileSync configuração</target> <source>FreeFileSync Batch Job</source> -<target>FreeFileSync Arquivo batch</target> +<target>Tarefa em lote do FreeFileSync</target> <source>Unable to create log file!</source> <target>Não foi possível criar arquivo de log!</target> <source>Batch execution</source> -<target>Execução do batch</target> +<target>Execução da tarefa em lote</target> <source>Stop</source> <target>Parar</target> @@ -466,7 +466,7 @@ A linha de comando é executada cada vez que: <target>&Configurações...</target> <source>&Create batch job...</source> -<target>C&riar um arquivo batch...</target> +<target>C&riar um arquivo de lote...</target> <source>&Export file list...</source> <target>&Exportar lista de arquivos...</target> @@ -540,17 +540,17 @@ A linha de comando é executada cada vez que: <source>Speed:</source> <target>Velocidade:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Tempo restante:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Tempo decorrido:</target> <source>Batch job</source> -<target>Arquivo Batch</target> +<target>Tarefa em lote</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Cria um arquivo batch para sincronização automática. Para iniciar o modo batch, simplesmente dê um click-duplo no arquivo ou execute via linha de comando: FreeFileSync.exe <arquivo ffs_batch>. Também pode ser agendado no Agendador de Tarefas do sistema operacional.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>Cria um arquivo de lote e automatiza a sincronização. Para iniciar em modo de lote, simplesmente dê um clique-duplo neste arquivo ou execute o comando: FreeFileSync.exe SyncJob.ffs_batch. Também pode ser agendado pelo Agendador de Tarefas do sistema operacional.</target> <source>Help</source> <target>Ajuda</target> @@ -564,9 +564,6 @@ A linha de comando é executada cada vez que: <source>Right</source> <target>Direita</target> -<source>Overview</source> -<target>Parâmetros</target> - <source>Status feedback</source> <target>Informação do Status</target> @@ -583,7 +580,7 @@ A linha de comando é executada cada vez que: <target>Escolha um diretório para salvar o arquivo de log:</target> <source>Batch settings</source> -<target>Configurações</target> +<target>Configurações da tarefa em lote</target> <source>&Save</source> <target>&Salvar</target> @@ -711,7 +708,7 @@ Os arquivos são considerados iguais se <source>Published under the GNU General Public License</source> <target>Publicado sobre a GNU General Public License</target> -<source>Ignore subsequent errors</source> +<source>Ignore further errors</source> <target>Ignorar erros subsequentes</target> <source>Hide further error messages during the current process</source> @@ -724,7 +721,7 @@ Os arquivos são considerados iguais se <target>&Tentar Novamente</target> <source>Do not show this dialog again</source> -<target>Não mostrar esse diálogo novamente</target> +<target>Não mostrar este diálogo novamente</target> <source>&Switch</source> <target>&Alterar</target> @@ -735,22 +732,22 @@ Os arquivos são considerados iguais se <source>&No</source> <target>&Não</target> +<source>Use Recycle Bin</source> +<target>Utilizar Lixeira</target> + <source>Delete on both sides</source> <target>Apagar em ambos os lados</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Apagar em ambos os lados mesmo se o arquivo está selecionado só em um lado</target> -<source>Use Recycle Bin</source> -<target>Utilizar Lixeira</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Apenas arquivos/diretórios que satisfazem todos as configurações dos filtros serão selecionados para sincronização. -Nota: O nome do filtro deve ser especificado relativo(!) ao diretório principal de sincronização. +Apenas arquivos que correspondem a todas as configurações do filtro serão sincronizados. +Nota: Os nomes dos arquivos devem ser relativos aos diretórios base! </target> <source>Hints:</source> @@ -786,20 +783,20 @@ Excluir: \stuff\temp\* <source>Exclude</source> <target>Excluir</target> -<source>Minimum file size</source> -<target>Tamanho mínimo do arquivo</target> +<source>Time span</source> +<target>Intervalo de tempo</target> -<source>Maximum file size</source> -<target>Tamanho máximo do arquivo</target> +<source>File size</source> +<target>Tamanho do arquivo</target> -<source>&Default</source> -<target>&Config. Padrão</target> +<source>Minimum</source> +<target>Mínimo</target> -<source>Move column up</source> -<target>Mover coluna para cima</target> +<source>Maximum</source> +<target>Máximo</target> -<source>Move column down</source> -<target>Mover coluna para baixo</target> +<source>&Default</source> +<target>&Config. Padrão</target> <source>Transactional file copy</source> <target>Cópia de arquivo transacional</target> @@ -819,14 +816,8 @@ Excluir: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Transfere as permissões de arquivos e diretórios (Requer direitos de Administrador)</target> -<source>Hidden dialogs:</source> -<target>Diálogos ocultados:</target> - -<source>Reset</source> -<target>Restaurar</target> - -<source>Show hidden dialogs</source> -<target>Mostrar diálogos ocultados</target> +<source>Restore hidden dialogs</source> +<target>Restaurar diálogos ocultados</target> <source>External applications</source> <target>Aplicações externas</target> @@ -858,8 +849,8 @@ Excluir: \stuff\temp\* <source>Folder pairs</source> <target>Pares de pastas</target> -<source>Compressed view</source> -<target>Visualização compacta</target> +<source>Overview</source> +<target>Parâmetros</target> <source>Select view</source> <target>Selecionar visualização</target> @@ -888,8 +879,8 @@ Excluir: \stuff\temp\* <source>Exclude all</source> <target>Excluir todos</target> -<source>Icon size:</source> -<target>Tamanho do ícone:</target> +<source>Show icons:</source> +<target>Mostrar ícones:</target> <source>Small</source> <target>Pequeno</target> @@ -915,6 +906,9 @@ Excluir: \stuff\temp\* <source>Configuration saved!</source> <target>Configuração salva!</target> +<source>Never save changes</source> +<target>Nunca salvar alterações</target> + <source>Save changes to current configuration?</source> <target>Salvar modificações para a configuração atual?</target> @@ -1026,9 +1020,6 @@ Excluir: \stuff\temp\* <source>Error writing file:</source> <target>Erro ao escrever arquivo:</target> -<source>Batch file created successfully!</source> -<target>Arquivo batch criado com sucesso!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1107,20 +1098,20 @@ Excluir: \stuff\temp\* <source>This year</source> <target>Este ano</target> +<source>Last x days</source> +<target>Últimos x dias</target> + <source>Byte</source> <target>Byte</target> <source>KB</source> -<target>KB</target> +<target>kB</target> <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>Filtro: Todos os pares</target> - -<source>Filter: Single pair</source> -<target>Filtro: Apenas um par</target> +<source>Filter</source> +<target>Filtro</target> <source>Direct</source> <target>Direcionar</target> @@ -1146,8 +1137,8 @@ Excluir: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- Correspondente do outro lado a %dir</target> -<source>Restore all hidden dialogs?</source> -<target>Restaurar todos os diálogos ocultados?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>Fazer com que os diálogos ocultados e mensagens de alerta fiquem visíveis novamente?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1278,9 +1269,6 @@ Excluir: \stuff\temp\* <source>Error copying file:</source> <target>Erro ao copiar arquivo:</target> -<source>Error opening file:</source> -<target>Erro ao abrir arquivo:</target> - <source>Error traversing directory:</source> <target>Erro ao percorrer diretório:</target> @@ -1323,8 +1311,8 @@ Excluir: \stuff\temp\* <source>Preparing synchronization...</source> <target>Preparando sincronização...</target> -<source>Memory allocation failed!</source> -<target>Alocação de memória falhou!</target> +<source>Out of memory!</source> +<target>Falta de memória!</target> <source>File %x has an invalid date!</source> <target>Arquivo %x tem uma data inválida!</target> @@ -1479,11 +1467,11 @@ Excluir: \stuff\temp\* <source>Generating database...</source> <target>Gerando banco de dados...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>Nada para sincronizar de acordo com a configuração!</target> +<source>Nothing to synchronize!</source> +<target>Nada para sincronizar!</target> -<source>Error copying locked file %x!</source> -<target>Erro ao copiar arquivo bloqueado %x!</target> +<source>Unable to copy locked file %x!</source> +<target>Não foi possível copiar o arquivo bloqueado %x!</target> <source>Data verification error: Source and target file have different content!</source> <target>Erro de verificação de dados: Arquivo de origem e destino têm o mesmo conteúdo!</target> diff --git a/BUILD/Languages/romanian.lng b/BUILD/Languages/romanian.lng index 8f2cb480..e249df6d 100644 --- a/BUILD/Languages/romanian.lng +++ b/BUILD/Languages/romanian.lng @@ -11,7 +11,7 @@ <target>Caut dosarul %x...</target> <source>Show in Explorer</source> -<target>Arată în Explorator</target> +<target>Arată în Exploratorul de File</target> <source>Open with default application</source> <target>Deschide cu Aplicația Implicită</target> @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Configurează Filtrul</target> -<source>Customize columns</source> -<target>Bifează coloanele de afișat</target> - <source>Global settings</source> <target>Setări Globale</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Explorează</target> -<source>Error reading from synchronization database:</source> -<target>Eroare la citirea din baza de date a sincronizării:</target> - -<source>Error writing to synchronization database:</source> -<target>Eroare la scrierea în baza de date a sincronizării:</target> - <source>Invalid command line: %x</source> <target>Linie de comandă nevalidă: %x</target> +<source>Info</source> +<target>Informații</target> + +<source>Fatal Error</source> +<target>Eroare Fatală</target> + <source>Windows Error Code %x:</source> <target>Codul Erorii Windows %x:</target> @@ -140,15 +137,21 @@ <pluralform>%x de Baiți</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Eroare la citirea din baza de date a sincronizării:</target> + +<source>Error writing to synchronization database:</source> +<target>Eroare la scrierea în baza de date a sincronizării:</target> + +<source>Incompatible synchronization database format:</source> +<target>Format al bazei de date necompatibil cu versiunea softului:</target> + <source>Initial synchronization:</source> <target>Sincronizare inițială:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>Una dintre părți nu are o filă de tip bază de date FreeFileSync:</target> -<source>Incompatible synchronization database format:</source> -<target>Format al bazei de date necompatibil cu versiunea softului:</target> - <source>Database files do not share a common synchronization session:</source> <target>Filele bază de date nu partajează o sesiune comună de sincronizare</target> @@ -174,12 +177,6 @@ <pluralform>%x de sec</pluralform> </target> -<source>Info</source> -<target>Informații</target> - -<source>Fatal Error</source> -<target>Eroare Fatală</target> - <source>Error reading file:</source> <target>Eroare la citirea filei:</target> @@ -205,11 +202,14 @@ <source>Error parsing configuration file:</source> <target>Eroare la parsarea filei de configurare:</target> -<source>Error moving to Recycle Bin:</source> -<target>Eroare la mutarea în Reciclator:</target> +<source>Configuration loaded partially only:</source> +<target>Configuraţie doar parțial deschisă</target> + +<source>Unable to move %x to the Recycle Bin!</source> +<target>Nu pot muta %x în Reciclator!</target> -<source>Could not load a required DLL:</source> -<target>Nu pot deschide o filă DLL necesară:</target> +<source>Cannot load file %x.</source> +<target>Nu pot deschide fila %x.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>Eroare la accesarea Serviciului de Conservare a Volumelor [Volume Shadow Copy]!</target> @@ -217,10 +217,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>Realizarea de conservări (copii de rezervă) prin sistemul WOW64 nu este suportată. Folosește versiunea pe 64-biți a FreeFileSync.</target> -<source>Could not determine volume name for file:</source> +<source>Cannot determine volume name for file:</source> <target>Nu pot determina numele volumului pentru fila:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>Numele volumului %x nu face parte din numele filei %y !</target> <source>/sec</source> @@ -229,8 +229,8 @@ <source>File does not exist:</source> <target>Fila nu există:</target> -<source>Could not read values for the following XML nodes:</source> -<target>Nu pot citi valorile pentru următoarele noduri XML:</target> +<source>Cannot read the following XML elements:</source> +<target>Nu pot citi următoarele elemente XML:</target> <source>S&ave configuration...</source> <target>S&alvează Configurația...</target> @@ -433,7 +433,7 @@ Linia de comandă este executată de fiecare dată cînd: <target>Rezultatul Comparării</target> <source>Drag && drop</source> -<target>Trage și pune un dosar în cîmpul de mai jos sau folosește butonul de explorare</target> +<target>Trage și pune un dosar mai jos sau explorează către el</target> <source>Close progress dialog</source> <target>Închide Fereastra cu Progresul Sincronizării</target> @@ -456,9 +456,6 @@ Linia de comandă este executată de fiecare dată cînd: <source>2. &Synchronize...</source> <target>2. &Sincronizează...</target> -<source>S&witch view</source> -<target>Schimbă &Vederea</target> - <source>&New</source> <target>Configurație &Nouă</target> @@ -546,17 +543,17 @@ Linia de comandă este executată de fiecare dată cînd: <source>Speed:</source> <target>Viteză:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Timp Rămas:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Timp Scurs:</target> <source>Batch job</source> <target>Sarcină Set</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Crearea unei file set [batch file] pentru sincronizarea inteligentă (automatizată). Pentru a porni în modul set de comenzi, trebuie dublu-clicată fila sau executată prin linia de comandă următoare: FreeFileSync.exe <ffs_batch file>. Operația poate fi de asemenea planificată cu ajutorul Planificatorului de Sarcini [Task Scheduler] din sistemul de operare.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>Creează o filă set [batch] și automatizează sincronizarea. Pentru a porni în modul set dublu-clichează această filă sau rulează comanda: FreeFileSync.exe SyncJob.ffs_batch. Operația poate fi de asemenea planificată folosind planificatorul de sarcini al sistemului.</target> <source>Help</source> <target>Ajutor</target> @@ -570,9 +567,6 @@ Linia de comandă este executată de fiecare dată cînd: <source>Right</source> <target>Dreapta</target> -<source>Overview</source> -<target>Panoramă</target> - <source>Status feedback</source> <target>Afișarea Stării</target> @@ -717,8 +711,8 @@ este același <source>Published under the GNU General Public License</source> <target>Publicat sub licența GNU GPL</target> -<source>Ignore subsequent errors</source> -<target>Ignoră (nu lua în seamă) erorile ulterioare</target> +<source>Ignore further errors</source> +<target>Ignoră erorile ulterioare</target> <source>Hide further error messages during the current process</source> <target>Ascunde mesajele de eroare apărute ulterior în timpul acestui proces</target> @@ -741,22 +735,22 @@ este același <source>&No</source> <target>&Nu</target> +<source>Use Recycle Bin</source> +<target>Mutare în Reciclator</target> + <source>Delete on both sides</source> <target>Șterge din ambele părți</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Șterge din ambele părți, chiar dacă fila e selecționată într-o singură parte</target> -<source>Use Recycle Bin</source> -<target>Mutare în Reciclator</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Doar filele/folderele care îndeplinesc toate condițiile filtrului vor fi selectate pentru sincronizare. -Notă: Filtrul de nume este pus în relație cu calea dosarelor principale sincronizate (elementele filtrate au specificată o cale relativă). +Doar filele care se potrivesc cu toate setările de filtrare vor fi sincronizate. +Notă: Numele filelor trebuie să fie relative la dosarele bază (rădăcină)! </target> <source>Hints:</source> @@ -792,20 +786,20 @@ Excluse: \stuff\temp\* <source>Exclude</source> <target>Excluse</target> -<source>Minimum file size</source> -<target>Mărimea minimă a filei</target> +<source>Time span</source> +<target>Intervalul de Timp</target> -<source>Maximum file size</source> -<target>Mărimea maximă a filei</target> +<source>File size</source> +<target>Mărimea Filei</target> -<source>&Default</source> -<target>Coloanele &Implicite</target> +<source>Minimum</source> +<target>Minim</target> -<source>Move column up</source> -<target>Mută coloana în sus</target> +<source>Maximum</source> +<target>Maxim</target> -<source>Move column down</source> -<target>Mută coloana în jos</target> +<source>&Default</source> +<target>Coloanele &Implicite</target> <source>Transactional file copy</source> <target>Copiază filele în mod tranzacțional</target> @@ -825,14 +819,8 @@ Excluse: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Permisiunile filelor și dosarelor sînt și ele transferate (necesită drepturi de Administrator)</target> -<source>Hidden dialogs:</source> -<target>Casete de dialog ascunse:</target> - -<source>Reset</source> -<target>Resetează</target> - -<source>Show hidden dialogs</source> -<target>Arată casetele de dialog ascunse</target> +<source>Restore hidden dialogs</source> +<target>Restaurează Dialogurile Ascunse</target> <source>External applications</source> <target>Aplicații Externe</target> @@ -864,8 +852,8 @@ Excluse: \stuff\temp\* <source>Folder pairs</source> <target>Perechi de Dosare</target> -<source>Compressed view</source> -<target>Vedere Comprimată</target> +<source>Overview</source> +<target>Panoramă</target> <source>Select view</source> <target>Selectează Vederea</target> @@ -894,17 +882,17 @@ Excluse: \stuff\temp\* <source>Exclude all</source> <target>Exclude Tot</target> -<source>Icon size:</source> -<target>Mărimea Icoanelor Elementelor:</target> +<source>Show icons:</source> +<target>Arată Icoane:</target> <source>Small</source> -<target>Mică</target> +<target>Mici</target> <source>Medium</source> -<target>Medie</target> +<target>Medii</target> <source>Large</source> -<target>Mare</target> +<target>Mari</target> <source>Select time span...</source> <target>Selectează intervalul de timp...</target> @@ -921,6 +909,9 @@ Excluse: \stuff\temp\* <source>Configuration saved!</source> <target>Configurație salvată !</target> +<source>Never save changes</source> +<target>Nu salva niciodată modificările</target> + <source>Save changes to current configuration?</source> <target>Vrei să salvezi modificările configurației curente?</target> @@ -1032,9 +1023,6 @@ Excluse: \stuff\temp\* <source>Error writing file:</source> <target>Eroare la scrierea filei:</target> -<source>Batch file created successfully!</source> -<target>Fila cu setul de comenzi a fost creată cu succces !</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1109,13 +1097,16 @@ Excluse: \stuff\temp\* <target>Azi</target> <source>This week</source> -<target>Săptămîna Asta</target> +<target>Săptămîna asta</target> <source>This month</source> -<target>Luna Asta</target> +<target>Luna asta</target> <source>This year</source> -<target>Anul Ăsta</target> +<target>Anul ăsta</target> + +<source>Last x days</source> +<target>Ultimele x zile</target> <source>Byte</source> <target>Baiți</target> @@ -1126,11 +1117,8 @@ Excluse: \stuff\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>Filtru: Toate perechile</target> - -<source>Filter: Single pair</source> -<target>Filtru: O singură pereche</target> +<source>Filter</source> +<target>Filtrează</target> <source>Direct</source> <target>Direcționează</target> @@ -1156,8 +1144,8 @@ Excluse: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- corespondentul din partea opusă al lui %dir</target> -<source>Restore all hidden dialogs?</source> -<target>Restaurezi toate casetele de dialog ascunse?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>Vrei ca dialogurile ascunse și mesajele de avertizare să fie vizibile din nou?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1293,9 +1281,6 @@ Excluse: \stuff\temp\* <source>Error copying file:</source> <target>Eroare la copierea filei:</target> -<source>Error opening file:</source> -<target>Eroare la deschiderea filei:</target> - <source>Error traversing directory:</source> <target>Eroare la parcurgerea dosarului:</target> @@ -1338,8 +1323,8 @@ Excluse: \stuff\temp\* <source>Preparing synchronization...</source> <target>Pregătesc sincronizarea...</target> -<source>Memory allocation failed!</source> -<target>Alocarea memoriei a eșuat!</target> +<source>Out of memory!</source> +<target>Memorie epuizată!</target> <source>File %x has an invalid date!</source> <target>Fila %x are o dată nevalidă !</target> @@ -1494,11 +1479,11 @@ Excluse: \stuff\temp\* <source>Generating database...</source> <target>Generez baza de date...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>Nu este nimic de sincronizat conform configurației!</target> +<source>Nothing to synchronize!</source> +<target>Nu e nimic de sincronizat!</target> -<source>Error copying locked file %x!</source> -<target>Eroare la copierea filei zăvorîte %x!</target> +<source>Unable to copy locked file %x!</source> +<target>Nu pot copia fila zăvorîtă %x</target> <source>Data verification error: Source and target file have different content!</source> <target>Eroare la verificarea datelor: Filele sursă și țintă au conținut diferit!</target> diff --git a/BUILD/Languages/russian.lng b/BUILD/Languages/russian.lng index 1440942c..01f4eded 100644 --- a/BUILD/Languages/russian.lng +++ b/BUILD/Languages/russian.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Настройки фильтра</target> -<source>Customize columns</source> -<target>Выбор колонок</target> - <source>Global settings</source> <target>Глобальные настройки</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Обзор</target> -<source>Error reading from synchronization database:</source> -<target>Ошибка при чтении из базы данных синхронизации:</target> - -<source>Error writing to synchronization database:</source> -<target>Ошибка при записи в базу данных синхронизации:</target> - <source>Invalid command line: %x</source> <target>Неверная командная строка: %x</target> +<source>Info</source> +<target>Информация</target> + +<source>Fatal Error</source> +<target>Критическая ошибка</target> + <source>Windows Error Code %x:</source> <target>Код ошибки Windows %x:</target> @@ -140,15 +137,21 @@ <pluralform>%x Байт</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Ошибка при чтении из базы данных синхронизации:</target> + +<source>Error writing to synchronization database:</source> +<target>Ошибка при записи в базу данных синхронизации:</target> + +<source>Incompatible synchronization database format:</source> +<target>Несовместимый формат базы данных синхронизации:</target> + <source>Initial synchronization:</source> <target>Первоначальная синхронизация:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>Одного из файлов баз данных FreeFileSync еще не существует:</target> -<source>Incompatible synchronization database format:</source> -<target>Несовместимый формат базы данных синхронизации:</target> - <source>Database files do not share a common synchronization session:</source> <target>Файлы баз данных не имеют общей сессии синхронизации:</target> @@ -174,12 +177,6 @@ <pluralform>%x секунд</pluralform> </target> -<source>Info</source> -<target>Информация</target> - -<source>Fatal Error</source> -<target>Критическая ошибка</target> - <source>Error reading file:</source> <target>Ошибка при чтении файла:</target> @@ -205,11 +202,14 @@ <source>Error parsing configuration file:</source> <target>Ошибка при анализе файла настроек синхронизации:</target> -<source>Error moving to Recycle Bin:</source> -<target>Ошибка при перемещении в "Корзину":</target> +<source>Configuration loaded partially only:</source> +<target>Конфигурация загрузилась частично:</target> -<source>Could not load a required DLL:</source> -<target>Не удалось загрузить необходимые DLL:</target> +<source>Unable to move %x to the Recycle Bin!</source> +<target>Невозможно переместить %x в "Корзину"!</target> + +<source>Cannot load file %x.</source> +<target>Не удается загрузить файл %x.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>Ошибка доступа к службе Теневого Копирования Тома!</target> @@ -217,10 +217,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>Создание теневых копий на WOW64 не поддерживается. Пожалуйста, используйте FreeFileSync 64-разрядной версии.</target> -<source>Could not determine volume name for file:</source> -<target>Не удалось определить название тома для файла:</target> +<source>Cannot determine volume name for file:</source> +<target>Невозможно определить имя тома для файла:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>Имя тома %x не является частью имени файла %y!</target> <source>/sec</source> @@ -229,8 +229,8 @@ <source>File does not exist:</source> <target>Файл не существует:</target> -<source>Could not read values for the following XML nodes:</source> -<target>Не удалось прочитать значения для следующих XML записей:</target> +<source>Cannot read the following XML elements:</source> +<target>Невозможно прочитать следующие XML элементы:</target> <source>S&ave configuration...</source> <target>Сохранить настройки синхронизации...</target> @@ -546,23 +546,23 @@ The command line is executed each time: <source>Speed:</source> <target>Скорость:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Времени осталось:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Времени прошло:</target> <source>Batch job</source> <target>Пакетное задание</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Создайте файл пакетного задания для автоматической синхронизации. Для запуска в пакетном режиме просто дважды щелкните по файлу или выполните командную строку: FreeFileSync.exe <ffs_batch file>. Также запуск можно запланировать в планировщике задач операционной системы.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>Создайте файл пакетного задания для автоматической синхронизации. Для запуска в пакетном режиме просто дважды щелкните по файлу или выполните командную строку: FreeFileSync.exe SyncJob.ffs_batch. Также запуск можно запланировать в планировщике задач операционной системы.</target> <source>Help</source> <target>Помощь</target> <source>Filter files</source> -<target>Фильтр файлов</target> +<target>Фильтр</target> <source>Left</source> <target>Слева</target> @@ -570,9 +570,6 @@ The command line is executed each time: <source>Right</source> <target>Справа</target> -<source>Overview</source> -<target>Главная</target> - <source>Status feedback</source> <target>Статус обратной связи</target> @@ -712,7 +709,7 @@ is the same <source>Published under the GNU General Public License</source> <target>Издается под лицензией GNU General Public License</target> -<source>Ignore subsequent errors</source> +<source>Ignore further errors</source> <target>Игнорировать последующие ошибки</target> <source>Hide further error messages during the current process</source> @@ -736,22 +733,22 @@ is the same <source>&No</source> <target>&Нет</target> +<source>Use Recycle Bin</source> +<target>Использовать "Корзину"</target> + <source>Delete on both sides</source> <target>Удалить с обеих сторон</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Удалить с обеих сторон, если даже файл выделен только на одной стороне</target> -<source>Use Recycle Bin</source> -<target>Использовать "Корзину"</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Только файлы/папки, соответствующие всем настройкам фильтра, будут выбраны для синхронизации. -Примечание: Фильтр имен должен быть задан относительно основных папок синхронизации. +Только файлы, соответствующие всем настройкам фильтра, будут синхронизированы. +Примечание: Файлы должны относиться к синхронизируемым папкам! </target> <source>Hints:</source> @@ -787,20 +784,20 @@ Exclude: \stuff\temp\* <source>Exclude</source> <target>Исключить</target> -<source>Minimum file size</source> -<target>Минимальный размер файла</target> +<source>Time span</source> +<target>Промежуток времени</target> -<source>Maximum file size</source> -<target>Максимальный размер файла</target> +<source>File size</source> +<target>Размер файла</target> -<source>&Default</source> -<target>&По-умолчанию</target> +<source>Minimum</source> +<target>минимум</target> -<source>Move column up</source> -<target>Переместить вверх</target> +<source>Maximum</source> +<target>максимум</target> -<source>Move column down</source> -<target>Переместить вниз</target> +<source>&Default</source> +<target>&По-умолчанию</target> <source>Transactional file copy</source> <target>Безопасное копирование файлов</target> @@ -820,14 +817,8 @@ Exclude: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Передача прав доступа к файлам/папкам (требуются права Администратора)</target> -<source>Hidden dialogs:</source> -<target>Скрытые диалоги</target> - -<source>Reset</source> -<target>Сбросить</target> - -<source>Show hidden dialogs</source> -<target>Показать скрытые диалоги</target> +<source>Restore hidden dialogs</source> +<target>Восстановить скрытые диалоговые окна?</target> <source>External applications</source> <target>Внешние приложения</target> @@ -859,8 +850,8 @@ Exclude: \stuff\temp\* <source>Folder pairs</source> <target>Пары папок для синхронизации</target> -<source>Compressed view</source> -<target>Компактный вид</target> +<source>Overview</source> +<target>Главная</target> <source>Select view</source> <target>Вид списка файлов</target> @@ -889,17 +880,17 @@ Exclude: \stuff\temp\* <source>Exclude all</source> <target>Исключить все</target> -<source>Icon size:</source> -<target>Размер иконок:</target> +<source>Show icons:</source> +<target>Отображать иконки:</target> <source>Small</source> -<target>- маленький</target> +<target>- маленькие</target> <source>Medium</source> -<target>- средний</target> +<target>- средние</target> <source>Large</source> -<target>- большой</target> +<target>- большие</target> <source>Select time span...</source> <target>Выберите промежуток времени...</target> @@ -916,6 +907,9 @@ Exclude: \stuff\temp\* <source>Configuration saved!</source> <target>Настройки синхронизации сохранены!</target> +<source>Never save changes</source> +<target>Никогда не сохранять изменения</target> + <source>Save changes to current configuration?</source> <target>Сохранить изменения в текущих настройках синхронизации?</target> @@ -1027,9 +1021,6 @@ Exclude: \stuff\temp\* <source>Error writing file:</source> <target>Ошибка при записи файла:</target> -<source>Batch file created successfully!</source> -<target>Файл пакетного задания создан успешно!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1112,6 +1103,9 @@ Exclude: \stuff\temp\* <source>This year</source> <target>в этом году</target> +<source>Last x days</source> +<target>последние х дня(ей)</target> + <source>Byte</source> <target>Байт</target> @@ -1121,11 +1115,8 @@ Exclude: \stuff\temp\* <source>MB</source> <target>МБ</target> -<source>Filter: All pairs</source> -<target>Фильтр: Все пары</target> - -<source>Filter: Single pair</source> -<target>Фильтр: Одна пара</target> +<source>Filter</source> +<target>Фильтр</target> <source>Direct</source> <target>Прямое</target> @@ -1154,8 +1145,8 @@ Exclude: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- аналогичная папка с другой стороны</target> -<source>Restore all hidden dialogs?</source> -<target>Отображать все скрытые диалоговые окна?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>Сделать скрытые диалоги и предупреждения видимыми вновь?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1291,9 +1282,6 @@ Exclude: \stuff\temp\* <source>Error copying file:</source> <target>Ошибка при копировании файла:</target> -<source>Error opening file:</source> -<target>Ошибка при открытии файла:</target> - <source>Error traversing directory:</source> <target>Ошибка при пересечении папок:</target> @@ -1339,8 +1327,8 @@ Exclude: \stuff\temp\* <source>Preparing synchronization...</source> <target>Подготовка к синхронизации...</target> -<source>Memory allocation failed!</source> -<target>Ошибка выделения памяти! (Не хватает памяти)</target> +<source>Out of memory!</source> +<target>Недостаточно памяти!</target> <source>File %x has an invalid date!</source> <target>Файл %x имеет недействительную дату!</target> @@ -1495,11 +1483,11 @@ Exclude: \stuff\temp\* <source>Generating database...</source> <target>Создание базы данных...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>Ничего нет для синхронизации в соответствии с настройками синхронизации!</target> +<source>Nothing to synchronize!</source> +<target>Ничего нет для синхронизации!</target> -<source>Error copying locked file %x!</source> -<target>Ошибка при копировании заблокированного файла %x!</target> +<source>Unable to copy locked file %x!</source> +<target>Невозможно скопировать заблокированный файл %x!</target> <source>Data verification error: Source and target file have different content!</source> <target>Ошибка проверки данных: исходный и конечный файлы имеют разное содержание!</target> diff --git a/BUILD/Languages/slovenian.lng b/BUILD/Languages/slovenian.lng index 567a5ed2..3a7cf10b 100644 --- a/BUILD/Languages/slovenian.lng +++ b/BUILD/Languages/slovenian.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Konfiguriraj filter</target> -<source>Customize columns</source> -<target>Stolpce prikroji po meri</target> - <source>Global settings</source> <target>Globalne nastavitve</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Brskaj</target> -<source>Error reading from synchronization database:</source> -<target>Napaka pri branju iz sinhronizacijske podatkovne baze:</target> - -<source>Error writing to synchronization database:</source> -<target>Napaka pri pisanju v sinhronizacijsko podatkovno bazo:</target> - <source>Invalid command line: %x</source> <target>Napačna ukazna vrstica: %x</target> +<source>Info</source> +<target>Info</target> + +<source>Fatal Error</source> +<target>Usodna napaka</target> + <source>Windows Error Code %x:</source> <target>Windows koda napake %x:</target> @@ -141,15 +138,21 @@ <pluralform>%x Bajtov</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Napaka pri branju iz sinhronizacijske podatkovne baze:</target> + +<source>Error writing to synchronization database:</source> +<target>Napaka pri pisanju v sinhronizacijsko podatkovno bazo:</target> + +<source>Incompatible synchronization database format:</source> +<target>Nekompatibilen format sinhronizacijske podatkovne baze:</target> + <source>Initial synchronization:</source> <target>Začetna sinhronizacija:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>Ena od FreeFileSync datotek podatkovne baze še en obstaja:</target> -<source>Incompatible synchronization database format:</source> -<target>Nekompatibilen format sinhronizacijske podatkovne baze:</target> - <source>Database files do not share a common synchronization session:</source> <target>Datoteke podatkovne baze si ne delijo skupne sinhronizacijske seje:</target> @@ -176,12 +179,6 @@ <pluralform>%x sek</pluralform> </target> -<source>Info</source> -<target>Info</target> - -<source>Fatal Error</source> -<target>Usodna napaka</target> - <source>Error reading file:</source> <target>Napaka pri branju datoteke:</target> @@ -208,11 +205,14 @@ <source>Error parsing configuration file:</source> <target>Napaka pri preverjanju konfiguracijske datoteke:</target> -<source>Error moving to Recycle Bin:</source> -<target>Napaka pri premikanju v Koš:</target> +<source>Configuration loaded partially only:</source> +<target>Nastavitev naložena samo delno:</target> -<source>Could not load a required DLL:</source> -<target>Ne morem naložiti zahtevano DLL:</target> +<source>Unable to move %x to the Recycle Bin!</source> +<target>Ne morem premakniti %x v Koš</target> + +<source>Cannot load file %x.</source> +<target>Ne morem naložiti datoteko %x.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>Napaka pri dostopu do servisa senčnih kopij!</target> @@ -220,10 +220,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>Ustvarjanje senčnih kopij na WOW63 ni podprto. Prosimo uporabite 64-bitno FreeFileSync različico.</target> -<source>Could not determine volume name for file:</source> +<source>Cannot determine volume name for file:</source> <target>Ne morem določiti imena volumna za datoteko:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>Ime volumna %x ni del imena datoteke %y!</target> <source>/sec</source> @@ -232,8 +232,8 @@ <source>File does not exist:</source> <target>Datoteka ne obstaja:</target> -<source>Could not read values for the following XML nodes:</source> -<target>Ne morem brati vrednosti za naslednja XML vozlišča:</target> +<source>Cannot read the following XML elements:</source> +<target>Ne morem brati naslednje XML elemente:</target> <source>S&ave configuration...</source> <target>Shr&ani konfiguracijo...</target> @@ -546,17 +546,17 @@ Ukazna vrstica se izvrši vsakič ko: <source>Speed:</source> <target>Hitrost:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Preostali čas:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Pretečen čas:</target> <source>Batch job</source> <target>Paketno opravilo</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Ustvarite paketno datoteko za avtomatizirano sinhronizacijo. Da začnete v paketnem načinu preprosto dvokliknite datoteko ali izvršite ukaz preko ukazne vrstice: FreeFileSync.exe <ffs_paketna datoteka>. To se lahko nastavi tudi v urniku opravil vašega operacijskega sistema.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>Ustvari paketno datoteko in avtomatiziraj sinhronizacijo. Da začnete v paketnem načinu preprosto dvokliknite to datoteko ali poženite ukaz: FreeFileSync.exe SyncJob.ffs_batch. To se lahko nastavi v vaš sistemski načrtovalec opravil.</target> <source>Help</source> <target>Pomoč</target> @@ -570,9 +570,6 @@ Ukazna vrstica se izvrši vsakič ko: <source>Right</source> <target>Desno</target> -<source>Overview</source> -<target>Pregled</target> - <source>Status feedback</source> <target>Povratne informacije statusa</target> @@ -717,8 +714,8 @@ enaka <source>Published under the GNU General Public License</source> <target>Objavljeno pod licenco GNU General Public</target> -<source>Ignore subsequent errors</source> -<target>Ignoriraj vse nadaljnje napake</target> +<source>Ignore further errors</source> +<target>Ignoriraj nadaljnje napake</target> <source>Hide further error messages during the current process</source> <target>Skrijte nadaljnja obvestila o napakah med trenutnim procesom</target> @@ -741,22 +738,22 @@ enaka <source>&No</source> <target>&Ne</target> +<source>Use Recycle Bin</source> +<target>Uporabi Koš</target> + <source>Delete on both sides</source> <target>Izbriši na obeh straneh</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Izbriši na obeh straneh, četudi je datoteka izbrana na samo eni strani</target> -<source>Use Recycle Bin</source> -<target>Uporabi Koš</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Samo datoteke/imeniki, ki ustrezajo vsem nastavitvam filtra bodo izbrani za sinhronizacjo. -Opomba: Ime filtra mora biti določeno relativno(!) glede na glavne sinhronizacijske imenike. +Samo datoteke, ki ustrezajo vsem nastavitvam filtra bodo sinhronizirane. +Opomba: Imena datoteka morajo biti relativna osnovnim imenikom! </target> <source>Hints:</source> @@ -792,20 +789,20 @@ Izključi: \stuff\temp\* <source>Exclude</source> <target>Izključi</target> -<source>Minimum file size</source> -<target>Minimalna velikost datoteke</target> +<source>Time span</source> +<target>Časovno obdobje</target> -<source>Maximum file size</source> -<target>Maksimalna velikost datoteke</target> +<source>File size</source> +<target>Velikost datoteke</target> -<source>&Default</source> -<target>&Privzeto</target> +<source>Minimum</source> +<target>Minimum</target> -<source>Move column up</source> -<target>Premakni stolpec gor</target> +<source>Maximum</source> +<target>Maksimum</target> -<source>Move column down</source> -<target>Premakni stolpec dol</target> +<source>&Default</source> +<target>&Privzeto</target> <source>Transactional file copy</source> <target>Transakcijsko kopiranje datotek</target> @@ -825,14 +822,8 @@ Izključi: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Prenesi dovoljenja datotek in imenikov (Zahteva pravice skrbnika)</target> -<source>Hidden dialogs:</source> -<target>Skriti pogovori:</target> - -<source>Reset</source> -<target>Ponastavi</target> - -<source>Show hidden dialogs</source> -<target>Prikaži skrite pogovore</target> +<source>Restore hidden dialogs</source> +<target>Obnovi skrite pogovore</target> <source>External applications</source> <target>Zunanje aplikacije</target> @@ -864,8 +855,8 @@ Izključi: \stuff\temp\* <source>Folder pairs</source> <target>Pari map</target> -<source>Compressed view</source> -<target>Stisnjeni pogled</target> +<source>Overview</source> +<target>Pregled</target> <source>Select view</source> <target>Izberite pogled</target> @@ -894,8 +885,8 @@ Izključi: \stuff\temp\* <source>Exclude all</source> <target>Izključi vse</target> -<source>Icon size:</source> -<target>Velikost ikone:</target> +<source>Show icons:</source> +<target>Prikaži ikone:</target> <source>Small</source> <target>Majhna</target> @@ -921,6 +912,9 @@ Izključi: \stuff\temp\* <source>Configuration saved!</source> <target>Konfiguracija shranjena!</target> +<source>Never save changes</source> +<target>Nikoli ne shrani sprememb</target> + <source>Save changes to current configuration?</source> <target>Shranim spremembe trenutne konfiguracije?</target> @@ -1032,9 +1026,6 @@ Izključi: \stuff\temp\* <source>Error writing file:</source> <target>Napaka pri pisanju datoteke:</target> -<source>Batch file created successfully!</source> -<target>Paketna datoteka je bila uspešno ustvarjena!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1121,6 +1112,9 @@ Izključi: \stuff\temp\* <source>This year</source> <target>To leto</target> +<source>Last x days</source> +<target>Zadnjih x dni</target> + <source>Byte</source> <target>Bajt</target> @@ -1130,11 +1124,8 @@ Izključi: \stuff\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>Filtriraj: Vse pare</target> - -<source>Filter: Single pair</source> -<target>Filtriraj: En sam par</target> +<source>Filter</source> +<target>Filter</target> <source>Direct</source> <target>Neposredno</target> @@ -1160,8 +1151,8 @@ Izključi: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- Duplikat z druge strani od %dir</target> -<source>Restore all hidden dialogs?</source> -<target>Obnovim vse skrite pogovore?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>Ponovno prikažem skrite pogovore in sporočila z opozorili?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1302,9 +1293,6 @@ Izključi: \stuff\temp\* <source>Error copying file:</source> <target>Napaka pri kopiranju datoteke:</target> -<source>Error opening file:</source> -<target>Napaka pri odpiranju datoteke:</target> - <source>Error traversing directory:</source> <target>Napaka pri prehajanju imenika:</target> @@ -1347,8 +1335,8 @@ Izključi: \stuff\temp\* <source>Preparing synchronization...</source> <target>Pripravljam sinhronizacijo...</target> -<source>Memory allocation failed!</source> -<target>Neuspešno dodeljevanje pomnilnika!</target> +<source>Out of memory!</source> +<target>Zmanjkalo pomnilnika!</target> <source>File %x has an invalid date!</source> <target>Datoteka %x ima neveljaven datum!</target> @@ -1503,11 +1491,11 @@ Izključi: \stuff\temp\* <source>Generating database...</source> <target>Ustvarjam podatkovno bazo...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>Po trenutni konfiguraciji ni nič za sinhronizirati!</target> +<source>Nothing to synchronize!</source> +<target>Nič za sinhronizirati!</target> -<source>Error copying locked file %x!</source> -<target>Napaka pri kopiranju zaklenjene datoteke %x!</target> +<source>Unable to copy locked file %x!</source> +<target>Ne morem kopirati zaklenjeno datoteko %x!</target> <source>Data verification error: Source and target file have different content!</source> <target>Napaka pri preverjanju podatkov: izvorna in ciljna datoteka imata različno vsebino!</target> diff --git a/BUILD/Languages/spanish.lng b/BUILD/Languages/spanish.lng index 84d5434e..0dfb54d0 100644 --- a/BUILD/Languages/spanish.lng +++ b/BUILD/Languages/spanish.lng @@ -41,7 +41,7 @@ <target>Limpiar opciones del filtrado</target> <source>Create a batch job</source> -<target>Crear una tarea batch</target> +<target>Crear una tarea por lotes</target> <source>Synchronization settings</source> <target>Opciones de sincronización</target> @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Configurar filtro</target> -<source>Customize columns</source> -<target>Personalizar columnas</target> - <source>Global settings</source> <target>Opciones globales</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Examinar</target> -<source>Error reading from synchronization database:</source> -<target>Error al leer de la base de datos de sincronización:</target> - -<source>Error writing to synchronization database:</source> -<target>Error al escribir en la base de datos de sincronización:</target> - <source>Invalid command line: %x</source> <target>Línea de comandos errónea: %x</target> +<source>Info</source> +<target>Info</target> + +<source>Fatal Error</source> +<target>Error fatal</target> + <source>Windows Error Code %x:</source> <target>Código de error de Windows %x:</target> @@ -139,15 +136,21 @@ <pluralform>%x Bytes</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Error al leer de la base de datos de sincronización:</target> + +<source>Error writing to synchronization database:</source> +<target>Error al escribir en la base de datos de sincronización:</target> + +<source>Incompatible synchronization database format:</source> +<target>Formato de base de datos de sincronización incompatible:</target> + <source>Initial synchronization:</source> <target>Sincronización inicial:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>Uno de los archivos de la base de datos de FreeFileSync aún no existe:</target> -<source>Incompatible synchronization database format:</source> -<target>Formato de base de datos de sincronización incompatible:</target> - <source>Database files do not share a common synchronization session:</source> <target>Archivos de base de datos no comparten la misma sesión de sincronización:</target> @@ -172,12 +175,6 @@ <pluralform>%x segundos</pluralform> </target> -<source>Info</source> -<target>Info</target> - -<source>Fatal Error</source> -<target>Error fatal</target> - <source>Error reading file:</source> <target>Error al leer archivo:</target> @@ -202,11 +199,14 @@ <source>Error parsing configuration file:</source> <target>Error al analizar el archivo de configuración:</target> -<source>Error moving to Recycle Bin:</source> -<target>Error al mover a la Papelera de Reciclaje:</target> +<source>Configuration loaded partially only:</source> +<target>Configuración cargada sólo parcialmente:</target> -<source>Could not load a required DLL:</source> -<target>No se ha podido cargar el DLL solicitado:</target> +<source>Unable to move %x to the Recycle Bin!</source> +<target>¡Incapaz de mover %x a la Papelera de reciclaje!</target> + +<source>Cannot load file %x.</source> +<target>No se ha podido cargar el archivo %x.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>¡Error al acceder al servicio Volume Shadow Copy!</target> @@ -214,10 +214,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>La realización de copias shadow en WOW64 no está soportado. Por favor, use la versión 64-bit de FreeFileSync.</target> -<source>Could not determine volume name for file:</source> -<target>No se ha podido determinar el nombre del volumen para el archivo:</target> +<source>Cannot determine volume name for file:</source> +<target>Incapaz de determinar nombre de volumen para el archivo:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>El nombre del volumen %x no es una parte del nombre de archivo %y</target> <source>/sec</source> @@ -226,8 +226,8 @@ <source>File does not exist:</source> <target>El archivo no existe:</target> -<source>Could not read values for the following XML nodes:</source> -<target>No se ha podido leer los valores para los siguientes nodos XML:</target> +<source>Cannot read the following XML elements:</source> +<target>Incapaz de leer los siguientes elementos XML:</target> <source>S&ave configuration...</source> <target>G&uardar configuración...</target> @@ -343,19 +343,19 @@ La línea de comandos se ejecuta cada vez: <target>Personalizado</target> <source>FreeFileSync batch file</source> -<target>Archivo batch de FreeFileSync</target> +<target>Archivo por lotes de FreeFileSync</target> <source>FreeFileSync configuration</source> <target>Configuración de FreeFileSync</target> <source>FreeFileSync Batch Job</source> -<target>Tarea batch de FreeFileSync</target> +<target>Tarea por lotes de FreeFileSync</target> <source>Unable to create log file!</source> <target>¡Incapaz de crear un archivo de registro!</target> <source>Batch execution</source> -<target>Ejecución batch</target> +<target>Ejecución por lotes</target> <source>Stop</source> <target>Detener</target> @@ -466,7 +466,7 @@ La línea de comandos se ejecuta cada vez: <target>&Opciones globales...</target> <source>&Create batch job...</source> -<target>&Crear tarea batch...</target> +<target>&Crear tarea por lotes...</target> <source>&Export file list...</source> <target>&Exportar lista de archivos...</target> @@ -540,17 +540,17 @@ La línea de comandos se ejecuta cada vez: <source>Speed:</source> <target>Velocidad:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Tiempo restante:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Tiempo transcurrido:</target> <source>Batch job</source> -<target>Tarea batch</target> +<target>Tarea por lotes</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Crear fichero batch para sincronización automática. Para empezar en modo batch, simplemente haga doble clic en el archivo o ejecútelo a través de la línea de comandos: FreeFileSync.exe <ffs_batch file>. Esto también puede programado por el planificador de tareas del sistema operativo.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>Crear un archivo por lotes y automatizar la sincronización. Para empezar en modo por lotes, hacer doble clic en el archivo o ejecutar el comando: FreeFileSync.exe SyncJob.ffs_batch. Esto también puede ser programado en el planificador de tareas del sistema.</target> <source>Help</source> <target>Ayuda</target> @@ -564,9 +564,6 @@ La línea de comandos se ejecuta cada vez: <source>Right</source> <target>Derecha</target> -<source>Overview</source> -<target>Visión global</target> - <source>Status feedback</source> <target>Status feedback</target> @@ -583,7 +580,7 @@ La línea de comandos se ejecuta cada vez: <target>Seleccione directorio para el archivo de registro:</target> <source>Batch settings</source> -<target>Opciones de batch</target> +<target>Opciones de lotes</target> <source>&Save</source> <target>&Guardar</target> @@ -711,8 +708,8 @@ es el mismo <source>Published under the GNU General Public License</source> <target>Publicado bajo "GNU General Public License"</target> -<source>Ignore subsequent errors</source> -<target>Ignorar errores posteriores</target> +<source>Ignore further errors</source> +<target>Ignorar más errores</target> <source>Hide further error messages during the current process</source> <target>Ocultar próximos mensajes de error durante el proceso actual</target> @@ -735,22 +732,22 @@ es el mismo <source>&No</source> <target>&No</target> +<source>Use Recycle Bin</source> +<target>Utilizar Papelera de Reciclaje</target> + <source>Delete on both sides</source> <target>Borrar en ambos lados</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Borrar en ambos lados incluso si el archivo está seleccionado en un solo lado</target> -<source>Use Recycle Bin</source> -<target>Utilizar Papelera de Reciclaje</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Sólo los archivos/directorios que cumplan con todos los filtros serán seleccionados para la sincronización. -Nota: El nombre del filtro debe ser especificado en relación(!) a los directorios principales de sincronización. +Sólo archivos en que coincidan todos los filtros serán sincronizados. +Aviso: ¡Los nombres de archivos deben ser relativos a los directorios base! </target> <source>Hints:</source> @@ -786,20 +783,20 @@ Excluir: \stuff\temp\* <source>Exclude</source> <target>Excluir</target> -<source>Minimum file size</source> -<target>Tamaño mínimo de archivo</target> +<source>Time span</source> +<target>Espacio de tiempo</target> -<source>Maximum file size</source> -<target>Taaño máximo de archivo</target> +<source>File size</source> +<target>Tamaño de archivo</target> -<source>&Default</source> -<target>&Configuración por defecto</target> +<source>Minimum</source> +<target>Mínimo</target> -<source>Move column up</source> -<target>Mover arriba la columna</target> +<source>Maximum</source> +<target>Máximo</target> -<source>Move column down</source> -<target>Mover abajo la columna</target> +<source>&Default</source> +<target>&Configuración por defecto</target> <source>Transactional file copy</source> <target>Copia de archivos transaccionales</target> @@ -819,14 +816,8 @@ Excluir: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Transferir permisos de archivo y directorio (Requiere derechos de administrador)</target> -<source>Hidden dialogs:</source> -<target>Diálogos ocultos:</target> - -<source>Reset</source> -<target>Reiniciar</target> - -<source>Show hidden dialogs</source> -<target>Mostrar diálogos ocultos</target> +<source>Restore hidden dialogs</source> +<target>Restaurar diálogos ocultos</target> <source>External applications</source> <target>Aplicaciones externas</target> @@ -858,8 +849,8 @@ Excluir: \stuff\temp\* <source>Folder pairs</source> <target>Pares de carpetas</target> -<source>Compressed view</source> -<target>Vista comprimida</target> +<source>Overview</source> +<target>Visión global</target> <source>Select view</source> <target>Seleccione vista</target> @@ -888,8 +879,8 @@ Excluir: \stuff\temp\* <source>Exclude all</source> <target>Excluir todo</target> -<source>Icon size:</source> -<target>Tamaño del icono:</target> +<source>Show icons:</source> +<target>Mostrar iconos:</target> <source>Small</source> <target>Pequeño</target> @@ -915,6 +906,9 @@ Excluir: \stuff\temp\* <source>Configuration saved!</source> <target>¡Configuración guardada!</target> +<source>Never save changes</source> +<target>Nunca guardar cambios</target> + <source>Save changes to current configuration?</source> <target>¿Guardar los cambios de la configuración actual?</target> @@ -1026,9 +1020,6 @@ Excluir: \stuff\temp\* <source>Error writing file:</source> <target>Error al escribir archivo:</target> -<source>Batch file created successfully!</source> -<target>¡El archivo batch ha sido creado correctamente!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1107,6 +1098,9 @@ Excluir: \stuff\temp\* <source>This year</source> <target>Este año</target> +<source>Last x days</source> +<target>Últimos x días</target> + <source>Byte</source> <target>Byte</target> @@ -1116,11 +1110,8 @@ Excluir: \stuff\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>Filtro: Todos los pares</target> - -<source>Filter: Single pair</source> -<target>Filtro: Sólo un par</target> +<source>Filter</source> +<target>Filtro</target> <source>Direct</source> <target>Enviar</target> @@ -1146,8 +1137,8 @@ Excluir: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- El otro lado equivale a %dir</target> -<source>Restore all hidden dialogs?</source> -<target>¿Restaurar diálogos ocultos?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>Hacer visibles diálogos y mensajes de advertencia?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1278,9 +1269,6 @@ Excluir: \stuff\temp\* <source>Error copying file:</source> <target>Error al copiar archivo:</target> -<source>Error opening file:</source> -<target>Error al abrir archivo:</target> - <source>Error traversing directory:</source> <target>Error al buscar en el directorio:</target> @@ -1323,8 +1311,8 @@ Excluir: \stuff\temp\* <source>Preparing synchronization...</source> <target>Preparando sincronización...</target> -<source>Memory allocation failed!</source> -<target>¡La asignación de memoria ha fallado!</target> +<source>Out of memory!</source> +<target>¡Sin memoria!</target> <source>File %x has an invalid date!</source> <target>¡El archivo %x tiene una fecha inválida!</target> @@ -1479,11 +1467,11 @@ Excluir: \stuff\temp\* <source>Generating database...</source> <target>Generando base de datos...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>¡Nada que sincronizar de acuerdo con la configuración!</target> +<source>Nothing to synchronize!</source> +<target>¡Nada que sincronizar!</target> -<source>Error copying locked file %x!</source> -<target>¡Error al copiar archivo bloqueado %x!</target> +<source>Unable to copy locked file %x!</source> +<target>¡Incapaz de copiar el archivo bloqueado %x!</target> <source>Data verification error: Source and target file have different content!</source> <target>Error de verificación de datos: ¡Los archivos de origen y destino tienen un contenido diferente!</target> diff --git a/BUILD/Languages/swedish.lng b/BUILD/Languages/swedish.lng index b6b133f4..1e59759d 100644 --- a/BUILD/Languages/swedish.lng +++ b/BUILD/Languages/swedish.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Filterinställningar</target> -<source>Customize columns</source> -<target>Anpassa kollumner</target> - <source>Global settings</source> <target>Allmäna inställningar</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Bläddra</target> -<source>Error reading from synchronization database:</source> -<target>Kan inte läsa från databasen:</target> - -<source>Error writing to synchronization database:</source> -<target>Kan inte skriva till databas:</target> - <source>Invalid command line: %x</source> <target>Ogiltig kommandorad: %x</target> +<source>Info</source> +<target>Info</target> + +<source>Fatal Error</source> +<target>Allvarligt fel</target> + <source>Windows Error Code %x:</source> <target>Windows Felkod %x:</target> @@ -139,15 +136,21 @@ <pluralform>%x Byte</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Kan inte läsa från databasen:</target> + +<source>Error writing to synchronization database:</source> +<target>Kan inte skriva till databas:</target> + +<source>Incompatible synchronization database format:</source> +<target>Inkompatibelt databasformat:</target> + <source>Initial synchronization:</source> <target>Initial synkronisering:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>En av FreeFileSyncs databasfiler saknas:</target> -<source>Incompatible synchronization database format:</source> -<target>Inkompatibelt databasformat:</target> - <source>Database files do not share a common synchronization session:</source> <target>Databasfiler delar inte en gemensam synkroniseringssession:</target> @@ -172,14 +175,8 @@ <pluralform>%x sek</pluralform> </target> -<source>Info</source> -<target>Info</target> - -<source>Fatal Error</source> -<target>Allvarligt fel</target> - <source>Error reading file:</source> -<target>Kan inte läsa fil:</target> +<target>Kan inte läsa filen:</target> <source>Scanning:</source> <target>Skannar:</target> @@ -202,11 +199,14 @@ <source>Error parsing configuration file:</source> <target>Kan inte läsa in konfigurationsfil:</target> -<source>Error moving to Recycle Bin:</source> -<target>Kan inte flytta till papperskorgen:</target> +<source>Configuration loaded partially only:</source> +<target>Konfigurationsfilen endast delvis inläst</target> -<source>Could not load a required DLL:</source> -<target>Kan inte läsa in nödvändig DLL:</target> +<source>Unable to move %x to the Recycle Bin!</source> +<target>Kan inte flytta %x till Papperskorgen</target> + +<source>Cannot load file %x.</source> +<target>Kan inte läsa in %x</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>Kunde inte starta tjänsten Volume Shadow Copy (VSS)</target> @@ -214,10 +214,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>Skuggkopior av wow64 stöds ej. Använd FreeFileSync x64 istället!</target> -<source>Could not determine volume name for file:</source> -<target>Kan inte bestämma volym för fil:</target> +<source>Cannot determine volume name for file:</source> +<target>Kan inte bestämma volymnamn för filen:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>Volymnamn %x saknas i filnamn %y!</target> <source>/sec</source> @@ -226,8 +226,8 @@ <source>File does not exist:</source> <target>Filen finns inte:</target> -<source>Could not read values for the following XML nodes:</source> -<target>Kan inte läsa värden för följande XML-noder:</target> +<source>Cannot read the following XML elements:</source> +<target>Kan inte läsa följande XML-element:</target> <source>S&ave configuration...</source> <target>S¶ inställningar...</target> @@ -453,9 +453,6 @@ Kommandot verkställes när: <source>2. &Synchronize...</source> <target>2. &Synkronisera...</target> -<source>S&witch view</source> -<target>V&äxla sida</target> - <source>&New</source> <target>&Nytt</target> @@ -543,17 +540,17 @@ Kommandot verkställes när: <source>Speed:</source> <target>Hastighet:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Kvarvarande tid:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Förfluten tid:</target> <source>Batch job</source> <target>Batch-jobb</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Skapa en batch-fil för automatisk synkronisering. För att starta i batch-läge dubbelklickar du på filen eller startar den med kommandoraden: FreeFileSync.exe <ffs_batch file>. Batch-filen kan också schemaläggas i Windows schemaläggare</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>Skapa en batch-fil och automatisera synkroniseringen. För att starta i batch-läge dubbelklickar du på den skapade filen, eller kör följande kommando: FreeFileSync.exe SyncJob.ffs_batch. Detta kan också schemaläggas i systemets schemaläggare.</target> <source>Help</source> <target>Hjälp</target> @@ -567,8 +564,8 @@ Kommandot verkställes när: <source>Right</source> <target>Höger</target> -<source>Overview</source> -<target>Översikt</target> +<source>Sync setttings</source> +<target>Synkroniseringsinställningar</target> <source>Status feedback</source> <target>Status</target> @@ -714,8 +711,8 @@ Filerna betecknas som lika om, <source>Published under the GNU General Public License</source> <target>Publiserad under GNU General Public License</target> -<source>Ignore subsequent errors</source> -<target>Ignorera följdfel</target> +<source>Ignore further errors</source> +<target>Ignorera ytterligare fel</target> <source>Hide further error messages during the current process</source> <target>Dölj vidare felmeddelanden under aktuell process</target> @@ -738,22 +735,22 @@ Filerna betecknas som lika om, <source>&No</source> <target>&Nej</target> +<source>Use Recycle Bin</source> +<target>Använd papperskorgen</target> + <source>Delete on both sides</source> <target>Ta bort på båda sidor</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Ta bort på båda sidor, även om filen är markerad på endast en sida</target> -<source>Use Recycle Bin</source> -<target>Använd papperskorgen</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Endast filer/kataloger som matchar alla filterinställningar, kommer att väljas ut för synkronisering -Notis: Namnfiltret måste specificeras relativt(!) till överordnade synkroniseringskataloger +Endast filer som matchar alla filterinställningar kommer att synkroniseras. +OBS! Filnamnen måste anges relativt till baskataloger </target> <source>Hints:</source> @@ -789,20 +786,20 @@ Undanta: \stuff\temp\* <source>Exclude</source> <target>Undanta</target> -<source>Minimum file size</source> -<target>Minimum filstorlek</target> +<source>Time span</source> +<target>Tidsintervall</target> -<source>Maximum file size</source> -<target>Maximum filstorlek</target> +<source>File size</source> +<target>Filstorlek</target> -<source>&Default</source> -<target>&Standard</target> +<source>Minimum</source> +<target>Minimum</target> -<source>Move column up</source> -<target>Flytta upp kollumn</target> +<source>Maximum</source> +<target>Maximum</target> -<source>Move column down</source> -<target>Flytta ner kollumn</target> +<source>&Default</source> +<target>&Standard</target> <source>Transactional file copy</source> <target>Transaktionell filkopiering</target> @@ -822,14 +819,8 @@ Undanta: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Överför fil- och katalogrättigheter (Kräver administratörsrättigheter)</target> -<source>Hidden dialogs:</source> -<target>Dolda meddelanden:</target> - -<source>Reset</source> -<target>Återställ</target> - -<source>Show hidden dialogs</source> -<target>Visa dolda meddelanden</target> +<source>Restore hidden dialogs</source> +<target>Återställ dolda dialoger</target> <source>External applications</source> <target>Externa program</target> @@ -861,8 +852,8 @@ Undanta: \stuff\temp\* <source>Folder pairs</source> <target>Katalogpar</target> -<source>Compressed view</source> -<target>Komprimerad vy</target> +<source>Overview</source> +<target>Översikt</target> <source>Select view</source> <target>Välj vy</target> @@ -891,8 +882,8 @@ Undanta: \stuff\temp\* <source>Exclude all</source> <target>Exkludera alla</target> -<source>Icon size:</source> -<target>Ikonstorlek:</target> +<source>Show icons:</source> +<target>Visa ikoner</target> <source>Small</source> <target>Liten</target> @@ -918,6 +909,9 @@ Undanta: \stuff\temp\* <source>Configuration saved!</source> <target>Inställningar sparade!</target> +<source>Never save changes</source> +<target>Spara aldrig ändringar</target> + <source>Save changes to current configuration?</source> <target>Vill du spara ändringarna i aktuella inställningar?</target> @@ -1029,9 +1023,6 @@ Undanta: \stuff\temp\* <source>Error writing file:</source> <target>Kan inte skriva fil:</target> -<source>Batch file created successfully!</source> -<target>Batch-filen skapades korrekt!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1110,6 +1101,9 @@ Undanta: \stuff\temp\* <source>This year</source> <target>I år</target> +<source>Last x days</source> +<target>Senaste x dagarna</target> + <source>Byte</source> <target>Byte</target> @@ -1119,11 +1113,8 @@ Undanta: \stuff\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>Filter: Generella undantag</target> - -<source>Filter: Single pair</source> -<target>Filter: Enstaka undantag</target> +<source>Filter</source> +<target>Filter</target> <source>Direct</source> <target>Direkt</target> @@ -1149,8 +1140,8 @@ Undanta: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- Andra sidans motsvarighet till %dir</target> -<source>Restore all hidden dialogs?</source> -<target>Vill du återställa alla dolda dialoger?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>Vill du göra dolda dialoger och varningsmeddelanden synliga igen?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1326,8 +1317,8 @@ Undanta: \stuff\temp\* <source>Preparing synchronization...</source> <target>Förbereder synkronisering...</target> -<source>Memory allocation failed!</source> -<target>Minnesallokering misslyckades!</target> +<source>Out of memory!</source> +<target>Minnesbrist!</target> <source>File %x has an invalid date!</source> <target>Filen %x har ett ogiltigt datum!</target> @@ -1482,11 +1473,11 @@ Undanta: \stuff\temp\* <source>Generating database...</source> <target>Skapar databas...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>Inget att synkronisera enligt aktuella inställningar!</target> +<source>Nothing to synchronize!</source> +<target>Det finns inget att synkronisera!</target> -<source>Error copying locked file %x!</source> -<target>Kan inte kopiera låst fil %x!</target> +<source>Unable to copy locked file %x!</source> +<target>Kan inte kopiera den låsta filen %x!</target> <source>Data verification error: Source and target file have different content!</source> <target>Verifikationsfel: Källfil och målfil har olika innehåll!</target> diff --git a/BUILD/Languages/turkish.lng b/BUILD/Languages/turkish.lng index d326b6c7..7d6ef2ce 100644 --- a/BUILD/Languages/turkish.lng +++ b/BUILD/Languages/turkish.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Yapılandırma süzgeci</target> -<source>Customize columns</source> -<target>Sütunları özelleştir</target> - <source>Global settings</source> <target>Genel ayarlar</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Gözat</target> -<source>Error reading from synchronization database:</source> -<target>Eşleştirme veri tabanı okunurken hata:</target> - -<source>Error writing to synchronization database:</source> -<target>Eşleştirme veri tabanına yazılırken hata:</target> - <source>Invalid command line: %x</source> <target>Geçersiz komut satırı: %x</target> +<source>Info</source> +<target>Bilgi</target> + +<source>Fatal Error</source> +<target>Ölümcül Hata</target> + <source>Windows Error Code %x:</source> <target>Windows Hata Kodu %x:</target> @@ -139,15 +136,21 @@ <pluralform>%x Bayt</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Eşleştirme veri tabanı okunurken hata:</target> + +<source>Error writing to synchronization database:</source> +<target>Eşleştirme veri tabanına yazılırken hata:</target> + +<source>Incompatible synchronization database format:</source> +<target>Uyumsuz eşleştirme veritabanı biçimi:</target> + <source>Initial synchronization:</source> <target>Başlangıç eşleştirmesi:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>FreeFileSync veritabanı dosyalarından biri henüz yok:</target> -<source>Incompatible synchronization database format:</source> -<target>Uyumsuz eşleştirme veritabanı biçimi:</target> - <source>Database files do not share a common synchronization session:</source> <target>Veritabanıdosyaları ortak bir eşleştirmeoturumunu paylaşmıyor:</target> @@ -172,12 +175,6 @@ <pluralform>%x saniye</pluralform> </target> -<source>Info</source> -<target>Bilgi</target> - -<source>Fatal Error</source> -<target>Ölümcül Hata</target> - <source>Error reading file:</source> <target>Dosya okunurken hata:</target> @@ -202,11 +199,14 @@ <source>Error parsing configuration file:</source> <target>Yapılandırma dosyası çözümlenirken hata:</target> -<source>Error moving to Recycle Bin:</source> -<target>Geri Dönüşüm Kutusu'na atılırken hata:</target> +<source>Configuration loaded partially only:</source> +<target>Yapılandırma yalnız kısmen yüklendi:</target> + +<source>Unable to move %x to the Recycle Bin!</source> +<target>%x Geri Dönüşüm Kutusuna gönderilemedi</target> -<source>Could not load a required DLL:</source> -<target>Gerekli bir DLL yüklenemedi:</target> +<source>Cannot load file %x.</source> +<target>%x dosyası yüklenemedi.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>Gölge Kopya Hizmetine erişilirken hata oldu!</target> @@ -214,10 +214,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>WOW64 üzerinde gölge kopyalama desteklenmiyor. FreeFileSync 64-bit sürümünü kullanın</target> -<source>Could not determine volume name for file:</source> -<target>Şu dosya için birim adı belirlenemedi:</target> +<source>Cannot determine volume name for file:</source> +<target>Dosya için birim adı belirlenemedi:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>%x birim adı, %y dosya adının parçası değil!</target> <source>/sec</source> @@ -226,8 +226,8 @@ <source>File does not exist:</source> <target>Dosya bulunamadı:</target> -<source>Could not read values for the following XML nodes:</source> -<target>Şu XML düğümlerindeki değerler okunamadı:</target> +<source>Cannot read the following XML elements:</source> +<target>Şu XML elemanları okunamadı:</target> <source>S&ave configuration...</source> <target>Y&apılandırmayı kaydet...</target> @@ -453,9 +453,6 @@ Her seferinde çalıştırılacak komut satırı: <source>2. &Synchronize...</source> <target>2. &Eşleştir...</target> -<source>S&witch view</source> -<target>Orta görünümü &değiştir</target> - <source>&New</source> <target>Ye&ni</target> @@ -543,17 +540,17 @@ Her seferinde çalıştırılacak komut satırı: <source>Speed:</source> <target>Hız:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Kalan zaman:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Geçen zaman:</target> <source>Batch job</source> <target>Toplu iş</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Otomatik eşleştirme için bir toplu iş dosyası oluşturabilirsiniz. İşlemi başlatmak için dosyaya çift tıklayabilir ya da komut satırını " FreeFileSync.exe <ffs_iş dosyası>" şeklinde kullabilirsiniz. Ayrıca bu dosyayı işletim sisteminizin görev zamanlayıcısı ile istediğiniz zamanlarda çalıştırabilirsiniz.</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>Bir yığın dosyası oluşturarak eşleştirmeyi otomatikleştirir. Yığın kipini başlatmak için oluşturulan dosya üzerinde çift tıklamak ya da şu komutu çalıştırmak yeterlidir: FreeFileSync.exe Eşleştirmeİşi.ffs_batch. Bu işlem aynı şekilde sisteminizin zamanlanmış görev çalıştırıcısına eklenebilir.</target> <source>Help</source> <target>Yardım</target> @@ -567,9 +564,6 @@ Her seferinde çalıştırılacak komut satırı: <source>Right</source> <target>Sağ</target> -<source>Overview</source> -<target>Genel</target> - <source>Status feedback</source> <target>Durum geri bildirimi</target> @@ -714,7 +708,7 @@ aynı olmalıdır <source>Published under the GNU General Public License</source> <target>GNU Genel Kamu Lisansı şartları altında yayınlanmıştır</target> -<source>Ignore subsequent errors</source> +<source>Ignore further errors</source> <target>Sonraki hataları yoksay</target> <source>Hide further error messages during the current process</source> @@ -738,22 +732,22 @@ aynı olmalıdır <source>&No</source> <target>&Hayır</target> +<source>Use Recycle Bin</source> +<target>Geri Dönüşüm Kutusu'nu kullan</target> + <source>Delete on both sides</source> <target>Her iki yandakini de sil</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Dosya yalnız bir tarafta seçili olsa bile her iki yandakini de sil</target> -<source>Use Recycle Bin</source> -<target>Geri Dönüşüm Kutusu'nu kullan</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Yalnızca tüm süzgeç koşullarına uyan dosya ve klasörler eşleştirilir. -Not: Ad süzgeci kök eşleştirme klasörüne göre bağıl(!) olarak belirtilmelidir. +Yalnız tüm süzgeç ayarlarına uyan dosyalar eşleştirilecek. +Not: Dosya adları kök klasörlere göre bağıl olmalıdır! </target> <source>Hints:</source> @@ -789,20 +783,20 @@ Katma: \stuff\temp\* <source>Exclude</source> <target>Dışlanacaklar:</target> -<source>Minimum file size</source> -<target>En küçük dosya boyutu</target> +<source>Time span</source> +<target>Zaman aralığı</target> -<source>Maximum file size</source> -<target>En büyük dosya boyutu</target> +<source>File size</source> +<target>Dosya boyutu</target> -<source>&Default</source> -<target>&Varsayılan</target> +<source>Minimum</source> +<target>En küçük</target> -<source>Move column up</source> -<target>Sütunu yukarı taşı</target> +<source>Maximum</source> +<target>En büyük</target> -<source>Move column down</source> -<target>Sütunu aşağı taşı</target> +<source>&Default</source> +<target>&Varsayılan</target> <source>Transactional file copy</source> <target>Aşamalı kopyalama kullan</target> @@ -822,14 +816,8 @@ Katma: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Dosya ve klasör izinlerini de aktarır (Yönetici izinlerine gerek duyar)</target> -<source>Hidden dialogs:</source> -<target>Gizlenmiş iletiler:</target> - -<source>Reset</source> -<target>Sıfırla</target> - -<source>Show hidden dialogs</source> -<target>Gizlenmiş iletileri göster</target> +<source>Restore hidden dialogs</source> +<target>Gizli iletileri göster</target> <source>External applications</source> <target>Dış uygulamalar</target> @@ -861,8 +849,8 @@ Katma: \stuff\temp\* <source>Folder pairs</source> <target>Klasör çiftleri</target> -<source>Compressed view</source> -<target>Sıkıştırılmış görünüm</target> +<source>Overview</source> +<target>Genel</target> <source>Select view</source> <target>Görünümü seçin</target> @@ -891,8 +879,8 @@ Katma: \stuff\temp\* <source>Exclude all</source> <target>Tümünü dışla</target> -<source>Icon size:</source> -<target>Simge boyutu:</target> +<source>Show icons:</source> +<target>Simgeleri göster:</target> <source>Small</source> <target>Küçük</target> @@ -918,6 +906,9 @@ Katma: \stuff\temp\* <source>Configuration saved!</source> <target>Yapılandırma kaydedildi!</target> +<source>Never save changes</source> +<target>Asla değişiklikleri kaydetme</target> + <source>Save changes to current configuration?</source> <target>Değişiklikleri şu anki yapılandırmaya kaydetmek ister misiniz?</target> @@ -1029,9 +1020,6 @@ Katma: \stuff\temp\* <source>Error writing file:</source> <target>Dosya yazılırken hata:</target> -<source>Batch file created successfully!</source> -<target>Toplu komut dosyası sorunsuz oluşturuldu!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1110,6 +1098,9 @@ Katma: \stuff\temp\* <source>This year</source> <target>Bu yıl</target> +<source>Last x days</source> +<target>Son x günde</target> + <source>Byte</source> <target>Bayt</target> @@ -1119,11 +1110,8 @@ Katma: \stuff\temp\* <source>MB</source> <target>MB</target> -<source>Filter: All pairs</source> -<target>Süzgeç: Tüm çiftler</target> - -<source>Filter: Single pair</source> -<target>Süzgeç: Tek çift</target> +<source>Filter</source> +<target>Süzgeç</target> <source>Direct</source> <target>Doğrudan</target> @@ -1149,8 +1137,8 @@ Katma: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- %dir klasörünün diğer taraftaki karşılığı</target> -<source>Restore all hidden dialogs?</source> -<target>Tüm gizlenmiş iletiler gösterilsin mi?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>Gizlenmiş anımsatma ve uyarı iletileri yeniden görünür olsun mu?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1281,9 +1269,6 @@ Katma: \stuff\temp\* <source>Error copying file:</source> <target>Dosya kopyalanırken hata:</target> -<source>Error opening file:</source> -<target>Dosya açılırken hata:</target> - <source>Error traversing directory:</source> <target>Klasörde dolaşırken hata:</target> @@ -1326,8 +1311,8 @@ Katma: \stuff\temp\* <source>Preparing synchronization...</source> <target>Eşleştirmeye hazırlanıyor...</target> -<source>Memory allocation failed!</source> -<target>Bellek ayrılamadı!</target> +<source>Out of memory!</source> +<target>Bellek yetersiz!</target> <source>File %x has an invalid date!</source> <target>%x dosyasının tarihi geçersiz!</target> @@ -1482,11 +1467,11 @@ Katma: \stuff\temp\* <source>Generating database...</source> <target>Veri tabanı oluşturuluyor...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>Yapılandırmaya göre eşleştirilecek bir şey yok!</target> +<source>Nothing to synchronize!</source> +<target>Eşleştirilecek bir şey yok!</target> -<source>Error copying locked file %x!</source> -<target>Kilitli dosya %x kopyalanırken hata!</target> +<source>Unable to copy locked file %x!</source> +<target>%x dosyası kilitli olduğundan kopyalanamıyor!</target> <source>Data verification error: Source and target file have different content!</source> <target>Veri doğrulama hatası: Kaynak ve hedef dosyası içeriği farklı!</target> diff --git a/BUILD/Languages/ukrainian.lng b/BUILD/Languages/ukrainian.lng index 704c6784..6ee50ff3 100644 --- a/BUILD/Languages/ukrainian.lng +++ b/BUILD/Languages/ukrainian.lng @@ -67,9 +67,6 @@ <source>Configure filter</source> <target>Налаштування фільтра</target> -<source>Customize columns</source> -<target>Вибір колонок</target> - <source>Global settings</source> <target>Глобальні налаштування</target> @@ -103,15 +100,15 @@ <source>Browse</source> <target>Переглянути</target> -<source>Error reading from synchronization database:</source> -<target>Помилка при читанні з бази даних синхронізації:</target> - -<source>Error writing to synchronization database:</source> -<target>Помилка при записі у базу данних синхронізації:</target> - <source>Invalid command line: %x</source> <target>Неправильний командний рядок: %x</target> +<source>Info</source> +<target>Інформація</target> + +<source>Fatal Error</source> +<target>Критична помилка</target> + <source>Windows Error Code %x:</source> <target>Код помилки Windows %x:</target> @@ -140,15 +137,21 @@ <pluralform>%x байтів</pluralform> </target> +<source>Error reading from synchronization database:</source> +<target>Помилка при читанні з бази даних синхронізації:</target> + +<source>Error writing to synchronization database:</source> +<target>Помилка при записі у базу данних синхронізації:</target> + +<source>Incompatible synchronization database format:</source> +<target>Несумісний формат бази даних синхронізації:</target> + <source>Initial synchronization:</source> <target>Вступна синхронізація:</target> <source>One of the FreeFileSync database files is not yet existing:</source> <target>Файлу бази даних FreeFileSync ще не існує:</target> -<source>Incompatible synchronization database format:</source> -<target>Несумісний формат бази даних синхронізації:</target> - <source>Database files do not share a common synchronization session:</source> <target>Файли бази даних не мають спільної сесії синхронізації</target> @@ -174,12 +177,6 @@ <pluralform>%x сек</pluralform> </target> -<source>Info</source> -<target>Інформація</target> - -<source>Fatal Error</source> -<target>Критична помилка</target> - <source>Error reading file:</source> <target>Помилка при читанні файлу:</target> @@ -205,11 +202,14 @@ <source>Error parsing configuration file:</source> <target>Помилка при анализі файлу налаштувань синхронізації:</target> -<source>Error moving to Recycle Bin:</source> -<target>Помилка переміщення в "Корзину":</target> +<source>Configuration loaded partially only:</source> +<target>Конфігурація завантажена лише частково</target> + +<source>Unable to move %x to the Recycle Bin!</source> +<target>Не вдається перенести %x до Корзини!</target> -<source>Could not load a required DLL:</source> -<target>Не вдалося завантажити необхідні DLL:</target> +<source>Cannot load file %x.</source> +<target>Не вдається завантажити файл %x.</target> <source>Error accessing Volume Shadow Copy Service!</source> <target>Помилка доступу до послуги Тіньового Копіювання Тому</target> @@ -217,10 +217,10 @@ <source>Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.</source> <target>Створення тіньових копій на WOW64 не підтримується. Будь ласка, використайте FreeFileSync 64-розрядної версії.</target> -<source>Could not determine volume name for file:</source> -<target>Не вдалося визначити назву тому для файлу:</target> +<source>Cannot determine volume name for file:</source> +<target>Не вдається визначити назву тому для файла:</target> -<source>Volume name %x not part of filename %y!</source> +<source>Volume name %x not part of file name %y!</source> <target>Ім’я тому %x не є частиною імені файлу %y!</target> <source>/sec</source> @@ -229,8 +229,8 @@ <source>File does not exist:</source> <target>Файл не існує:</target> -<source>Could not read values for the following XML nodes:</source> -<target>Не вдалося прочитати значення таких XML записів:</target> +<source>Cannot read the following XML elements:</source> +<target>Не вдається прочитати такі елементи XML:</target> <source>S&ave configuration...</source> <target>Зберегти налаштування...</target> @@ -412,7 +412,7 @@ The command line is executed each time: <target>Повний шлях</target> <source>Name</source> -<target></target> +<target>Назва</target> <source>Relative path</source> <target>Відносний шлях</target> @@ -456,9 +456,6 @@ The command line is executed each time: <source>2. &Synchronize...</source> <target>2. &Синхронізувати</target> -<source>S&witch view</source> -<target>Змінити відображення</target> - <source>&New</source> <target>&Нова</target> @@ -549,17 +546,17 @@ The command line is executed each time: <source>Speed:</source> <target>Швидкість:</target> -<source>Time remaining:</source> +<source>Remaining time:</source> <target>Залишилось часу:</target> -<source>Time elapsed:</source> +<source>Elapsed time:</source> <target>Пройшло часу:</target> <source>Batch job</source> <target>Пакетне завдання</target> -<source>Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner.</source> -<target>Створіть пакетний файл для автоматичної синхронізації. Для виконання пакетної синхронізації просто двічі клацніть файл мишкою або скористайтесь командним рядком: FreeFileSync.exe <ffs_batch file>. Можна також використати планувальник завдань операційної системи</target> +<source>Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner.</source> +<target>Створити комакндний файл і автоматизувати синхронізацію. Для виконання пакетної синхронізації просто двічі клацніть файл мишкою або скористайтесь командним рядком: FreeFileSync.exe <ffs_batch file>. Можна також використати планувальник завдань операційної системи</target> <source>Help</source> <target>Допомога</target> @@ -573,9 +570,6 @@ The command line is executed each time: <source>Right</source> <target>Праворуч</target> -<source>Overview</source> -<target>Головна</target> - <source>Status feedback</source> <target>Статус оберненого зв’язку</target> @@ -693,7 +687,7 @@ is the same <target>Код програми написаний на C++ з використанням:</target> <source>Feedback and suggestions are welcome</source> -<target></target> +<target>Відгуки та пропозиції вітаються</target> <source>Homepage</source> <target>Оф.сайт</target> @@ -716,8 +710,8 @@ is the same <source>Published under the GNU General Public License</source> <target>Видано за ліцензією GNU General Public License</target> -<source>Ignore subsequent errors</source> -<target>Ігнорувати наступні помилки</target> +<source>Ignore further errors</source> +<target>Ігнорувати майбутні помилки</target> <source>Hide further error messages during the current process</source> <target>Приховати наступні помилки підчас цього процесу</target> @@ -740,22 +734,22 @@ is the same <source>&No</source> <target>&Ні</target> +<source>Use Recycle Bin</source> +<target>Використовувати "Корзину"</target> + <source>Delete on both sides</source> <target>Вилучити з обох сторін</target> <source>Delete on both sides even if the file is selected on one side only</source> <target>Вилучити з обох сторін, навіть якщо файл виділений тільки з однієї сторони</target> -<source>Use Recycle Bin</source> -<target>Використовувати "Корзину"</target> - <source> -Only files/directories that match all filter settings will be selected for synchronization. -Note: The name filter must be specified relative(!) to main synchronization directories. +Only files that match all filter settings will be synchronized. +Note: File names must be relative to base directories! </source> <target> -Тільки файли/каталоги, які пройдуть фільтрацію будуть відібрані для синхронізації. -Фільтр буде застосовуватися до імен відносно(!) основних синхронізованих папок. +Тільки файли, які задовільняють всім налаштуванням фільтра будуть синхронізовані. +Увага: Назви файлів вказуються відносно базових каталогів. </target> <source>Hints:</source> @@ -791,20 +785,20 @@ Exclude: \stuff\temp\* <source>Exclude</source> <target>Виключити</target> -<source>Minimum file size</source> -<target>Мінімальний розмір файлу</target> +<source>Time span</source> +<target>Часовий інтервал</target> -<source>Maximum file size</source> -<target>Максимальний розмір файлу</target> +<source>File size</source> +<target>Розмір файла</target> -<source>&Default</source> -<target>&За замовчуванням</target> +<source>Minimum</source> +<target>Мінімум</target> -<source>Move column up</source> -<target>Перемістити догори</target> +<source>Maximum</source> +<target>Максимум</target> -<source>Move column down</source> -<target>Перемістити донизу</target> +<source>&Default</source> +<target>&За замовчуванням</target> <source>Transactional file copy</source> <target>Копіювання файлів з використанням трансакцій</target> @@ -824,14 +818,8 @@ Exclude: \stuff\temp\* <source>Transfer file and directory permissions (Requires Administrator rights)</source> <target>Передача прав доступу файлу/каталогу (потрібні права Адміністратора)</target> -<source>Hidden dialogs:</source> -<target>Приховані діалоги</target> - -<source>Reset</source> -<target>Скинути</target> - -<source>Show hidden dialogs</source> -<target>Показати приховані діалоги</target> +<source>Restore hidden dialogs</source> +<target>Відновити сховані діалоги</target> <source>External applications</source> <target>Зовнішні програми</target> @@ -863,8 +851,8 @@ Exclude: \stuff\temp\* <source>Folder pairs</source> <target>Пари папок</target> -<source>Compressed view</source> -<target></target> +<source>Overview</source> +<target>Головна</target> <source>Select view</source> <target>Список файлів</target> @@ -888,13 +876,13 @@ Exclude: \stuff\temp\* <target>Видалити</target> <source>Include all</source> -<target></target> +<target>Включити все</target> <source>Exclude all</source> -<target></target> +<target>Виключити все</target> -<source>Icon size:</source> -<target>Розмір іконки:</target> +<source>Show icons:</source> +<target>Показати іконки:</target> <source>Small</source> <target>Малий</target> @@ -909,7 +897,7 @@ Exclude: \stuff\temp\* <target>Виберіть інтервал часу...</target> <source>Default view</source> -<target></target> +<target>Вигляд за замовчуванням</target> <source>Show "%x"</source> <target>Показати "%x"</target> @@ -920,6 +908,9 @@ Exclude: \stuff\temp\* <source>Configuration saved!</source> <target>Налаштування синхронізації збережено!</target> +<source>Never save changes</source> +<target>Ніколи не зберігати змін</target> + <source>Save changes to current configuration?</source> <target>Зберегти зміни в активних налаштуваннях?</target> @@ -1031,9 +1022,6 @@ Exclude: \stuff\temp\* <source>Error writing file:</source> <target>Помилка при записі файлу:</target> -<source>Batch file created successfully!</source> -<target>Файл завдання успішно створений!</target> - <source> <pluralform>Object deleted successfully!</pluralform> <pluralform>%x objects deleted successfully!</pluralform> @@ -1116,6 +1104,9 @@ Exclude: \stuff\temp\* <source>This year</source> <target>Цього року</target> +<source>Last x days</source> +<target>Останні x днів</target> + <source>Byte</source> <target>Байт</target> @@ -1125,11 +1116,8 @@ Exclude: \stuff\temp\* <source>MB</source> <target>МБ</target> -<source>Filter: All pairs</source> -<target>Фільтр: Всі пари</target> - -<source>Filter: Single pair</source> -<target>Фільтр: Одна пара</target> +<source>Filter</source> +<target>Фільтр</target> <source>Direct</source> <target>Прямо</target> @@ -1155,8 +1143,8 @@ Exclude: \stuff\temp\* <source>- Other side's counterpart to %dir</source> <target>- аналогічна папка з другої сторони</target> -<source>Restore all hidden dialogs?</source> -<target>Відновити всі приховані діалогові вікна?</target> +<source>Make hidden dialogs and warning messages visible again?</source> +<target>Зробити приховані діалоги та попередження знову видимими?</target> <source> <pluralform>Do you really want to move the following object to the Recycle Bin?</pluralform> @@ -1197,10 +1185,10 @@ Exclude: \stuff\temp\* <target>Переміщати файли в підкатлог з часовою міткою</target> <source>Files</source> -<target></target> +<target>Файли</target> <source>Percentage</source> -<target></target> +<target>Проценти</target> <source>%x TB</source> <target>%x ТБ</target> @@ -1292,9 +1280,6 @@ Exclude: \stuff\temp\* <source>Error copying file:</source> <target>Помилка при копіюванні файлу:</target> -<source>Error opening file:</source> -<target>Помилка при відкриванні файлу:</target> - <source>Error traversing directory:</source> <target>Помилка обходу каталогу:</target> @@ -1338,10 +1323,10 @@ Exclude: \stuff\temp\* <target>Залежні каталоги! Будьте уважні при налаштуванні правил синхронізації:</target> <source>Preparing synchronization...</source> -<target></target> +<target>Підготовка до синхронізації...</target> -<source>Memory allocation failed!</source> -<target>Помилка виділення пам’яті! (Не хватает памяти)</target> +<source>Out of memory!</source> +<target>Бракує пам'яті!</target> <source>File %x has an invalid date!</source> <target>Файл %x має неіснуючу дату!</target> @@ -1458,7 +1443,7 @@ Exclude: \stuff\temp\* <target>Кінцевий каталог не повинен бути порожнім</target> <source>Directory for file versioning was not supplied!</source> -<target></target> +<target>Не вказаний каталог для старих версій файлів!</target> <source>Source directory does not exist anymore:</source> <target>Каталог-джерело вже не існує:</target> @@ -1496,11 +1481,11 @@ Exclude: \stuff\temp\* <source>Generating database...</source> <target>Створення бази даних...</target> -<source>Nothing to synchronize according to configuration!</source> -<target>Нічого синхронізувати згідно з налаштуваннями синхронізації!</target> +<source>Nothing to synchronize!</source> +<target>Нічого синхронізувати!</target> -<source>Error copying locked file %x!</source> -<target>Помилка при копіюванні заблокованого файлу %x!</target> +<source>Unable to copy locked file %x!</source> +<target>Не можу зкопіювати заблокований файл %x!</target> <source>Data verification error: Source and target file have different content!</source> <target>Помилка перевірки даних: вхідний і вихідний файли мають різний вміст!</target> diff --git a/BUILD/Resources.zip b/BUILD/Resources.zip Binary files differindex 905fa797..9cae0887 100644 --- a/BUILD/Resources.zip +++ b/BUILD/Resources.zip diff --git a/FreeFileSync.cbp b/FreeFileSync.cbp index 8d24385b..c3b8f6f0 100644 --- a/FreeFileSync.cbp +++ b/FreeFileSync.cbp @@ -23,7 +23,7 @@ <Linker> <Add option="-s" /> <Add option="-static" /> - <Add library="libboost_thread-mgw46-mt-s-1_48.a" /> + <Add library="libboost_thread-mgw46-mt-s-1_49.a" /> <Add library="libwxmsw28u_aui.a" /> <Add library="libwxmsw28u_adv.a" /> <Add library="libwxmsw28u_core.a" /> @@ -33,6 +33,9 @@ <Add library="libwxzlib.a" /> <Add directory="C:\Programme\C++\wxWidgets\lib\gcc_lib" /> </Linker> + <ExtraCommands> + <Add after='"C:\Program Files\C++\CodeSigning\SignCode.cmd" "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)"' /> + </ExtraCommands> </Target> <Target title="Debug-DLL"> <Option output="BUILD\Bin\FreeFileSync_Debug" prefix_auto="1" extension_auto="1" /> @@ -50,7 +53,7 @@ <Add directory="C:\Programme\C++\wxWidgets\lib\gcc_dll\mswud" /> </Compiler> <Linker> - <Add library="libboost_thread-mgw46-mt-sd-1_48.a" /> + <Add library="libboost_thread-mgw46-mt-sd-1_49.a" /> <Add library="libwxmsw28ud_aui.a" /> <Add library="libwxmsw28ud_adv.a" /> <Add library="libwxmsw28ud_core.a" /> @@ -77,7 +80,7 @@ <Add directory="lib\gtest\include" /> </Compiler> <Linker> - <Add library="libboost_thread-mgw46-mt-sd-1_48.a" /> + <Add library="libboost_thread-mgw46-mt-sd-1_49.a" /> <Add library="libwxmsw28ud_adv.a" /> <Add library="libwxmsw28ud_core.a" /> <Add library="libwxbase28ud.a" /> @@ -156,7 +159,6 @@ <Unit filename="lib\dir_exist_async.h" /> <Unit filename="lib\dir_lock.cpp" /> <Unit filename="lib\dir_lock.h" /> - <Unit filename="lib\error_log.cpp" /> <Unit filename="lib\error_log.h" /> <Unit filename="lib\ffs_paths.h" /> <Unit filename="lib\gtest\main.cpp"> diff --git a/FreeFileSync.vcxproj b/FreeFileSync.vcxproj index d34d50f6..f9b1c35d 100644 --- a/FreeFileSync.vcxproj +++ b/FreeFileSync.vcxproj @@ -1 +1,320 @@ -<?xml version="1.0" encoding="utf-8"?><Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> <Platform>Win32</Platform> </ProjectConfiguration> <ProjectConfiguration Include="Debug|x64"> <Configuration>Debug</Configuration> <Platform>x64</Platform> </ProjectConfiguration> <ProjectConfiguration Include="Release|Win32"> <Configuration>Release</Configuration> <Platform>Win32</Platform> </ProjectConfiguration> <ProjectConfiguration Include="Release|x64"> <Configuration>Release</Configuration> <Platform>x64</Platform> </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> <ProjectGuid>{86C36CC7-9418-4253-9928-828486F59A00}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>FreeFileSync</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> <CharacterSet>Unicode</CharacterSet> <PlatformToolset>Windows7.1SDK</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> <CharacterSet>Unicode</CharacterSet> <PlatformToolset>Windows7.1SDK</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> <CharacterSet>Unicode</CharacterSet> <PlatformToolset>Windows7.1SDK</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> <CharacterSet>Unicode</CharacterSet> <PlatformToolset>Windows7.1SDK</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> </ImportGroup> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> </ImportGroup> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> </ImportGroup> <PropertyGroup Label="UserMacros" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <LinkIncremental>true</LinkIncremental> <OutDir>BUILD\Bin\</OutDir> <IntDir>OBJ\$(ProjectName)_$(Configuration)_$(PlatformName)_VCPP\</IntDir> <GenerateManifest>false</GenerateManifest> <TargetName>$(ProjectName)_Debug</TargetName> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <LinkIncremental>true</LinkIncremental> <OutDir>BUILD\Bin\</OutDir> <IntDir>OBJ\$(ProjectName)_$(Configuration)_$(PlatformName)_VCPP\</IntDir> <GenerateManifest>false</GenerateManifest> <TargetName>$(ProjectName)_Debug</TargetName> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <LinkIncremental>false</LinkIncremental> <OutDir>BUILD\Bin\</OutDir> <IntDir>OBJ\$(ProjectName)_$(Configuration)_$(PlatformName)_VCPP\</IntDir> <GenerateManifest>false</GenerateManifest> <TargetName>$(ProjectName)_$(PlatformName)</TargetName> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <LinkIncremental>false</LinkIncremental> <OutDir>BUILD\Bin\</OutDir> <IntDir>OBJ\$(ProjectName)_$(Configuration)_$(PlatformName)_VCPP\</IntDir> <GenerateManifest>false</GenerateManifest> <TargetName>$(ProjectName)_$(PlatformName)</TargetName> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> <PrecompiledHeader>Use</PrecompiledHeader> <WarningLevel>Level4</WarningLevel> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>WXUSINGDLL;ZEN_PLATFORM_WINDOWS;wxUSE_UNICODE;__WXMSW__;FFS_WIN;WXINTL_NO_GETTEXT_MACRO;__WXDEBUG__;%(PreprocessorDefinitions)</PreprocessorDefinitions> <AdditionalIncludeDirectories>.;C:\Program Files\C++\wxWidgets\include;C:\Program Files\C++\wxWidgets\lib\vc_dll\mswud;C:\Program Files\C++\Boost</AdditionalIncludeDirectories> <PrecompiledHeaderFile>wx+\pch.h</PrecompiledHeaderFile> <DisableSpecificWarnings>4100;4996;4267;4512</DisableSpecificWarnings> <MultiProcessorCompilation>true</MultiProcessorCompilation> <PrecompiledHeaderOutputFile>$(IntDir)pch.obj</PrecompiledHeaderOutputFile> <ForcedIncludeFiles>zen/warn_static.h;wx+\pch.h</ForcedIncludeFiles> <DebugInformationFormat>EditAndContinue</DebugInformationFormat> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <MinimalRebuild>false</MinimalRebuild> <ShowIncludes> </ShowIncludes> </ClCompile> <Link> <SubSystem>Windows</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <AdditionalDependencies>wxmsw28ud_aui.lib;wxmsw28ud_adv.lib;wxmsw28ud_core.lib;wxbase28ud_net.lib;wxbase28ud.lib;wxpngd.lib;wxzlibd.lib;comctl32.lib;ws2_32.lib;Rpcrt4.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>C:\Program Files\C++\wxWidgets\lib\vc_dll;C:\Program Files\C++\Boost\stage\lib</AdditionalLibraryDirectories> <LinkStatus> </LinkStatus> <ShowProgress> </ShowProgress> </Link> <ResourceCompile> <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include;C:\Program Files\C++\wxWidgets\lib\vc_lib\mswud</AdditionalIncludeDirectories> <PreprocessorDefinitions>%(PreprocessorDefinitions);</PreprocessorDefinitions> </ResourceCompile> <Manifest> <SuppressDependencyElement> </SuppressDependencyElement> </Manifest> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ClCompile> <PrecompiledHeader>Use</PrecompiledHeader> <WarningLevel>Level4</WarningLevel> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>WXUSINGDLL;ZEN_PLATFORM_WINDOWS;wxUSE_UNICODE;__WXMSW__;FFS_WIN;WXINTL_NO_GETTEXT_MACRO;__WXDEBUG__;%(PreprocessorDefinitions)</PreprocessorDefinitions> <AdditionalIncludeDirectories>.;C:\Program Files\C++\wxWidgets-x64\include;C:\Program Files\C++\wxWidgets-x64\lib\vc_dll\mswud;C:\Program Files\C++\Boost</AdditionalIncludeDirectories> <PrecompiledHeaderFile>wx+\pch.h</PrecompiledHeaderFile> <DisableSpecificWarnings>4100;4996;4267;4512</DisableSpecificWarnings> <MultiProcessorCompilation>true</MultiProcessorCompilation> <PrecompiledHeaderOutputFile>$(IntDir)pch.obj</PrecompiledHeaderOutputFile> <ForcedIncludeFiles>zen/warn_static.h;wx+\pch.h</ForcedIncludeFiles> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <MinimalRebuild>false</MinimalRebuild> </ClCompile> <Link> <SubSystem>Windows</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <AdditionalDependencies>wxbase28ud.lib;wxmsw28ud_core.lib;wxmsw28ud_adv.lib;wxmsw28ud_aui.lib;wxbase28ud_net.lib;wxpngd.lib;wxzlibd.lib;comctl32.lib;ws2_32.lib;Rpcrt4.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>C:\Program Files\C++\wxWidgets-x64\lib\vc_dll;C:\Program Files\C++\Boost\stage64\lib</AdditionalLibraryDirectories> <LinkStatus> </LinkStatus> </Link> <ResourceCompile> <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include;C:\Program Files\C++\wxWidgets\lib\vc_lib\mswud</AdditionalIncludeDirectories> <PreprocessorDefinitions>%(PreprocessorDefinitions);WX_CPU_AMD64</PreprocessorDefinitions> </ResourceCompile> <Manifest> <SuppressDependencyElement> </SuppressDependencyElement> </Manifest> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> <WarningLevel>Level4</WarningLevel> <PrecompiledHeader>NotUsing</PrecompiledHeader> <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <PreprocessorDefinitions>ZEN_PLATFORM_WINDOWS;wxUSE_UNICODE;__WXMSW__;FFS_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <AdditionalIncludeDirectories>.;C:\Program Files\C++\wxWidgets\include;C:\Program Files\C++\wxWidgets\lib\vc_lib\mswu;C:\Program Files\C++\Boost</AdditionalIncludeDirectories> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <DisableSpecificWarnings>4100;4996;4267;4512</DisableSpecificWarnings> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <MultiProcessorCompilation>true</MultiProcessorCompilation> <InlineFunctionExpansion>Default</InlineFunctionExpansion> <ForcedIncludeFiles>zen/warn_static.h</ForcedIncludeFiles> </ClCompile> <Link> <SubSystem>Windows</SubSystem> <GenerateDebugInformation>false</GenerateDebugInformation> <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> <AdditionalDependencies>wxmsw28u_aui.lib;wxmsw28u_adv.lib;wxmsw28u_core.lib;wxbase28u.lib;wxpng.lib;wxzlib.lib;wxbase28u_net.lib;comctl32.lib;ws2_32.lib;winmm.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <AdditionalLibraryDirectories>C:\Program Files\C++\wxWidgets\lib\vc_lib;C:\Program Files\C++\Boost\stage\lib</AdditionalLibraryDirectories> <LinkStatus> </LinkStatus> <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> </Link> <ResourceCompile> <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include;C:\Program Files\C++\wxWidgets\lib\vc_lib\mswu</AdditionalIncludeDirectories> <PreprocessorDefinitions>%(PreprocessorDefinitions);</PreprocessorDefinitions> <Culture> </Culture> </ResourceCompile> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> <WarningLevel>Level4</WarningLevel> <PrecompiledHeader>NotUsing</PrecompiledHeader> <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <PreprocessorDefinitions>ZEN_PLATFORM_WINDOWS;wxUSE_UNICODE;__WXMSW__;FFS_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <AdditionalIncludeDirectories>.;C:\Program Files\C++\wxWidgets-x64\include;C:\Program Files\C++\wxWidgets-x64\lib\vc_lib\mswu;C:\Program Files\C++\Boost</AdditionalIncludeDirectories> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <DisableSpecificWarnings>4100;4996;4267;4512</DisableSpecificWarnings> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <MultiProcessorCompilation>true</MultiProcessorCompilation> <ForcedIncludeFiles>zen/warn_static.h</ForcedIncludeFiles> </ClCompile> <Link> <SubSystem>Windows</SubSystem> <GenerateDebugInformation>false</GenerateDebugInformation> <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> <AdditionalDependencies>wxmsw28u_aui.lib;wxmsw28u_adv.lib;wxmsw28u_core.lib;wxbase28u.lib;wxpng.lib;wxzlib.lib;wxbase28u_net.lib;comctl32.lib;ws2_32.lib;winmm.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <AdditionalLibraryDirectories>C:\Program Files\C++\wxWidgets-x64\lib\vc_lib;C:\Program Files\C++\Boost\stage64\lib</AdditionalLibraryDirectories> <LinkStatus> </LinkStatus> <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> </Link> <ResourceCompile> <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include;C:\Program Files\C++\wxWidgets\lib\vc_lib\mswu</AdditionalIncludeDirectories> <PreprocessorDefinitions>%(PreprocessorDefinitions);WX_CPU_AMD64</PreprocessorDefinitions> <Culture> </Culture> </ResourceCompile> <PreBuildEvent> <Command> </Command> </PreBuildEvent> </ItemDefinitionGroup> <ItemGroup> <ClCompile Include="algorithm.cpp"> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> </ClCompile> <ClCompile Include="application.cpp" /> <ClCompile Include="comparison.cpp" /> <ClCompile Include="file_hierarchy.cpp" /> <ClCompile Include="lib\binary.cpp" /> <ClCompile Include="lib\db_file.cpp" /> <ClCompile Include="lib\dir_lock.cpp" /> <ClCompile Include="lib\error_log.cpp" /> <ClCompile Include="lib\hard_filter.cpp" /> <ClCompile Include="lib\icon_buffer.cpp" /> <ClCompile Include="lib\localization.cpp" /> <ClCompile Include="lib\parallel_scan.cpp" /> <ClCompile Include="lib\process_xml.cpp" /> <ClCompile Include="lib\recycler.cpp" /> <ClCompile Include="lib\resolve_path.cpp" /> <ClCompile Include="lib\resources.cpp" /> <ClCompile Include="lib\shadow.cpp" /> <ClCompile Include="lib\statistics.cpp" /> <ClCompile Include="lib\status_handler.cpp" /> <ClCompile Include="lib\xml_base.cpp" /> <ClCompile Include="structures.cpp" /> <ClCompile Include="synchronization.cpp" /> <ClCompile Include="ui\batch_config.cpp" /> <ClCompile Include="ui\batch_status_handler.cpp" /> <ClCompile Include="ui\check_version.cpp" /> <ClCompile Include="ui\custom_grid.cpp" /> <ClCompile Include="ui\dir_name.cpp" /> <ClCompile Include="ui\exec_finished_box.cpp" /> <ClCompile Include="ui\folder_history_box.cpp" /> <ClCompile Include="ui\grid_view.cpp" /> <ClCompile Include="ui\gui_generated.cpp" /> <ClCompile Include="ui\gui_status_handler.cpp" /> <ClCompile Include="ui\main_dlg.cpp" /> <ClCompile Include="ui\msg_popup.cpp" /> <ClCompile Include="ui\progress_indicator.cpp" /> <ClCompile Include="ui\search.cpp" /> <ClCompile Include="ui\small_dlgs.cpp" /> <ClCompile Include="ui\sync_cfg.cpp" /> <ClCompile Include="ui\taskbar.cpp" /> <ClCompile Include="ui\tray_icon.cpp" /> <ClCompile Include="ui\tree_view.cpp" /> <ClCompile Include="wx+\button.cpp" /> <ClCompile Include="wx+\format_unit.cpp" /> <ClCompile Include="wx+\graph.cpp" /> <ClCompile Include="wx+\grid.cpp" /> <ClCompile Include="wx+\mouse_move_dlg.cpp" /> <ClCompile Include="wx+\tooltip.cpp" /> <ClCompile Include="zenxml\unit_test.cpp" /> <ClCompile Include="zen\dst_hack.cpp" /> <ClCompile Include="zen\file_handling.cpp" /> <ClCompile Include="zen\file_id.cpp" /> <ClCompile Include="zen\file_io.cpp" /> <ClCompile Include="zen\file_traverser.cpp" /> <ClCompile Include="zen\privilege.cpp" /> <ClCompile Include="zen\zstring.cpp" /> </ItemGroup> <ItemGroup> <ResourceCompile Include="resource.rc" /> </ItemGroup> <ItemGroup> <None Include="WxWizFrame.fbp"> <SubType>Designer</SubType> </None> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup></Project>
\ No newline at end of file +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{86C36CC7-9418-4253-9928-828486F59A00}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>FreeFileSync</RootNamespace> + <VCTargetsPath Condition="'$(VCTargetsPath11)' != '' and '$(VSVersion)' == '' and $(VisualStudioVersion) == ''">$(VCTargetsPath11)</VCTargetsPath> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>Windows7.1SDK</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>Windows7.1SDK</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>BUILD\Bin\</OutDir> + <IntDir>OBJ\$(ProjectName)_$(Configuration)_$(PlatformName)_VCPP\</IntDir> + <GenerateManifest>false</GenerateManifest> + <TargetName>$(ProjectName)_Debug</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>BUILD\Bin\</OutDir> + <IntDir>OBJ\$(ProjectName)_$(Configuration)_$(PlatformName)_VCPP\</IntDir> + <GenerateManifest>false</GenerateManifest> + <TargetName>$(ProjectName)_Debug</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>BUILD\Bin\</OutDir> + <IntDir>OBJ\$(ProjectName)_$(Configuration)_$(PlatformName)_VCPP\</IntDir> + <GenerateManifest>false</GenerateManifest> + <TargetName>$(ProjectName)_$(PlatformName)</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>BUILD\Bin\</OutDir> + <IntDir>OBJ\$(ProjectName)_$(Configuration)_$(PlatformName)_VCPP\</IntDir> + <GenerateManifest>false</GenerateManifest> + <TargetName>$(ProjectName)_$(PlatformName)</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <WarningLevel>Level4</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;ZEN_PLATFORM_WINDOWS;wxUSE_UNICODE;__WXMSW__;FFS_WIN;WXINTL_NO_GETTEXT_MACRO;__WXDEBUG__;WXUSINGDLL</PreprocessorDefinitions> + <AdditionalIncludeDirectories>.;C:\Program Files\C++\wxWidgets\include;C:\Program Files\C++\wxWidgets\lib\vc_dll\mswud;C:\Program Files\C++\Boost</AdditionalIncludeDirectories> + <PrecompiledHeaderFile>wx+\pch.h</PrecompiledHeaderFile> + <DisableSpecificWarnings>4100;4512</DisableSpecificWarnings> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <PrecompiledHeaderOutputFile>$(IntDir)pch.obj</PrecompiledHeaderOutputFile> + <ForcedIncludeFiles>zen/warn_static.h;wx+\pch.h</ForcedIncludeFiles> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <MinimalRebuild>false</MinimalRebuild> + <ShowIncludes> + </ShowIncludes> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <AdditionalDependencies>wxmsw28ud_aui.lib;wxmsw28ud_adv.lib;wxmsw28ud_core.lib;wxbase28ud_net.lib;wxbase28ud.lib;wxpngd.lib;wxzlibd.lib;comctl32.lib;ws2_32.lib;Rpcrt4.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>C:\Program Files\C++\wxWidgets\lib\vc_dll;C:\Program Files\C++\Boost\stage\lib</AdditionalLibraryDirectories> + <LinkStatus> + </LinkStatus> + <ShowProgress> + </ShowProgress> + <Profile>true</Profile> + </Link> + <ResourceCompile> + <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);</PreprocessorDefinitions> + </ResourceCompile> + <Manifest> + <SuppressDependencyElement> + </SuppressDependencyElement> + </Manifest> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader>Use</PrecompiledHeader> + <WarningLevel>Level4</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;ZEN_PLATFORM_WINDOWS;wxUSE_UNICODE;__WXMSW__;FFS_WIN;WXINTL_NO_GETTEXT_MACRO;__WXDEBUG__;WXUSINGDLL</PreprocessorDefinitions> + <AdditionalIncludeDirectories>.;C:\Program Files\C++\wxWidgets-x64-VC11\include;C:\Program Files\C++\wxWidgets-x64\lib\vc_dll\mswud;C:\Program Files\C++\Boost</AdditionalIncludeDirectories> + <PrecompiledHeaderFile>wx+\pch.h</PrecompiledHeaderFile> + <DisableSpecificWarnings>4100;4512</DisableSpecificWarnings> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <PrecompiledHeaderOutputFile>$(IntDir)pch.obj</PrecompiledHeaderOutputFile> + <ForcedIncludeFiles>zen/warn_static.h;wx+\pch.h</ForcedIncludeFiles> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <MinimalRebuild>false</MinimalRebuild> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <AdditionalDependencies>wxbase28ud.lib;wxmsw28ud_core.lib;wxmsw28ud_adv.lib;wxmsw28ud_aui.lib;wxbase28ud_net.lib;wxpngd.lib;wxzlibd.lib;comctl32.lib;ws2_32.lib;Rpcrt4.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>C:\Program Files\C++\wxWidgets-x64-VC11\lib\vc_dll;C:\Program Files\C++\Boost\stage64\lib</AdditionalLibraryDirectories> + <LinkStatus> + </LinkStatus> + <Profile>true</Profile> + </Link> + <ResourceCompile> + <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets-x64-VC11\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);WX_CPU_AMD64</PreprocessorDefinitions> + </ResourceCompile> + <Manifest> + <SuppressDependencyElement> + </SuppressDependencyElement> + </Manifest> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level4</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;ZEN_PLATFORM_WINDOWS;wxUSE_UNICODE;__WXMSW__;FFS_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG</PreprocessorDefinitions> + <AdditionalIncludeDirectories>.;C:\Program Files\C++\wxWidgets\include;C:\Program Files\C++\wxWidgets\lib\vc_lib\mswu;C:\Program Files\C++\Boost</AdditionalIncludeDirectories> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <DisableSpecificWarnings>4100;4512</DisableSpecificWarnings> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <ForcedIncludeFiles>zen/warn_static.h</ForcedIncludeFiles> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>false</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>wxmsw28u_aui.lib;wxmsw28u_adv.lib;wxmsw28u_core.lib;wxbase28u.lib;wxpng.lib;wxzlib.lib;wxbase28u_net.lib;comctl32.lib;ws2_32.lib;winmm.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <AdditionalLibraryDirectories>C:\Program Files\C++\wxWidgets\lib\vc_lib;C:\Program Files\C++\Boost\stage\lib</AdditionalLibraryDirectories> + <LinkStatus> + </LinkStatus> + <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> + <Profile>true</Profile> + </Link> + <ResourceCompile> + <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);</PreprocessorDefinitions> + <Culture> + </Culture> + </ResourceCompile> + <PostBuildEvent> + <Command>"C:\Program Files\C++\CodeSigning\SignCode.cmd" "$(TargetPath)"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level4</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;ZEN_PLATFORM_WINDOWS;wxUSE_UNICODE;__WXMSW__;FFS_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG</PreprocessorDefinitions> + <AdditionalIncludeDirectories>.;C:\Program Files\C++\wxWidgets-x64-VC11\include;C:\Program Files\C++\wxWidgets-x64\lib\vc_lib\mswu;C:\Program Files\C++\Boost</AdditionalIncludeDirectories> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <DisableSpecificWarnings>4100;4512</DisableSpecificWarnings> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <ForcedIncludeFiles>zen/warn_static.h</ForcedIncludeFiles> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>false</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>wxmsw28u_aui.lib;wxmsw28u_adv.lib;wxmsw28u_core.lib;wxbase28u.lib;wxpng.lib;wxzlib.lib;wxbase28u_net.lib;comctl32.lib;ws2_32.lib;winmm.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <AdditionalLibraryDirectories>C:\Program Files\C++\wxWidgets-x64-VC11\lib\vc_lib;C:\Program Files\C++\Boost\stage64\lib</AdditionalLibraryDirectories> + <LinkStatus> + </LinkStatus> + <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> + <Profile>true</Profile> + </Link> + <ResourceCompile> + <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets-x64-VC11\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);WX_CPU_AMD64</PreprocessorDefinitions> + <Culture> + </Culture> + </ResourceCompile> + <PreBuildEvent> + <Command> + </Command> + </PreBuildEvent> + <PostBuildEvent> + <Command>"C:\Program Files\C++\CodeSigning\SignCode.cmd" "$(TargetPath)"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="algorithm.cpp"> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> + <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> + </ClCompile> + <ClCompile Include="application.cpp" /> + <ClCompile Include="comparison.cpp" /> + <ClCompile Include="file_hierarchy.cpp" /> + <ClCompile Include="lib\binary.cpp" /> + <ClCompile Include="lib\db_file.cpp" /> + <ClCompile Include="lib\dir_lock.cpp" /> + <ClCompile Include="lib\hard_filter.cpp" /> + <ClCompile Include="lib\icon_buffer.cpp" /> + <ClCompile Include="lib\localization.cpp" /> + <ClCompile Include="lib\parallel_scan.cpp" /> + <ClCompile Include="lib\process_xml.cpp" /> + <ClCompile Include="lib\recycler.cpp" /> + <ClCompile Include="lib\resolve_path.cpp" /> + <ClCompile Include="lib\resources.cpp" /> + <ClCompile Include="lib\shadow.cpp" /> + <ClCompile Include="lib\statistics.cpp" /> + <ClCompile Include="lib\status_handler.cpp" /> + <ClCompile Include="lib\xml_base.cpp" /> + <ClCompile Include="structures.cpp" /> + <ClCompile Include="synchronization.cpp" /> + <ClCompile Include="ui\batch_config.cpp" /> + <ClCompile Include="ui\batch_status_handler.cpp" /> + <ClCompile Include="ui\check_version.cpp" /> + <ClCompile Include="ui\custom_grid.cpp" /> + <ClCompile Include="ui\dir_name.cpp" /> + <ClCompile Include="ui\exec_finished_box.cpp" /> + <ClCompile Include="ui\folder_history_box.cpp" /> + <ClCompile Include="ui\grid_view.cpp" /> + <ClCompile Include="ui\gui_generated.cpp" /> + <ClCompile Include="ui\gui_status_handler.cpp" /> + <ClCompile Include="ui\main_dlg.cpp" /> + <ClCompile Include="ui\msg_popup.cpp" /> + <ClCompile Include="ui\progress_indicator.cpp" /> + <ClCompile Include="ui\search.cpp" /> + <ClCompile Include="ui\small_dlgs.cpp" /> + <ClCompile Include="ui\sync_cfg.cpp" /> + <ClCompile Include="ui\taskbar.cpp" /> + <ClCompile Include="ui\tray_icon.cpp" /> + <ClCompile Include="ui\tree_view.cpp" /> + <ClCompile Include="wx+\button.cpp" /> + <ClCompile Include="wx+\format_unit.cpp" /> + <ClCompile Include="wx+\graph.cpp" /> + <ClCompile Include="wx+\grid.cpp" /> + <ClCompile Include="wx+\mouse_move_dlg.cpp" /> + <ClCompile Include="wx+\tooltip.cpp" /> + <ClCompile Include="zenxml\unit_test.cpp" /> + <ClCompile Include="zen\dst_hack.cpp" /> + <ClCompile Include="zen\file_handling.cpp" /> + <ClCompile Include="zen\file_id.cpp" /> + <ClCompile Include="zen\file_io.cpp" /> + <ClCompile Include="zen\file_traverser.cpp" /> + <ClCompile Include="zen\privilege.cpp" /> + <ClCompile Include="zen\zstring.cpp" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="resource.rc" /> + </ItemGroup> + <ItemGroup> + <None Include="WxWizFrame.fbp"> + <SubType>Designer</SubType> + </None> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file @@ -5,37 +5,36 @@ SHAREDIR = $(DESTDIR)$(prefix)/share APPSHAREDIR = $(SHAREDIR)/$(APPNAME) DOCSHAREDIR = $(SHAREDIR)/doc/$(APPNAME) -COMMON_COMPILE_FLAGS = -Wall -pipe `pkg-config --cflags gtk+-2.0` -O3 -pthread -std=gnu++0x -DNDEBUG -DwxUSE_UNICODE -DFFS_LINUX -DZEN_PLATFORM_OTHER -DWXINTL_NO_GETTEXT_MACRO -I. -include "zen/i18n.h" -COMMON_LINK_FLAGS = -O3 -pthread +COMMON_COMPILE_FLAGS = -Wall -pipe -O3 -pthread -std=gnu++0x -DNDEBUG -DwxUSE_UNICODE -DFFS_LINUX -DZEN_PLATFORM_OTHER -DWXINTL_NO_GETTEXT_MACRO -I. -include "zen/i18n.h" +COMMON_LINK_FLAGS = -pthread #default build -FFS_CPPFLAGS = $(COMMON_COMPILE_FLAGS) `wx-config --cxxflags --debug=no --unicode=yes` -LINKFLAGS = $(COMMON_LINK_FLAGS) `wx-config --libs std,aui --debug=no --unicode=yes` -lboost_thread +CPPFLAGS = $(COMMON_COMPILE_FLAGS) `wx-config --cxxflags --debug=no --unicode=yes` +LINKFLAGS = $(COMMON_LINK_FLAGS) `wx-config --libs std,aui --debug=no --unicode=yes` -lboost_thread #static std library linkage used for precompiled release ifeq ($(BUILD),release) -FFS_CPPFLAGS = $(COMMON_COMPILE_FLAGS) `wx-config --cxxflags --debug=no --unicode=yes --static=yes` -LINKFLAGS = $(COMMON_LINK_FLAGS) `wx-config --libs std,aui --debug=no --unicode=yes --static=yes` /usr/local/lib/libboost_thread.a +CPPFLAGS = $(COMMON_COMPILE_FLAGS) `wx-config --cxxflags --debug=no --unicode=yes --static=yes` +LINKFLAGS = $(COMMON_LINK_FLAGS) `wx-config --libs std,aui --debug=no --unicode=yes --static=yes` /usr/local/lib/libboost_thread.a endif ##################################################################################################### - -#support for GTKMM -FFS_CPPFLAGS += `pkg-config --cflags gtkmm-2.4` -LINKFLAGS += `pkg-config --libs gtkmm-2.4` +#Gtk - recycler/icon loading +CPPFLAGS += `pkg-config --cflags gtk+-2.0` +LINKFLAGS += `pkg-config --libs gtk+-2.0` #support for SELinux (optional) SELINUX_EXISTING=$(shell pkg-config --exists libselinux && echo YES) ifeq ($(SELINUX_EXISTING),YES) -FFS_CPPFLAGS += `pkg-config --cflags libselinux ` -DHAVE_SELINUX -LINKFLAGS += `pkg-config --libs libselinux` +CPPFLAGS += `pkg-config --cflags libselinux` -DHAVE_SELINUX +LINKFLAGS += `pkg-config --libs libselinux` endif #support for Ubuntu Unity (optional) UNITY_EXISTING=$(shell pkg-config --exists unity && echo YES) ifeq ($(UNITY_EXISTING),YES) -FFS_CPPFLAGS += `pkg-config --cflags unity` -DHAVE_UBUNTU_UNITY -LINKFLAGS += `pkg-config --libs unity` +CPPFLAGS += `pkg-config --cflags unity` -DHAVE_UBUNTU_UNITY +LINKFLAGS += `pkg-config --libs unity` endif CPP_LIST= #internal list of all *.cpp files needed for compilation @@ -67,7 +66,6 @@ CPP_LIST+=ui/tray_icon.cpp CPP_LIST+=lib/binary.cpp CPP_LIST+=lib/db_file.cpp CPP_LIST+=lib/dir_lock.cpp -CPP_LIST+=lib/error_log.cpp CPP_LIST+=lib/hard_filter.cpp CPP_LIST+=lib/icon_buffer.cpp CPP_LIST+=lib/localization.cpp @@ -97,7 +95,7 @@ all: FreeFileSync OBJ/FFS_Release_GCC_Make/%.o : %.cpp mkdir -p $(dir $@) - g++ $(FFS_CPPFLAGS) -c $< -o $@ + g++ $(CPPFLAGS) -c $< -o $@ FreeFileSync: $(OBJECT_LIST) g++ -o ./BUILD/$(APPNAME) $(OBJECT_LIST) $(LINKFLAGS) diff --git a/RealtimeSync/RealtimeSync.cbp b/RealtimeSync/RealtimeSync.cbp index 2b1b97b7..e1b46812 100644 --- a/RealtimeSync/RealtimeSync.cbp +++ b/RealtimeSync/RealtimeSync.cbp @@ -27,9 +27,12 @@ <Add library="libwxbase28u.a" /> <Add library="libwxpng.a" /> <Add library="libwxzlib.a" /> - <Add library="libboost_thread-mgw46-mt-s-1_48.a" /> + <Add library="libboost_thread-mgw46-mt-s-1_49.a" /> <Add directory="C:\Programme\C++\wxWidgets\lib\gcc_lib" /> </Linker> + <ExtraCommands> + <Add after='"C:\Program Files\C++\CodeSigning\SignCode.cmd" "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)"' /> + </ExtraCommands> </Target> <Target title="Debug-DLL"> <Option output="..\BUILD\Bin\RealtimeSync_Debug" prefix_auto="1" extension_auto="1" /> @@ -51,7 +54,7 @@ <Add library="libwxbase28ud.a" /> <Add library="libwxpngd.a" /> <Add library="libwxzlibd.a" /> - <Add library="libboost_thread-mgw46-mt-sd-1_48.a" /> + <Add library="libboost_thread-mgw46-mt-sd-1_49.a" /> <Add directory="C:\Program Files\C++\wxWidgets\lib\gcc_dll" /> </Linker> </Target> @@ -99,26 +102,6 @@ <Add library="libuxtheme.a" /> <Add directory="C:\Program Files\C++\Boost\stage\lib" /> </Linker> - <Unit filename="WxWizDialog.fbp" /> - <Unit filename="application.cpp" /> - <Unit filename="application.h" /> - <Unit filename="gui_generated.cpp" /> - <Unit filename="gui_generated.h" /> - <Unit filename="main_dlg.cpp" /> - <Unit filename="main_dlg.h" /> - <Unit filename="resource.rc"> - <Option compilerVar="WINDRES" /> - </Unit> - <Unit filename="resources.cpp" /> - <Unit filename="resources.h" /> - <Unit filename="tray_menu.cpp" /> - <Unit filename="tray_menu.h" /> - <Unit filename="watcher.cpp" /> - <Unit filename="watcher.h" /> - <Unit filename="xml_ffs.cpp" /> - <Unit filename="xml_ffs.h" /> - <Unit filename="xml_proc.cpp" /> - <Unit filename="xml_proc.h" /> <Unit filename="..\lib\localization.cpp" /> <Unit filename="..\lib\process_xml.cpp" /> <Unit filename="..\lib\resolve_path.cpp" /> @@ -144,6 +127,26 @@ <Unit filename="..\zen\notify_removal.cpp" /> <Unit filename="..\zen\privilege.cpp" /> <Unit filename="..\zen\zstring.cpp" /> + <Unit filename="WxWizDialog.fbp" /> + <Unit filename="application.cpp" /> + <Unit filename="application.h" /> + <Unit filename="gui_generated.cpp" /> + <Unit filename="gui_generated.h" /> + <Unit filename="main_dlg.cpp" /> + <Unit filename="main_dlg.h" /> + <Unit filename="resource.rc"> + <Option compilerVar="WINDRES" /> + </Unit> + <Unit filename="resources.cpp" /> + <Unit filename="resources.h" /> + <Unit filename="tray_menu.cpp" /> + <Unit filename="tray_menu.h" /> + <Unit filename="watcher.cpp" /> + <Unit filename="watcher.h" /> + <Unit filename="xml_ffs.cpp" /> + <Unit filename="xml_ffs.h" /> + <Unit filename="xml_proc.cpp" /> + <Unit filename="xml_proc.h" /> <Extensions> <code_completion /> <envvars /> diff --git a/RealtimeSync/RealtimeSync.vcxproj b/RealtimeSync/RealtimeSync.vcxproj index 46529d63..f115bac4 100644 --- a/RealtimeSync/RealtimeSync.vcxproj +++ b/RealtimeSync/RealtimeSync.vcxproj @@ -22,6 +22,7 @@ <ProjectGuid>{A80B97E9-807C-47A1-803A-27565A1BD526}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>RealtimeSync</RootNamespace> + <VCTargetsPath Condition="'$(VCTargetsPath11)' != '' and '$(VSVersion)' == '' and $(VisualStudioVersion) == ''">$(VCTargetsPath11)</VCTargetsPath> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> @@ -34,7 +35,7 @@ <ConfigurationType>Application</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v110</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> @@ -48,7 +49,7 @@ <UseDebugLibraries>false</UseDebugLibraries> <WholeProgramOptimization>true</WholeProgramOptimization> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v110</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> @@ -99,7 +100,7 @@ <PrecompiledHeader>Use</PrecompiledHeader> <WarningLevel>Level4</WarningLevel> <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WXUSINGDLL;ZEN_PLATFORM_WINDOWS;wxUSE_UNICODE;__WXMSW__;FFS_WIN;WXINTL_NO_GETTEXT_MACRO;__WXDEBUG__;</PreprocessorDefinitions> + <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;ZEN_PLATFORM_WINDOWS;wxUSE_UNICODE;__WXMSW__;FFS_WIN;WXINTL_NO_GETTEXT_MACRO;__WXDEBUG__;WXUSINGDLL</PreprocessorDefinitions> <AdditionalIncludeDirectories>..;C:\Program Files\C++\wxWidgets\include;C:\Program Files\C++\wxWidgets\lib\vc_dll\mswud;C:\Program Files\C++\Boost</AdditionalIncludeDirectories> <PrecompiledHeaderFile>wx+/pch.h</PrecompiledHeaderFile> <DisableSpecificWarnings>4100;4996;4267;4512</DisableSpecificWarnings> @@ -120,7 +121,7 @@ </LinkStatus> </Link> <ResourceCompile> - <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include;C:\Program Files\C++\wxWidgets\lib\vc_lib\mswud</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include</AdditionalIncludeDirectories> <PreprocessorDefinitions>%(PreprocessorDefinitions);</PreprocessorDefinitions> </ResourceCompile> </ItemDefinitionGroup> @@ -129,8 +130,8 @@ <PrecompiledHeader>Use</PrecompiledHeader> <WarningLevel>Level4</WarningLevel> <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WXUSINGDLL;ZEN_PLATFORM_WINDOWS;wxUSE_UNICODE;__WXMSW__;FFS_WIN;WXINTL_NO_GETTEXT_MACRO;__WXDEBUG__;</PreprocessorDefinitions> - <AdditionalIncludeDirectories>..;C:\Program Files\C++\wxWidgets-x64\include;C:\Program Files\C++\wxWidgets-x64\lib\vc_dll\mswud;C:\Program Files\C++\Boost</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;ZEN_PLATFORM_WINDOWS;wxUSE_UNICODE;__WXMSW__;FFS_WIN;WXINTL_NO_GETTEXT_MACRO;__WXDEBUG__;WXUSINGDLL</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..;C:\Program Files\C++\wxWidgets-x64-VC11\include;C:\Program Files\C++\wxWidgets-x64\lib\vc_dll\mswud;C:\Program Files\C++\Boost</AdditionalIncludeDirectories> <PrecompiledHeaderFile>wx+/pch.h</PrecompiledHeaderFile> <DisableSpecificWarnings>4100;4996;4267;4512</DisableSpecificWarnings> <MultiProcessorCompilation>false</MultiProcessorCompilation> @@ -146,12 +147,12 @@ <SuppressStartupBanner>true</SuppressStartupBanner> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <AdditionalDependencies>wxmsw28ud_adv.lib;wxmsw28ud_core.lib;wxbase28ud.lib;wxpngd.lib;wxzlibd.lib;wxbase28ud_net.lib;comctl32.lib;ws2_32.lib;Rpcrt4.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> - <AdditionalLibraryDirectories>C:\Program Files\C++\wxWidgets-x64\lib\vc_dll;C:\Program Files\C++\Boost\stage64\lib</AdditionalLibraryDirectories> + <AdditionalLibraryDirectories>C:\Program Files\C++\wxWidgets-x64-VC11\lib\vc_dll;C:\Program Files\C++\Boost\stage64\lib</AdditionalLibraryDirectories> <LinkStatus> </LinkStatus> </Link> <ResourceCompile> - <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include;C:\Program Files\C++\wxWidgets\lib\vc_lib\mswud</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets-x64-VC11\include</AdditionalIncludeDirectories> <PreprocessorDefinitions>%(PreprocessorDefinitions);WX_CPU_AMD64</PreprocessorDefinitions> </ResourceCompile> </ItemDefinitionGroup> @@ -162,7 +163,7 @@ <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>ZEN_PLATFORM_WINDOWS;wxUSE_UNICODE;__WXMSW__;FFS_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG</PreprocessorDefinitions> + <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;ZEN_PLATFORM_WINDOWS;wxUSE_UNICODE;__WXMSW__;FFS_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG</PreprocessorDefinitions> <AdditionalIncludeDirectories>..;C:\Program Files\C++\wxWidgets\include;C:\Program Files\C++\wxWidgets\lib\vc_lib\mswu;C:\Program Files\C++\Boost</AdditionalIncludeDirectories> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <DisableSpecificWarnings>4100;4996;4267;4512</DisableSpecificWarnings> @@ -182,13 +183,17 @@ <AdditionalLibraryDirectories>C:\Program Files\C++\wxWidgets\lib\vc_lib;C:\Program Files\C++\Boost\stage\lib</AdditionalLibraryDirectories> <LinkStatus> </LinkStatus> + <Profile>true</Profile> </Link> <ResourceCompile> - <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include;C:\Program Files\C++\wxWidgets\lib\vc_lib\mswu</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include</AdditionalIncludeDirectories> <PreprocessorDefinitions>%(PreprocessorDefinitions);</PreprocessorDefinitions> <Culture> </Culture> </ResourceCompile> + <PostBuildEvent> + <Command>"C:\Program Files\C++\CodeSigning\SignCode.cmd" "$(TargetPath)"</Command> + </PostBuildEvent> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> @@ -197,8 +202,8 @@ <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>ZEN_PLATFORM_WINDOWS;wxUSE_UNICODE;__WXMSW__;FFS_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG</PreprocessorDefinitions> - <AdditionalIncludeDirectories>..;C:\Program Files\C++\wxWidgets-x64\include;C:\Program Files\C++\wxWidgets-x64\lib\vc_lib\mswu;C:\Program Files\C++\Boost</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;ZEN_PLATFORM_WINDOWS;wxUSE_UNICODE;__WXMSW__;FFS_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..;C:\Program Files\C++\wxWidgets-x64-VC11\include;C:\Program Files\C++\wxWidgets-x64\lib\vc_lib\mswu;C:\Program Files\C++\Boost</AdditionalIncludeDirectories> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <DisableSpecificWarnings>4100;4996;4267;4512</DisableSpecificWarnings> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> @@ -215,16 +220,20 @@ <SuppressStartupBanner>true</SuppressStartupBanner> <AdditionalDependencies>wxmsw28u_adv.lib;wxmsw28u_core.lib;wxbase28u.lib;wxpng.lib;wxzlib.lib;wxbase28u_net.lib;comctl32.lib;ws2_32.lib;winmm.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <AdditionalLibraryDirectories>C:\Program Files\C++\wxWidgets-x64\lib\vc_lib;C:\Program Files\C++\Boost\stage64\lib</AdditionalLibraryDirectories> + <AdditionalLibraryDirectories>C:\Program Files\C++\wxWidgets-x64-VC11\lib\vc_lib;C:\Program Files\C++\Boost\stage64\lib</AdditionalLibraryDirectories> <LinkStatus> </LinkStatus> + <Profile>true</Profile> </Link> <ResourceCompile> - <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include;C:\Program Files\C++\wxWidgets\lib\vc_lib\mswu</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets-x64-VC11\include</AdditionalIncludeDirectories> <PreprocessorDefinitions>%(PreprocessorDefinitions);WX_CPU_AMD64</PreprocessorDefinitions> <Culture> </Culture> </ResourceCompile> + <PostBuildEvent> + <Command>"C:\Program Files\C++\CodeSigning\SignCode.cmd" "$(TargetPath)"</Command> + </PostBuildEvent> </ItemDefinitionGroup> <ItemGroup> <ClCompile Include="..\lib\localization.cpp" /> @@ -262,6 +271,7 @@ <ResourceCompile Include="resource.rc" /> </ItemGroup> <ItemGroup> + <None Include="ClassDiagram.cd" /> <None Include="WxWizDialog.fbp" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> diff --git a/RealtimeSync/application.cpp b/RealtimeSync/application.cpp index d45ae482..ead65eaa 100644 --- a/RealtimeSync/application.cpp +++ b/RealtimeSync/application.cpp @@ -33,7 +33,7 @@ bool Application::OnInit() //Note: initialization is done in the FIRST idle event instead of OnInit. Reason: Commandline mode requires the wxApp eventhandler to be established //for UI update events. This is not the case at the time of OnInit(). - Connect(wxEVT_IDLE, wxIdleEventHandler(Application::OnStartApplication), NULL, this); + Connect(wxEVT_IDLE, wxIdleEventHandler(Application::OnStartApplication), nullptr, this); return true; } @@ -41,7 +41,7 @@ bool Application::OnInit() void Application::OnStartApplication(wxIdleEvent& event) { - Disconnect(wxEVT_IDLE, wxIdleEventHandler(Application::OnStartApplication), NULL, this); + Disconnect(wxEVT_IDLE, wxIdleEventHandler(Application::OnStartApplication), nullptr, this); //if appname is not set, the default is the executable's name! SetAppName(wxT("FreeFileSync")); //use a different app name, to have "GetUserDataDir()" return the same directory as for FreeFileSync @@ -83,7 +83,7 @@ void Application::OnStartApplication(wxIdleEvent& event) if (!commandArgs.empty()) cfgFilename = commandArgs[0]; - MainDialog* frame = new MainDialog(NULL, cfgFilename); + MainDialog* frame = new MainDialog(nullptr, cfgFilename); frame->SetIcon(GlobalResources::instance().programIcon); //set application icon frame->Show(); } diff --git a/RealtimeSync/gui_generated.cpp b/RealtimeSync/gui_generated.cpp index f968c995..849915a4 100644 --- a/RealtimeSync/gui_generated.cpp +++ b/RealtimeSync/gui_generated.cpp @@ -1,13 +1,10 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Dec 2 2011) +// C++ code generated with wxFormBuilder (version Feb 9 2012) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! /////////////////////////////////////////////////////////////////////////// -#include "../wx+/button.h" -#include "../wx+/dir_picker.h" - #include "gui_generated.h" /////////////////////////////////////////////////////////////////////////// @@ -26,8 +23,7 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr m_menuItem13 = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("&Load configuration...") ) + wxT('\t') + wxT("CTRL+L"), wxEmptyString, wxITEM_NORMAL ); m_menuFile->Append( m_menuItem13 ); - wxMenuItem* m_separator1; - m_separator1 = m_menuFile->AppendSeparator(); + m_menuFile->AppendSeparator(); wxMenuItem* m_menuItem4; m_menuItem4 = new wxMenuItem( m_menuFile, wxID_EXIT, wxString( _("&Quit") ) + wxT('\t') + wxT("CTRL+Q"), wxEmptyString, wxITEM_NORMAL ); @@ -37,11 +33,10 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr m_menuHelp = new wxMenu(); wxMenuItem* m_menuItemContent; - m_menuItemContent = new wxMenuItem( m_menuHelp, wxID_ANY, wxString( _("&Content") ) + wxT('\t') + wxT("F1"), wxEmptyString, wxITEM_NORMAL ); + m_menuItemContent = new wxMenuItem( m_menuHelp, wxID_HELP, wxString( _("&Content") ) + wxT('\t') + wxT("F1"), wxEmptyString, wxITEM_NORMAL ); m_menuHelp->Append( m_menuItemContent ); - wxMenuItem* m_separator2; - m_separator2 = m_menuHelp->AppendSeparator(); + m_menuHelp->AppendSeparator(); m_menuItemAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( _("&About...") ) + wxT('\t') + wxT("SHIFT+F1"), wxEmptyString, wxITEM_NORMAL ); m_menuHelp->Append( m_menuItemAbout ); @@ -81,6 +76,7 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr m_staticText21->Wrap( -1 ); sbSizer41->Add( m_staticText21, 0, wxRIGHT|wxLEFT|wxEXPAND, 5 ); + bSizer1->Add( sbSizer41, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxRIGHT|wxLEFT, 20 ); m_staticline2 = new wxStaticLine( m_panelMain, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); @@ -102,6 +98,7 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr m_staticTextFinalPath->Wrap( -1 ); bSizer11->Add( m_staticTextFinalPath, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 2 ); + bSizer10->Add( bSizer11, 0, 0, 5 ); wxBoxSizer* bSizer781; @@ -125,8 +122,10 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr bSizer781->Add( m_dirPickerMain, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer10->Add( bSizer781, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + m_panelMainFolder->SetSizer( bSizer10 ); m_panelMainFolder->Layout(); bSizer10->Fit( m_panelMainFolder ); @@ -136,11 +135,13 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr m_scrolledWinFolders->SetScrollRate( 5, 5 ); bSizerFolders = new wxBoxSizer( wxVERTICAL ); + m_scrolledWinFolders->SetSizer( bSizerFolders ); m_scrolledWinFolders->Layout(); bSizerFolders->Fit( m_scrolledWinFolders ); sbSizerDirToWatch2->Add( m_scrolledWinFolders, 0, wxEXPAND, 5 ); + bSizer1->Add( sbSizerDirToWatch2, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); wxStaticBoxSizer* sbSizer3; @@ -149,6 +150,7 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr m_textCtrlCommand = new wxTextCtrl( m_panelMain, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); sbSizer3->Add( m_textCtrlCommand, 0, wxEXPAND|wxBOTTOM, 5 ); + bSizer1->Add( sbSizer3, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); wxStaticBoxSizer* sbSizer4; @@ -159,6 +161,7 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr sbSizer4->Add( m_spinCtrlDelay, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer1->Add( sbSizer4, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); m_buttonStart = new zen::BitmapButton( m_panelMain, wxID_ANY, _("Start"), wxDefaultPosition, wxSize( -1,40 ), 0 ); @@ -170,11 +173,13 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr m_buttonCancel = new wxButton( m_panelMain, wxID_CANCEL, _("dummy"), wxDefaultPosition, wxSize( 0,0 ), 0 ); bSizer1->Add( m_buttonCancel, 0, 0, 5 ); + m_panelMain->SetSizer( bSizer1 ); m_panelMain->Layout(); bSizer1->Fit( m_panelMain ); bSizerMain->Add( m_panelMain, 1, wxEXPAND, 5 ); + this->SetSizer( bSizerMain ); this->Layout(); bSizerMain->Fit( this ); @@ -199,7 +204,7 @@ MainDlgGenerated::~MainDlgGenerated() this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnSaveConfig ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnLoadConfig ) ); this->Disconnect( wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnQuit ) ); - this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnShowHelp ) ); + this->Disconnect( wxID_HELP, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnShowHelp ) ); this->Disconnect( wxID_ABOUT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnMenuAbout ) ); m_bpButtonAddFolder->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDlgGenerated::OnAddFolder ), NULL, this ); m_bpButtonRemoveTopFolder->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDlgGenerated::OnRemoveTopFolder ), NULL, this ); @@ -229,8 +234,10 @@ FolderGenerated::FolderGenerated( wxWindow* parent, wxWindowID id, const wxPoint bSizer20->Add( m_dirPicker, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer114->Add( bSizer20, 1, wxALIGN_CENTER_VERTICAL, 5 ); + this->SetSizer( bSizer114 ); this->Layout(); bSizer114->Fit( this ); diff --git a/RealtimeSync/gui_generated.h b/RealtimeSync/gui_generated.h index 2232fc67..aa0f5ad8 100644 --- a/RealtimeSync/gui_generated.h +++ b/RealtimeSync/gui_generated.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Dec 2 2011) +// C++ code generated with wxFormBuilder (version Feb 9 2012) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -11,9 +11,8 @@ #include <wx/artprov.h> #include <wx/xrc/xmlres.h> #include <wx/intl.h> -namespace zen { class BitmapButton; } -namespace zen { class DirPickerCtrl; } - +#include "../wx+/dir_picker.h" +#include "../wx+/button.h" #include <wx/string.h> #include <wx/bitmap.h> #include <wx/image.h> diff --git a/RealtimeSync/main_dlg.cpp b/RealtimeSync/main_dlg.cpp index 3b40236a..c91e4856 100644 --- a/RealtimeSync/main_dlg.cpp +++ b/RealtimeSync/main_dlg.cpp @@ -39,7 +39,7 @@ MainDialog::MainDialog(wxDialog* dlg, const wxString& cfgFileName) m_buttonStart ->setBitmapFront(GlobalResources::getImage(L"startRed")); //register key event - Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(MainDialog::OnKeyPressed), NULL, this); + Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(MainDialog::OnKeyPressed), nullptr, this); //prepare drag & drop dirNameFirst.reset(new DirectoryName<wxTextCtrl>(*m_panelMainFolder, *m_dirPickerMain, *m_txtCtrlDirectoryMain, m_staticTextFinalPath)); @@ -401,7 +401,7 @@ void MainDialog::addFolder(const std::vector<wxString>& newFolders, bool addFron } //register events - newFolder->m_bpButtonRemoveFolder->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainDialog::OnRemoveFolder), NULL, this ); + newFolder->m_bpButtonRemoveFolder->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainDialog::OnRemoveFolder), nullptr, this ); //insert directory name newFolder->setName(*i); diff --git a/RealtimeSync/makefile b/RealtimeSync/makefile index 0dc2d8af..c92e2052 100644 --- a/RealtimeSync/makefile +++ b/RealtimeSync/makefile @@ -2,18 +2,23 @@ APPNAME = RealtimeSync prefix = /usr BINDIR = $(DESTDIR)$(prefix)/bin -COMMON_COMPILE_FLAGS = -Wall -pipe `pkg-config --cflags gtk+-2.0` -O3 -pthread -std=gnu++0x -DNDEBUG -DwxUSE_UNICODE -DFFS_LINUX -DZEN_PLATFORM_OTHER -DWXINTL_NO_GETTEXT_MACRO -I.. -include "../zen/i18n.h" -COMMON_LINK_FLAGS = -O3 -pthread +COMMON_COMPILE_FLAGS = -Wall -pipe -O3 -pthread -std=gnu++0x -DNDEBUG -DwxUSE_UNICODE -DFFS_LINUX -DZEN_PLATFORM_OTHER -DWXINTL_NO_GETTEXT_MACRO -I.. -include "../zen/i18n.h" +COMMON_LINK_FLAGS = -pthread #default build -FFS_CPPFLAGS = $(COMMON_COMPILE_FLAGS) `wx-config --cxxflags --debug=no --unicode=yes` -LINKFLAGS = $(COMMON_LINK_FLAGS) `wx-config --libs --debug=no --unicode=yes` -lboost_thread +CPPFLAGS = $(COMMON_COMPILE_FLAGS) `wx-config --cxxflags --debug=no --unicode=yes` +LINKFLAGS = $(COMMON_LINK_FLAGS) `wx-config --libs --debug=no --unicode=yes` -lboost_thread #static std library linkage used for precompiled release ifeq ($(BUILD),release) -FFS_CPPFLAGS = $(COMMON_COMPILE_FLAGS) `wx-config --cxxflags --debug=no --unicode=yes --static=yes` -LINKFLAGS = $(COMMON_LINK_FLAGS) `wx-config --libs --debug=no --unicode=yes --static=yes` /usr/local/lib/libboost_thread.a +CPPFLAGS = $(COMMON_COMPILE_FLAGS) `wx-config --cxxflags --debug=no --unicode=yes --static=yes` +LINKFLAGS = $(COMMON_LINK_FLAGS) `wx-config --libs --debug=no --unicode=yes --static=yes` /usr/local/lib/libboost_thread.a endif +##################################################################################################### + +#Gtk - no button border +CPPFLAGS += `pkg-config --cflags gtk+-2.0` +LINKFLAGS += `pkg-config --libs gtk+-2.0` CPP_LIST= #internal list of all *.cpp files needed for compilation CPP_LIST+=application.cpp @@ -46,7 +51,7 @@ all: RealtimeSync ../OBJ/RTS_Release_GCC_Make/RTS/%.o : %.cpp mkdir -p $(dir $@) - g++ $(FFS_CPPFLAGS) -c $< -o $@ + g++ $(CPPFLAGS) -c $< -o $@ RealtimeSync: $(OBJECT_LIST) g++ -o ../BUILD/$(APPNAME) $(OBJECT_LIST) $(LINKFLAGS) diff --git a/RealtimeSync/resource.rc b/RealtimeSync/resource.rc index dcdb6ad1..bad326e1 100644 --- a/RealtimeSync/resource.rc +++ b/RealtimeSync/resource.rc @@ -16,11 +16,11 @@ BEGIN BEGIN BLOCK "FFFF04B0" BEGIN - VALUE "FileDescription", "Realtime Application Launcher\0" + VALUE "FileDescription", "Real-time Command Line Launcher\0" VALUE "FileVersion", VER_FREEFILESYNC_STR VALUE "ProductName", "RealtimeSync\0" VALUE "ProductVersion", VER_FREEFILESYNC_STR - VALUE "LegalCopyright", "(c) 2008 - 2011 ZenJu\0" + VALUE "LegalCopyright", "ZenJu - All Rights Reserved\0" END END BLOCK "VarFileInfo" diff --git a/RealtimeSync/resources.cpp b/RealtimeSync/resources.cpp index 41e16808..f81af50a 100644 --- a/RealtimeSync/resources.cpp +++ b/RealtimeSync/resources.cpp @@ -29,12 +29,13 @@ GlobalResources::GlobalResources() //activate support for .png files wxImage::AddHandler(new wxPNGHandler); //ownership passed - wxZipInputStream resourceFile(input); + wxZipInputStream resourceFile(input, wxConvUTF8); + //do NOT rely on wxConvLocal! May result in "Cannot convert from the charset 'Unknown encoding (-1)'!" while (true) { std::unique_ptr<wxZipEntry> entry(resourceFile.GetNextEntry()); - if (entry.get() == NULL) + if (entry.get() == nullptr) break; const wxString name = entry->GetName(); diff --git a/RealtimeSync/tray_menu.cpp b/RealtimeSync/tray_menu.cpp index c8eccbf5..e18101e0 100644 --- a/RealtimeSync/tray_menu.cpp +++ b/RealtimeSync/tray_menu.cpp @@ -76,14 +76,14 @@ public: void parentHasDied() //call before tray icon is marked for deferred deletion { - parent_ = NULL; + parent_ = nullptr; } private: virtual wxMenu* CreatePopupMenu() { if (!parent_) - return NULL; + return nullptr; wxMenu* contextMenu = new wxMenu; contextMenu->Append(CONTEXT_RESTORE, _("&Restore")); @@ -91,7 +91,7 @@ private: contextMenu->AppendSeparator(); contextMenu->Append(CONTEXT_ABORT, _("&Exit")); //event handling - contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TrayIconHolder::OnContextMenuSelection), NULL, parent_); + contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TrayIconHolder::OnContextMenuSelection), nullptr, parent_); return contextMenu; //ownership transferred to caller } @@ -127,13 +127,13 @@ TrayIconHolder::TrayIconHolder(const wxString& jobname) : showIconActive(); //register double-click - trayMenu->Connect(wxEVT_TASKBAR_LEFT_DCLICK, wxCommandEventHandler(TrayIconHolder::OnRequestResume), NULL, this); + trayMenu->Connect(wxEVT_TASKBAR_LEFT_DCLICK, wxCommandEventHandler(TrayIconHolder::OnRequestResume), nullptr, this); } TrayIconHolder::~TrayIconHolder() { - trayMenu->Disconnect(wxEVT_TASKBAR_LEFT_DCLICK, wxCommandEventHandler(TrayIconHolder::OnRequestResume), NULL, this); + trayMenu->Disconnect(wxEVT_TASKBAR_LEFT_DCLICK, wxCommandEventHandler(TrayIconHolder::OnRequestResume), nullptr, this); trayMenu->RemoveIcon(); //(try to) hide icon until final deletion takes place trayMenu->parentHasDied(); @@ -200,7 +200,7 @@ void TrayIconHolder::OnContextMenuSelection(wxCommandEvent& event) wxString buildFormatted = _("(Build: %x)"); buildFormatted.Replace(wxT("%x"), build); - wxMessageDialog aboutDlg(NULL, wxString(wxT("RealtimeSync")) + wxT("\n\n") + buildFormatted, _("About"), wxOK); + wxMessageDialog aboutDlg(nullptr, wxString(wxT("RealtimeSync")) + wxT("\n\n") + buildFormatted, _("About"), wxOK); aboutDlg.ShowModal(); } break; diff --git a/RealtimeSync/xml_proc.cpp b/RealtimeSync/xml_proc.cpp index df50d569..4f9306d2 100644 --- a/RealtimeSync/xml_proc.cpp +++ b/RealtimeSync/xml_proc.cpp @@ -29,10 +29,7 @@ bool isXmlTypeRTS(const XmlDoc& doc) //throw() { std::string type; if (doc.root().getAttribute("XmlType", type)) - { - if (type == "REAL") - return true; - } + return type == "REAL"; } return false; } @@ -54,7 +51,7 @@ void xmlAccess::readRealConfig(const wxString& filename, XmlRealConfig& config) ::readConfig(in, config); if (in.errorsOccured()) - throw FfsXmlError(_("Error parsing configuration file:") + L"\n\"" + toZ(filename) + L"\"\n\n" + + throw FfsXmlError(_("Configuration loaded partially only:") + L"\n\"" + toZ(filename) + L"\"\n\n" + getErrorMessageFormatted(in), FfsXmlError::WARNING); } diff --git a/algorithm.cpp b/algorithm.cpp index 77704bfc..3d440bb0 100644 --- a/algorithm.cpp +++ b/algorithm.cpp @@ -5,6 +5,7 @@ // ************************************************************************** #include "algorithm.h" +#include <set> #include <iterator> #include <stdexcept> #include <tuple> @@ -151,42 +152,30 @@ private: //--------------------------------------------------------------------------------------------------------------- -class HaveNonEqual //test if non-equal items exist in scanned data +struct AllEqual //test if non-equal items exist in scanned data { -public: bool operator()(const HierarchyObject& hierObj) const { - return std::find_if(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), - [](const FileMapping& fileObj) - { - return fileObj.getCategory() != FILE_EQUAL; - }) != hierObj.refSubFiles().end() || //files + return std::all_of(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), + [](const FileMapping& fileObj) { return fileObj.getCategory() == FILE_EQUAL; }) && //files - std::find_if(hierObj.refSubLinks().begin(), hierObj.refSubLinks().end(), - [](const SymLinkMapping& linkObj) - { - return linkObj.getLinkCategory() != SYMLINK_EQUAL; - }) != hierObj.refSubLinks().end() || //symlinks + std::all_of(hierObj.refSubLinks().begin(), hierObj.refSubLinks().end(), + [](const SymLinkMapping& linkObj) { return linkObj.getLinkCategory() == SYMLINK_EQUAL; }) && //symlinks - std::find_if(hierObj.refSubDirs(). begin(), hierObj.refSubDirs(). end(), - [](const DirMapping& dirObj) -> bool + std::all_of(hierObj.refSubDirs(). begin(), hierObj.refSubDirs(). end(), + [](const DirMapping& dirObj) -> bool { if (dirObj.getDirCategory() != DIR_EQUAL) - return true; - return HaveNonEqual()(dirObj); //recursion - }) != hierObj.refSubDirs ().end(); //directories + return false; + return AllEqual()(dirObj); //recurse + }); //directories } }; -bool allElementsEqual(const BaseDirMapping& baseMap) -{ - return !HaveNonEqual()(baseMap); -} - bool zen::allElementsEqual(const FolderComparison& folderCmp) { - return std::find_if(begin(folderCmp), end(folderCmp), HaveNonEqual()) == end(folderCmp); + return std::all_of(begin(folderCmp), end(folderCmp), AllEqual()); } //--------------------------------------------------------------------------------------------------------------- @@ -412,13 +401,13 @@ private: txtLastSyncFail (_("Cannot determine sync-direction:") + L" \n" + _("The file was not processed by last synchronization!")), reportWarning_(reportWarning) { - if (allElementsEqual(baseDirectory)) //nothing to do: abort and don't show any nag-screens + if (AllEqual()(baseDirectory)) //nothing to do: abort and don't show any nag-screens return; //try to load sync-database files std::pair<DirInfoPtr, DirInfoPtr> dirInfo = loadDBFile(baseDirectory); - if (dirInfo.first.get() == NULL || - dirInfo.second.get() == NULL) + if (dirInfo.first.get() == nullptr || + dirInfo.second.get() == nullptr) { //set conservative "two-way" directions DirectionSet twoWayCfg = getTwoWaySet(); @@ -464,7 +453,7 @@ private: } */ - std::pair<DirInfoPtr, DirInfoPtr> loadDBFile(const BaseDirMapping& baseDirectory) //return NULL on failure + std::pair<DirInfoPtr, DirInfoPtr> loadDBFile(const BaseDirMapping& baseDirectory) //return nullptr on failure { try { @@ -476,7 +465,7 @@ private: reportWarning_(error.toString() + L" \n\n" + _("Setting default synchronization directions: Old files will be overwritten with newer files.")); } - return std::pair<DirInfoPtr, DirInfoPtr>(); //NULL + return std::pair<DirInfoPtr, DirInfoPtr>(); } /* @@ -491,8 +480,8 @@ private: bool filterDirConflictFound(const Zstring& relativeName) const { //if filtering would have excluded directory during database creation, then we can't say anything about its former state - return (dbFilterLeft && !dbFilterLeft ->passDirFilter(relativeName, NULL)) || - (dbFilterRight && !dbFilterRight->passDirFilter(relativeName, NULL)); + return (dbFilterLeft && !dbFilterLeft ->passDirFilter(relativeName, nullptr)) || + (dbFilterRight && !dbFilterRight->passDirFilter(relativeName, nullptr)); } */ @@ -868,6 +857,10 @@ private: file ID, size, date | | \|/ X Y + + FAT caveat: File Ids are generally not stable when file is either moved or renamed! + => 1. Move/rename operations on FAT cannot be detected. + => 2. database generally contains wrong file ID on FAT after renaming from .ffs_tmp files => correct file Ids in database after next sync */ }; @@ -1166,7 +1159,7 @@ private: else { //the only case with partially unclear semantics: - //file and time filters may match on one side, leaving a total of 16 combinations for both sides! + //file and time filters may match or not match on each side, leaving a total of 16 combinations for both sides! /* ST S T - ST := match size and time --------- S := match size only @@ -1563,7 +1556,7 @@ void zen::deleteFromGridAndHD(const std::vector<FileSystemObject*>& rowsToDelete //last step: cleanup empty rows: this one invalidates all pointers! std::for_each(begin(folderCmp), end(folderCmp), BaseDirMapping::removeEmpty); }; - ZEN_ON_BLOCK_EXIT(updateDirection()); //MSVC: assert is a macro and it doesn't play nice with ZEN_ON_BLOCK_EXIT, surprise... wasn't there something about macros being "evil"? + ZEN_ON_SCOPE_EXIT(updateDirection()); //MSVC: assert is a macro and it doesn't play nice with ZEN_ON_SCOPE_EXIT, surprise... wasn't there something about macros being "evil"? deleteFromGridAndHDOneSide<LEFT_SIDE>(deleteLeft.begin(), deleteLeft.end(), useRecycleBin, diff --git a/comparison.cpp b/comparison.cpp index 16ddaa72..15cd25fb 100644 --- a/comparison.cpp +++ b/comparison.cpp @@ -6,6 +6,8 @@ #include "comparison.h" #include <stdexcept> +#include <numeric> +#include <zen/perf.h> #include <zen/scope_guard.h> #include <wx+/string_conv.h> #include <wx+/format_unit.h> @@ -15,10 +17,7 @@ #include "lib/binary.h" #include "lib/cmp_filetime.h" #include "algorithm.h" - -#ifdef FFS_WIN -#include <zen/perf.h> -#endif +#include "lib/status_handler_impl.h" using namespace zen; @@ -71,50 +70,33 @@ void checkForIncompleteInput(const std::vector<FolderPairCfg>& folderPairsForm, }); //check for empty entries - if ((totallyFilledPairs + partiallyFilledPairs == 0) || //all empty - (partiallyFilledPairs > 0 && //partial entry is invalid - !(totallyFilledPairs == 0 && partiallyFilledPairs == 1))) //exception: one partial pair okay: one-dir only scenario + tryReportingError([&] { - while (true) - { - const std::wstring additionalInfo = _("You can ignore this error to consider the directory as empty."); - const ProcessCallback::Response rv = procCallback.reportError(_("A directory input field is empty.") + L" \n\n" + - + L"(" + additionalInfo + L")"); - if (rv == ProcessCallback::IGNORE_ERROR) - break; - else if (rv == ProcessCallback::RETRY) - ; //continue with loop - else - throw std::logic_error("Programming Error: Unknown return value! (1)"); - } - } + if ((totallyFilledPairs + partiallyFilledPairs == 0) || //all empty + (partiallyFilledPairs > 0 && //partial entry is invalid + !(totallyFilledPairs == 0 && partiallyFilledPairs == 1))) //exception: one partial pair okay: one-dir only scenario + throw FileError(_("A directory input field is empty.") + L" \n\n" + + _("You can ignore this error to consider the directory as empty.")); + }, procCallback); } -void checkDirectoryExistence(const std::set<Zstring, LessFilename>& dirnames, - std::set<Zstring, LessFilename>& dirnamesExisting, - bool allowUserInteraction, - ProcessCallback& procCallback) +void determineExistentDirs(const std::set<Zstring, LessFilename>& dirnames, + std::set<Zstring, LessFilename>& dirnamesExisting, + bool allowUserInteraction, + ProcessCallback& procCallback) { std::for_each(dirnames.begin(), dirnames.end(), [&](const Zstring& dirname) { if (!dirname.empty()) { - while (!dirExistsUpdating(dirname, allowUserInteraction, procCallback)) - { - const std::wstring additionalInfo = _("You can ignore this error to consider the directory as empty."); - std::wstring errorMessage = _("Directory does not exist:") + L"\n" + L"\"" + dirname + L"\""; - ProcessCallback::Response rv = procCallback.reportError(errorMessage + L"\n\n" + additionalInfo /* + L" " + getLastErrorFormatted()*/); - - if (rv == ProcessCallback::IGNORE_ERROR) - return; - else if (rv == ProcessCallback::RETRY) - ; //continue with loop - else - throw std::logic_error("Programming Error: Unknown return value! (2)"); - } - + if (tryReportingError([&] + { + if (!dirExistsUpdating(dirname, allowUserInteraction, procCallback)) + throw FileError(_("Directory does not exist:") + L"\n" + L"\"" + dirname + L"\"" + L" \n\n" + + _("You can ignore this error to consider the directory as empty.")); + }, procCallback)) dirnamesExisting.insert(dirname); } }); @@ -178,12 +160,12 @@ private: }; -bool filesHaveSameContentUpdating(const Zstring& filename1, const Zstring& filename2, UInt64 totalBytesToCmp, ProcessCallback& pc) +bool filesHaveSameContentUpdating(const Zstring& filename1, const Zstring& filename2, UInt64 totalBytesToCmp, ProcessCallback& pc) //throw FileError { UInt64 bytesReported; //amount of bytes that have been compared and communicated to status handler //in error situation: undo communication of processed amount of data - zen::ScopeGuard guardStatistics = zen::makeGuard([&]() { pc.updateProcessedData(0, -1 * to<Int64>(bytesReported)); }); + zen::ScopeGuard guardStatistics = zen::makeGuard([&] { pc.updateProcessedData(0, -1 * to<Int64>(bytesReported)); }); CmpCallbackImpl callback(pc, bytesReported); bool sameContent = filesHaveSameContent(filename1, filename2, callback); //throw FileError @@ -245,7 +227,7 @@ void CompareProcess::startCompareProcess(const std::vector<FolderPairCfg>& cfgLi dirnames.insert(fpCfg.leftDirectoryFmt); dirnames.insert(fpCfg.rightDirectoryFmt); }); - checkDirectoryExistence(dirnames, dirnamesExisting, allowUserInteraction_, procCallback); + determineExistentDirs(dirnames, dirnamesExisting, allowUserInteraction_, procCallback); } auto dirAvailable = [&](const Zstring& dirnameFmt) { return dirnamesExisting.find(dirnameFmt) != dirnamesExisting.end(); }; @@ -363,7 +345,7 @@ void CompareProcess::startCompareProcess(const std::vector<FolderPairCfg>& cfgLi } catch (const std::bad_alloc& e) { - procCallback.reportFatalError(_("Memory allocation failed!") + L" " + utf8CvrtTo<std::wstring>(e.what())); + procCallback.reportFatalError(_("Out of memory!") + L" " + utf8CvrtTo<std::wstring>(e.what())); } catch (const std::exception& e) { @@ -515,17 +497,6 @@ void CompareProcess::compareByTimeSize(const FolderPairCfg& fpConfig, BaseDirMap } -UInt64 getBytesToCompare(const std::vector<FileMapping*>& rowsToCompare) -{ - UInt64 dataTotal; - - for (auto j = rowsToCompare.begin(); j != rowsToCompare.end(); ++j) - dataTotal += (*j)->getFileSize<LEFT_SIDE>(); //left and right filesizes should be the same - - return dataTotal * 2U; -} - - void CompareProcess::categorizeSymlinkByContent(SymLinkMapping& linkObj) const { //categorize symlinks that exist on both sides @@ -587,7 +558,9 @@ void CompareProcess::compareByContent(std::vector<std::pair<FolderPairCfg, BaseD }); const size_t objectsTotal = filesToCompareBytewise.size() * 2; - const UInt64 bytesTotal = getBytesToCompare(filesToCompareBytewise); + const UInt64 bytesTotal = //left and right filesizes should be the same + 2U * std::accumulate(filesToCompareBytewise.begin(), filesToCompareBytewise.end(), static_cast<UInt64>(0), + [](UInt64 sum, FileMapping* fsObj) { return sum + fsObj->getFileSize<LEFT_SIDE>(); }); procCallback.initNewProcess(static_cast<int>(objectsTotal), to<Int64>(bytesTotal), @@ -604,44 +577,29 @@ void CompareProcess::compareByContent(std::vector<std::pair<FolderPairCfg, BaseD procCallback.reportStatus(replaceCpy(txtComparingContentOfFiles, L"%x", utf8CvrtTo<std::wstring>(fileObj->getRelativeName<LEFT_SIDE>()), false)); //check files that exist in left and right model but have different content - while (true) - { - try - { - if (filesHaveSameContentUpdating(fileObj->getFullName<LEFT_SIDE>(), - fileObj->getFullName<RIGHT_SIDE>(), - fileObj->getFileSize<LEFT_SIDE>() * 2U, - procCallback)) - { - if (fileObj->getShortName<LEFT_SIDE>() == fileObj->getShortName<RIGHT_SIDE>() && - timeCmp.getResult(fileObj->getLastWriteTime<LEFT_SIDE>(), - fileObj->getLastWriteTime<RIGHT_SIDE>()) == CmpFileTime::TIME_EQUAL) - fileObj->setCategory<FILE_EQUAL>(); - else - fileObj->setCategory<FILE_DIFFERENT_METADATA>(); - } - else - fileObj->setCategory<FILE_DIFFERENT>(); - procCallback.updateProcessedData(2, 0); //processed data is communicated in subfunctions! - procCallback.requestUiRefresh(); //may throw - break; - } - catch (FileError& error) + if (!tryReportingError([&] + { + if (filesHaveSameContentUpdating(fileObj->getFullName<LEFT_SIDE>(), //throw FileError + fileObj->getFullName<RIGHT_SIDE>(), + fileObj->getFileSize<LEFT_SIDE>() * 2U, + procCallback)) { - ProcessCallback::Response rv = procCallback.reportError(error.toString()); - if (rv == ProcessCallback::IGNORE_ERROR) - { - fileObj->setCategoryConflict(_("Conflict detected:") + L"\n" + _("Comparing files by content failed.")); - break; - } - - else if (rv == ProcessCallback::RETRY) - ; //continue with loop + if (fileObj->getShortName<LEFT_SIDE>() == fileObj->getShortName<RIGHT_SIDE>() && + timeCmp.getResult(fileObj->getLastWriteTime<LEFT_SIDE>(), + fileObj->getLastWriteTime<RIGHT_SIDE>()) == CmpFileTime::TIME_EQUAL) + fileObj->setCategory<FILE_EQUAL>(); else - throw std::logic_error("Programming Error: Unknown return value!"); + fileObj->setCategory<FILE_DIFFERENT_METADATA>(); } - } + else + fileObj->setCategory<FILE_DIFFERENT>(); + + procCallback.updateProcessedData(2, 0); //processed data is communicated in subfunctions! + procCallback.requestUiRefresh(); //may throw + + }, procCallback)) + fileObj->setCategoryConflict(_("Conflict detected:") + L"\n" + _("Comparing files by content failed.")); }); } @@ -730,7 +688,7 @@ void MergeSides::execute(const DirContainer& leftSide, const DirContainer& right typedef const DirContainer::FileList::value_type FileData; linearMerge(leftSide.files, rightSide.files, - [&](const FileData& fileLeft) { output.addSubFile<LEFT_SIDE> (fileLeft.first, fileLeft.second); }, //left only + [&](const FileData& fileLeft ) { output.addSubFile<LEFT_SIDE >(fileLeft .first, fileLeft .second); }, //left only [&](const FileData& fileRight) { output.addSubFile<RIGHT_SIDE>(fileRight.first, fileRight.second); }, //right only [&](const FileData& fileLeft, const FileData& fileRight) //both sides @@ -792,7 +750,7 @@ void processFilteredDirs(HierarchyObject& hierObj, const HardFilter& filterProc) std::for_each(subDirs.begin(), subDirs.end(), [&](DirMapping& dirObj) { - dirObj.setActive(filterProc.passDirFilter(dirObj.getObjRelativeName(), NULL)); //subObjMightMatch is always true in this context! + dirObj.setActive(filterProc.passDirFilter(dirObj.getObjRelativeName(), nullptr)); //subObjMightMatch is always true in this context! processFilteredDirs(dirObj, filterProc); }); diff --git a/comparison.h b/comparison.h index 747f4230..28d666c7 100644 --- a/comparison.h +++ b/comparison.h @@ -10,7 +10,7 @@ #include <zen/process_status.h> #include "file_hierarchy.h" #include "lib/process_xml.h" -#include "lib/status_handler.h" +#include "process_callback.h" #include "structures.h" #include "lib/norm_filter.h" #include "lib/parallel_scan.h" diff --git a/file_hierarchy.cpp b/file_hierarchy.cpp index 769ad74f..f1bb7385 100644 --- a/file_hierarchy.cpp +++ b/file_hierarchy.cpp @@ -13,12 +13,12 @@ using namespace zen; void HierarchyObject::removeEmptyRec() { - bool haveEmpty = false; + bool emptyExisting = false; auto isEmpty = [&](const FileSystemObject& fsObj) -> bool { - bool objEmpty = fsObj.isEmpty(); + const bool objEmpty = fsObj.isEmpty(); if (objEmpty) - haveEmpty = true; + emptyExisting = true; return objEmpty; }; @@ -26,19 +26,20 @@ void HierarchyObject::removeEmptyRec() refSubLinks().remove_if(isEmpty); refSubDirs ().remove_if(isEmpty); - if (haveEmpty) //notify if actual deletion happened + if (emptyExisting) //notify if actual deletion happened notifySyncCfgChanged(); //mustn't call this in ~FileSystemObject(), since parent, usually a DirMapping, is already partially destroyed and existing as a pure HierarchyObject! - //recurse + // for (auto& subDir : refSubDirs()) + // subDir.removeEmptyRec(); //recurse std::for_each(refSubDirs().begin(), refSubDirs().end(), std::mem_fun_ref(&HierarchyObject::removeEmptyRec)); } namespace { -SyncOperation proposedSyncOperation(CompareFilesResult cmpResult, - bool selectedForSynchronization, - SyncDirection syncDir, - bool haveDirConflict) //perf: std::wstring was wasteful here +SyncOperation getIsolatedSyncOperation(CompareFilesResult cmpResult, + bool selectedForSynchronization, + SyncDirection syncDir, + bool hasDirConflict) //perf: std::wstring was wasteful here { if (!selectedForSynchronization) return cmpResult == FILE_EQUAL ? @@ -55,7 +56,7 @@ SyncOperation proposedSyncOperation(CompareFilesResult cmpResult, case SYNC_DIR_RIGHT: return SO_CREATE_NEW_RIGHT; //copy files to right case SYNC_DIR_NONE: - return haveDirConflict ? SO_UNRESOLVED_CONFLICT : SO_DO_NOTHING; + return hasDirConflict ? SO_UNRESOLVED_CONFLICT : SO_DO_NOTHING; } break; @@ -67,7 +68,7 @@ SyncOperation proposedSyncOperation(CompareFilesResult cmpResult, case SYNC_DIR_RIGHT: return SO_DELETE_RIGHT; //delete files on right case SYNC_DIR_NONE: - return haveDirConflict ? SO_UNRESOLVED_CONFLICT : SO_DO_NOTHING; + return hasDirConflict ? SO_UNRESOLVED_CONFLICT : SO_DO_NOTHING; } break; @@ -82,7 +83,7 @@ SyncOperation proposedSyncOperation(CompareFilesResult cmpResult, case SYNC_DIR_RIGHT: return SO_OVERWRITE_RIGHT; //copy from left to right case SYNC_DIR_NONE: - return haveDirConflict ? SO_UNRESOLVED_CONFLICT : SO_DO_NOTHING; + return hasDirConflict ? SO_UNRESOLVED_CONFLICT : SO_DO_NOTHING; } break; @@ -94,7 +95,7 @@ SyncOperation proposedSyncOperation(CompareFilesResult cmpResult, case SYNC_DIR_RIGHT: return SO_COPY_METADATA_TO_RIGHT; case SYNC_DIR_NONE: - return haveDirConflict ? SO_UNRESOLVED_CONFLICT : SO_DO_NOTHING; + return hasDirConflict ? SO_UNRESOLVED_CONFLICT : SO_DO_NOTHING; } break; @@ -103,6 +104,7 @@ SyncOperation proposedSyncOperation(CompareFilesResult cmpResult, return SO_EQUAL; } + assert(false); return SO_DO_NOTHING; //dummy } @@ -110,27 +112,27 @@ SyncOperation proposedSyncOperation(CompareFilesResult cmpResult, template <class Predicate> inline bool hasDirectChild(const HierarchyObject& hierObj, Predicate p) { - return std::find_if(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), p) != hierObj.refSubFiles().end() || - std::find_if(hierObj.refSubLinks().begin(), hierObj.refSubLinks().end(), p) != hierObj.refSubLinks().end() || - std::find_if(hierObj.refSubDirs(). begin(), hierObj.refSubDirs(). end(), p) != hierObj.refSubDirs ().end(); + return std::any_of(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), p) || + std::any_of(hierObj.refSubLinks().begin(), hierObj.refSubLinks().end(), p) || + std::any_of(hierObj.refSubDirs(). begin(), hierObj.refSubDirs(). end(), p); } } -SyncOperation FileSystemObject::testSyncOperation(SyncDirection testSyncDir, bool active) const +SyncOperation FileSystemObject::testSyncOperation(SyncDirection testSyncDir) const //semantics: "what if"! assumes "active, no conflict, no recursion (directory)! { - return proposedSyncOperation(getCategory(), active, testSyncDir, syncDirConflict.get() != NULL); + return getIsolatedSyncOperation(getCategory(), true, testSyncDir, false); } SyncOperation FileSystemObject::getSyncOperation() const { - return FileSystemObject::testSyncOperation(syncDir, selectedForSynchronization); - //no *not* make a virtual call to testSyncOperation()! See FileMapping::testSyncOperation()! + return getIsolatedSyncOperation(getCategory(), selectedForSynchronization, syncDir, syncDirConflict.get() != nullptr); + //no *not* make a virtual call to testSyncOperation()! See FileMapping::testSyncOperation()! <- better not implement one in terms of the other!!! } -//SyncOperation DirMapping::testSyncOperation() const -> not required: we do NOT want to consider child elements when testing! +//SyncOperation DirMapping::testSyncOperation() const -> no recursion: we do NOT want to consider child elements when testing! SyncOperation DirMapping::getSyncOperation() const @@ -163,80 +165,99 @@ SyncOperation DirMapping::getSyncOperation() const case SO_DELETE_RIGHT: case SO_DO_NOTHING: case SO_UNRESOLVED_CONFLICT: - { if (isEmpty<LEFT_SIDE>()) { //1. if at least one child-element is to be created, make sure parent folder is created also //note: this automatically fulfills "create parent folders even if excluded"; //see http://sourceforge.net/tracker/index.php?func=detail&aid=2628943&group_id=234430&atid=1093080 if (hasDirectChild(*this, - [](const FileSystemObject& fsObj) -> bool { const SyncOperation op = fsObj.getSyncOperation(); return op == SO_CREATE_NEW_LEFT || op == SO_MOVE_LEFT_TARGET; })) - syncOpBuffered = SO_CREATE_NEW_LEFT; + [](const FileSystemObject& fsObj) -> bool + { + const SyncOperation op = fsObj.getSyncOperation(); + return op == SO_CREATE_NEW_LEFT || + op == SO_MOVE_LEFT_TARGET; + })) + syncOpBuffered = SO_CREATE_NEW_LEFT; //2. cancel parent deletion if only a single child is not also scheduled for deletion else if (syncOpBuffered == SO_DELETE_RIGHT && hasDirectChild(*this, [](const FileSystemObject& fsObj) -> bool { - if (fsObj.isEmpty()) return false; //fsObj may already be empty because it once contained a "move source" - const SyncOperation op = fsObj.getSyncOperation(); return op != SO_DELETE_RIGHT && op != SO_MOVE_RIGHT_SOURCE; + if (fsObj.isEmpty()) + return false; //fsObj may already be empty because it once contained a "move source" + const SyncOperation op = fsObj.getSyncOperation(); + return op != SO_DELETE_RIGHT && + op != SO_MOVE_RIGHT_SOURCE; })) syncOpBuffered = SO_DO_NOTHING; } else if (isEmpty<RIGHT_SIDE>()) { if (hasDirectChild(*this, - [](const FileSystemObject& fsObj) -> bool { const SyncOperation op = fsObj.getSyncOperation(); return op == SO_CREATE_NEW_RIGHT || op == SO_MOVE_RIGHT_TARGET; })) - syncOpBuffered = SO_CREATE_NEW_RIGHT; + [](const FileSystemObject& fsObj) -> bool + { + const SyncOperation op = fsObj.getSyncOperation(); + return op == SO_CREATE_NEW_RIGHT || + op == SO_MOVE_RIGHT_TARGET; + })) + syncOpBuffered = SO_CREATE_NEW_RIGHT; else if (syncOpBuffered == SO_DELETE_LEFT && hasDirectChild(*this, [](const FileSystemObject& fsObj) -> bool { - if (fsObj.isEmpty()) return false; + if (fsObj.isEmpty()) + return false; const SyncOperation op = fsObj.getSyncOperation(); - return op != SO_DELETE_LEFT && op != SO_MOVE_LEFT_SOURCE; + return op != SO_DELETE_LEFT && + op != SO_MOVE_LEFT_SOURCE; })) syncOpBuffered = SO_DO_NOTHING; } - } - break; + break; } } return syncOpBuffered; } -SyncOperation FileMapping::testSyncOperation(SyncDirection testSyncDir, bool active) const +inline //it's private! +SyncOperation FileMapping::applyMoveOptimization(SyncOperation op) const { - SyncOperation op = FileSystemObject::testSyncOperation(testSyncDir, active); - /* check whether we can optimize "create + delete" via "move": note: as long as we consider "create + delete" cases only, detection of renamed files, should be fine even for "binary" comparison variant! */ - if (const FileSystemObject* refFile = dynamic_cast<const FileMapping*>(FileSystemObject::retrieve(moveFileRef))) //we expect a "FileMapping", but only need a "FileSystemObject" - { - SyncOperation opRef = refFile->FileSystemObject::getSyncOperation(); //do *not* make a virtual call! - - if (op == SO_CREATE_NEW_LEFT && - opRef == SO_DELETE_LEFT) - op = SO_MOVE_LEFT_TARGET; - else if (op == SO_DELETE_LEFT && - opRef == SO_CREATE_NEW_LEFT) - op = SO_MOVE_LEFT_SOURCE; - else if (op == SO_CREATE_NEW_RIGHT && - opRef == SO_DELETE_RIGHT) - op = SO_MOVE_RIGHT_TARGET; - else if (op == SO_DELETE_RIGHT && - opRef == SO_CREATE_NEW_RIGHT) - op = SO_MOVE_RIGHT_SOURCE; - } + if (moveFileRef) + if (auto refFile = dynamic_cast<const FileMapping*>(FileSystemObject::retrieve(moveFileRef))) //we expect a "FileMapping", but only need a "FileSystemObject" + { + SyncOperation opRef = refFile->FileSystemObject::getSyncOperation(); //do *not* make a virtual call! + + if (op == SO_CREATE_NEW_LEFT && + opRef == SO_DELETE_LEFT) + op = SO_MOVE_LEFT_TARGET; + else if (op == SO_DELETE_LEFT && + opRef == SO_CREATE_NEW_LEFT) + op = SO_MOVE_LEFT_SOURCE; + else if (op == SO_CREATE_NEW_RIGHT && + opRef == SO_DELETE_RIGHT) + op = SO_MOVE_RIGHT_TARGET; + else if (op == SO_DELETE_RIGHT && + opRef == SO_CREATE_NEW_RIGHT) + op = SO_MOVE_RIGHT_SOURCE; + } return op; } +SyncOperation FileMapping::testSyncOperation(SyncDirection testSyncDir) const +{ + return applyMoveOptimization(FileSystemObject::testSyncOperation(testSyncDir)); +} + + SyncOperation FileMapping::getSyncOperation() const { - return FileMapping::testSyncOperation(getSyncDir(), isActive()); + return applyMoveOptimization(FileSystemObject::getSyncOperation()); } diff --git a/file_hierarchy.h b/file_hierarchy.h index 5ad0a2a0..e41992a3 100644 --- a/file_hierarchy.h +++ b/file_hierarchy.h @@ -10,6 +10,7 @@ #include <map> #include <string> #include <memory> +#include <functional> #include <zen/zstring.h> #include <zen/fixed_list.h> #include <zen/stl_tools.h> @@ -310,10 +311,10 @@ public: ObjectIdConst getId() const { return this; } /**/ ObjectId getId() { return this; } - static const T* retrieve(ObjectIdConst id) //returns NULL if object is not valid anymore + static const T* retrieve(ObjectIdConst id) //returns nullptr if object is not valid anymore { auto iter = activeObjects().find(id); - return static_cast<const T*>(iter == activeObjects().end() ? NULL : *iter); + return static_cast<const T*>(iter == activeObjects().end() ? nullptr : *iter); } static T* retrieve(ObjectId id) { return const_cast<T*>(retrieve(static_cast<ObjectIdConst>(id))); } @@ -346,9 +347,9 @@ public: virtual CompareFilesResult getCategory() const = 0; virtual std::wstring getCatConflict() const = 0; //only filled if getCategory() == FILE_CONFLICT //sync operation - virtual SyncOperation testSyncOperation(SyncDirection testSyncDir, bool active) const; + virtual SyncOperation testSyncOperation(SyncDirection testSyncDir) const; //semantics: "what if"! assumes "active, no conflict, no recursion (directory)! virtual SyncOperation getSyncOperation() const; - std::wstring getSyncOpConflict() const; //return conflict when determining sync direction or during categorization + std::wstring getSyncOpConflict() const; //return conflict when determining sync direction or (still unresolved) conflict during categorization //sync settings void setSyncDir(SyncDirection newDir); @@ -382,7 +383,6 @@ protected: ~FileSystemObject() {} //don't need polymorphic deletion //mustn't call parent here, it is already partially destroyed and nothing more than a pure HierarchyObject! - virtual void flip(); virtual void notifySyncCfgChanged() { parent().notifySyncCfgChanged(); /*propagate!*/ } @@ -477,7 +477,7 @@ public: cmpResult(defaultCmpResult), dataLeft(left), dataRight(right), - moveFileRef(NULL) {} + moveFileRef(nullptr) {} template <SelectedSide side> Int64 getLastWriteTime() const; template <SelectedSide side> UInt64 getFileSize () const; @@ -485,21 +485,23 @@ public: template <SelectedSide side> const Zstring getExtension() const; void setMoveRef(ObjectId refId) { moveFileRef = refId; } //reference to corresponding renamed file - ObjectId getMoveRef() const { return moveFileRef; } //may be NULL + ObjectId getMoveRef() const { return moveFileRef; } //may be nullptr virtual CompareFilesResult getCategory() const; virtual std::wstring getCatConflict() const; - virtual SyncOperation testSyncOperation(SyncDirection testSyncDir, bool active) const; + virtual SyncOperation testSyncOperation(SyncDirection testSyncDir) const; //semantics: "what if"! assumes "active, no conflict, no recursion (directory)! virtual SyncOperation getSyncOperation() const; - template <SelectedSide side> void syncTo(const FileDescriptor& descrTarget, const FileDescriptor* descrSource = NULL); //copy + update file attributes (optional) + template <SelectedSide side> void syncTo(const FileDescriptor& descrTarget, const FileDescriptor* descrSource = nullptr); //copy + update file attributes (optional) private: template <CompareFilesResult res> void setCategory(); void setCategoryConflict(const std::wstring& description); + SyncOperation applyMoveOptimization(SyncOperation op) const; + virtual void flip(); virtual void removeObjectL(); virtual void removeObjectR(); @@ -512,7 +514,7 @@ private: FileDescriptor dataLeft; FileDescriptor dataRight; - ObjectId moveFileRef; + ObjectId moveFileRef; //optional, filled by redetermineSyncDirection() }; //------------------------------------------------------------------ @@ -1116,7 +1118,7 @@ void FileMapping::syncTo<LEFT_SIDE>(const FileDescriptor& descrTarget, const Fil if (descrSource) dataRight = *descrSource; - moveFileRef = NULL; + moveFileRef = nullptr; cmpResult = FILE_EQUAL; copyToL(); //copy FileSystemObject specific part } @@ -1129,7 +1131,7 @@ void FileMapping::syncTo<RIGHT_SIDE>(const FileDescriptor& descrTarget, const Fi if (descrSource) dataLeft = *descrSource; - moveFileRef = NULL; + moveFileRef = nullptr; cmpResult = FILE_EQUAL; copyToR(); //copy FileSystemObject specific part } diff --git a/lib/IFileOperation/file_op.cpp b/lib/IFileOperation/file_op.cpp index 8024ab91..3d7717f4 100644 --- a/lib/IFileOperation/file_op.cpp +++ b/lib/IFileOperation/file_op.cpp @@ -24,7 +24,7 @@ void moveToRecycleBin(const wchar_t* fileNames[], //throw ComError { ComPtr<IFileOperation> fileOp; ZEN_CHECK_COM(::CoCreateInstance(CLSID_FileOperation, //throw ComError - NULL, + nullptr, CLSCTX_ALL, IID_PPV_ARGS(fileOp.init()))); @@ -45,7 +45,7 @@ void moveToRecycleBin(const wchar_t* fileNames[], //throw ComError //create file/folder item object ComPtr<IShellItem> psiFile; HRESULT hr = ::SHCreateItemFromParsingName(fileNames[i], - NULL, + nullptr, IID_PPV_ARGS(psiFile.init())); if (FAILED(hr)) { @@ -55,7 +55,7 @@ void moveToRecycleBin(const wchar_t* fileNames[], //throw ComError throw ComError(std::wstring(L"Error calling \"SHCreateItemFromParsingName\" for file:\n") + L"\"" + fileNames[i] + L"\".", hr); } - ZEN_CHECK_COM(fileOp->DeleteItem(psiFile.get(), NULL)); + ZEN_CHECK_COM(fileOp->DeleteItem(psiFile.get(), nullptr)); ++operationCount; } @@ -80,7 +80,7 @@ void copyFile(const wchar_t* sourceFile, //throw ComError { ComPtr<IFileOperation> fileOp; ZEN_CHECK_COM(::CoCreateInstance(CLSID_FileOperation, //throw ComError - NULL, + nullptr, CLSCTX_ALL, IID_PPV_ARGS(fileOp.init()))); @@ -96,7 +96,7 @@ void copyFile(const wchar_t* sourceFile, //throw ComError ComPtr<IShellItem> psiSourceFile; { HRESULT hr = ::SHCreateItemFromParsingName(sourceFile, - NULL, + nullptr, IID_PPV_ARGS(psiSourceFile.init())); if (FAILED(hr)) throw ComError(std::wstring(L"Error calling \"SHCreateItemFromParsingName\" for file:\n") + L"\"" + sourceFile + L"\".", hr); @@ -113,14 +113,14 @@ void copyFile(const wchar_t* sourceFile, //throw ComError ComPtr<IShellItem> psiTargetFolder; { HRESULT hr = ::SHCreateItemFromParsingName(targetFolder.c_str(), - NULL, + nullptr, IID_PPV_ARGS(psiTargetFolder.init())); if (FAILED(hr)) throw ComError(std::wstring(L"Error calling \"SHCreateItemFromParsingName\" for folder:\n") + L"\"" + targetFolder + L"\".", hr); } //schedule file copy operation - ZEN_CHECK_COM(fileOp->CopyItem(psiSourceFile.get(), psiTargetFolder.get(), targetFileNameShort.c_str(), NULL)); + ZEN_CHECK_COM(fileOp->CopyItem(psiSourceFile.get(), psiTargetFolder.get(), targetFileNameShort.c_str(), nullptr)); //perform actual operations ZEN_CHECK_COM(fileOp->PerformOperations()); diff --git a/lib/ShadowCopy/LockFile.cpp b/lib/ShadowCopy/LockFile.cpp index 523b01bb..b9008863 100644 --- a/lib/ShadowCopy/LockFile.cpp +++ b/lib/ShadowCopy/LockFile.cpp @@ -24,10 +24,10 @@ int wmain(int argc, wchar_t* argv[]) HANDLE hFile = ::CreateFile(filename.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, + nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, - NULL); + nullptr); if (hFile == INVALID_HANDLE_VALUE) { std::wcout << "Error obtaining exclusive lock on test file: " << filename << "\n\n"; diff --git a/lib/ShadowCopy/shadow.cpp b/lib/ShadowCopy/shadow.cpp index fc95381d..bc27e2c3 100644 --- a/lib/ShadowCopy/shadow.cpp +++ b/lib/ShadowCopy/shadow.cpp @@ -110,7 +110,7 @@ shadow::ShadowData createShadowCopy(const wchar_t* volumeName) //throw ComError ZEN_CHECK_COM(fut.Wait()); HRESULT hr = S_OK; - ZEN_CHECK_COM(fut.QueryStatus(&hr, NULL)); //check if the async operation succeeded... + ZEN_CHECK_COM(fut.QueryStatus(&hr, nullptr)); //check if the async operation succeeded... if (FAILED(hr)) throw ComError(L"Error calling \"fut->QueryStatus\".", hr); }; @@ -151,7 +151,7 @@ shadow::ShadowData createShadowCopy(const wchar_t* volumeName) //throw ComError VSS_SNAPSHOT_PROP props = {}; ZEN_CHECK_COM(backupComp->GetSnapshotProperties(SnapShotId, &props)); - ZEN_ON_BLOCK_EXIT(::VssFreeSnapshotProperties(&props)); + ZEN_ON_SCOPE_EXIT(::VssFreeSnapshotProperties(&props)); //finally: write volume name of newly created shadow copy return shadow::ShadowData(backupComp, props.m_pwszSnapshotDeviceObject); diff --git a/lib/Thumbnail/thumbnail.cpp b/lib/Thumbnail/thumbnail.cpp index 050251de..0176f89b 100644 --- a/lib/Thumbnail/thumbnail.cpp +++ b/lib/Thumbnail/thumbnail.cpp @@ -31,59 +31,59 @@ thumb::HICON thumb::getThumbnail(const wchar_t* filename, int requestedSize) //r { HRESULT hr = ::SHGetDesktopFolder(shellFolder.init()); if (FAILED(hr) || !shellFolder) - return NULL; + return nullptr; } - PIDLIST_RELATIVE pidlFolder = NULL; + PIDLIST_RELATIVE pidlFolder = nullptr; { const std::wstring& pathName = beforeLast(filenameStr, '\\'); - HRESULT hr = shellFolder->ParseDisplayName(NULL, // [in] HWND hwnd, - NULL, // [in] IBindCtx *pbc, + HRESULT hr = shellFolder->ParseDisplayName(nullptr, // [in] HWND hwnd, + nullptr, // [in] IBindCtx *pbc, const_cast<LPWSTR>(pathName.c_str()), // [in] LPWSTR pszDisplayName, - NULL, // [out] ULONG *pchEaten, - &pidlFolder, // [out] PIDLIST_RELATIVE* ppidl, - NULL); // [in, out] ULONG *pdwAttributes + nullptr, // [out] ULONG *pchEaten, + &pidlFolder, // [out] PIDLIST_RELATIVE* ppidl, + nullptr); // [in, out] ULONG *pdwAttributes if (FAILED(hr) || !pidlFolder) - return NULL; + return nullptr; } - ZEN_ON_BLOCK_EXIT(::ILFree(pidlFolder)); //older version: ::CoTaskMemFree + ZEN_ON_SCOPE_EXIT(::ILFree(pidlFolder)); //older version: ::CoTaskMemFree ComPtr<IShellFolder> imageFolder; { HRESULT hr = shellFolder->BindToObject(pidlFolder, // [in] PCUIDLIST_RELATIVE pidl, - NULL, + nullptr, IID_PPV_ARGS(imageFolder.init())); if (FAILED(hr) || !imageFolder) - return NULL; + return nullptr; } - PIDLIST_RELATIVE pidImage = NULL; + PIDLIST_RELATIVE pidImage = nullptr; { const std::wstring& shortName = afterLast(filenameStr, '\\'); - HRESULT hr = imageFolder->ParseDisplayName(NULL, // [in] HWND hwnd, - NULL, // [in] IBindCtx *pbc, + HRESULT hr = imageFolder->ParseDisplayName(nullptr, // [in] HWND hwnd, + nullptr, // [in] IBindCtx *pbc, const_cast<LPWSTR>(shortName.c_str()), // [in] LPWSTR pszDisplayName, - NULL, // [out] ULONG *pchEaten, - &pidImage, // [out] PIDLIST_RELATIVE *ppidl, - NULL); // [in, out] ULONG *pdwAttributes + nullptr, // [out] ULONG *pchEaten, + &pidImage, // [out] PIDLIST_RELATIVE *ppidl, + nullptr); // [in, out] ULONG *pdwAttributes if (FAILED(hr) || !pidImage) - return NULL; + return nullptr; } - ZEN_ON_BLOCK_EXIT(::ILFree(pidImage)); //older version: ::CoTaskMemFree + ZEN_ON_SCOPE_EXIT(::ILFree(pidImage)); //older version: ::CoTaskMemFree ComPtr<IExtractImage> extractImage; { PCUITEMID_CHILD_ARRAY pidlIn = reinterpret_cast<PCUITEMID_CHILD_ARRAY>(&pidImage); //this is where STRICT_TYPED_ITEMIDS gets us ;) - HRESULT hr = imageFolder->GetUIObjectOf(NULL, // [in] HWND hwndOwner, + HRESULT hr = imageFolder->GetUIObjectOf(nullptr, // [in] HWND hwndOwner, 1, // [in] UINT cidl, pidlIn, // [in] PCUITEMID_CHILD_ARRAY apidl, IID_IExtractImage, // [in] REFIID riid, - NULL, // [in, out] UINT *rgfReserved, + nullptr, // [in, out] UINT *rgfReserved, reinterpret_cast<void**>(extractImage.init())); // [out] void **ppv if (FAILED(hr) || !extractImage) - return NULL; + return nullptr; } { @@ -100,28 +100,28 @@ thumb::HICON thumb::getThumbnail(const wchar_t* filename, int requestedSize) //r clrDepth, // [in] DWORD dwRecClrDepth, &flags); // [in, out] DWORD *pdwFlags if (FAILED(hr)) - return NULL; + return nullptr; } - HBITMAP bitmap = NULL; + HBITMAP bitmap = nullptr; { HRESULT hr = extractImage->Extract(&bitmap); if (FAILED(hr) || !bitmap) - return NULL; + return nullptr; } - ZEN_ON_BLOCK_EXIT(::DeleteObject(bitmap)); + ZEN_ON_SCOPE_EXIT(::DeleteObject(bitmap)); BITMAP bmpInfo = {}; if (::GetObject(bitmap, //__in HGDIOBJ hgdiobj, sizeof(bmpInfo), //__in int cbBuffer, &bmpInfo) == 0) //__out LPVOID lpvObject - return NULL; + return nullptr; - HBITMAP bitmapMask = ::CreateCompatibleBitmap(::GetDC(NULL), bmpInfo.bmWidth, bmpInfo.bmHeight); + HBITMAP bitmapMask = ::CreateCompatibleBitmap(::GetDC(nullptr), bmpInfo.bmWidth, bmpInfo.bmHeight); if (bitmapMask == 0) - return NULL; - ZEN_ON_BLOCK_EXIT(::DeleteObject(bitmapMask)); + return nullptr; + ZEN_ON_SCOPE_EXIT(::DeleteObject(bitmapMask)); ICONINFO iconInfo = {}; iconInfo.fIcon = true; @@ -141,7 +141,7 @@ thumb::HICON thumb::getIconByIndex(int iconIndex, int shilIconType) //return 0 o HRESULT hr = ::SHGetImageList(shilIconType, //__in int iImageList, IID_PPV_ARGS(imageList.init())); if (FAILED(hr) || !imageList) - return NULL; + return nullptr; } bool hasAlpha = false; //perf: 0,14 s @@ -153,7 +153,7 @@ thumb::HICON thumb::getIconByIndex(int iconIndex, int shilIconType) //return 0 o hasAlpha = flags & ILIF_ALPHA; } - ::HICON hIcon = NULL; //perf: 1,5 ms - the dominant block + ::HICON hIcon = nullptr; //perf: 1,5 ms - the dominant block { HRESULT hr = imageList->GetIcon(iconIndex, // [in] int i, hasAlpha ? ILD_IMAGE : ILD_NORMAL, // [in] UINT flags, @@ -161,7 +161,7 @@ thumb::HICON thumb::getIconByIndex(int iconIndex, int shilIconType) //return 0 o //other flags: http://msdn.microsoft.com/en-us/library/windows/desktop/bb775230(v=vs.85).aspx &hIcon); // [out] HICON *picon if (FAILED(hr) || !hIcon) - return NULL; + return nullptr; } return hIcon; diff --git a/lib/Thumbnail/thumbnail.h b/lib/Thumbnail/thumbnail.h index 7e11812c..b8b95d8f 100644 --- a/lib/Thumbnail/thumbnail.h +++ b/lib/Thumbnail/thumbnail.h @@ -21,8 +21,8 @@ namespace thumb /* PREREQUISITES: -1. COM must be initialized for the current thread via ::CoInitialize(NULL) or ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED), - but NOT ::CoInitializeEx(NULL, COINIT_MULTITHREADED) -> internal access violation crash! +1. COM must be initialized for the current thread via ::CoInitialize(nullptr) or ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED), + but NOT ::CoInitializeEx(nullptr, COINIT_MULTITHREADED) -> internal access violation crash! 2. call ::FileIconInit() on app start to remedy obscure errors like SHELL_E_WRONG_BITDEPTH (0x80270102) for certain file types, e.g. lnk, mpg - required on Windows 7 see http://msdn.microsoft.com/en-us/library/ms683212(v=VS.85).aspx */ diff --git a/lib/db_file.cpp b/lib/db_file.cpp index 2d02d634..8ae8f94b 100644 --- a/lib/db_file.cpp +++ b/lib/db_file.cpp @@ -60,16 +60,36 @@ Zstring getDBFilename(const BaseDirMapping& baseMap, bool tempfile = false) } +class CheckedDbReader : public CheckedReader +{ +public: + CheckedDbReader(wxInputStream& stream, const Zstring& errorObjName) : CheckedReader(stream), errorObjName_(errorObjName) {} + +private: + virtual void throwException() const { throw FileError(_("Error reading from synchronization database:") + L" \n" + L"\"" + errorObjName_ + L"\""); } + + const Zstring errorObjName_; +}; + + +class CheckedDbWriter : public CheckedWriter +{ +public: + CheckedDbWriter(wxOutputStream& stream, const Zstring& errorObjName) : CheckedWriter(stream), errorObjName_(errorObjName) {} + + virtual void throwException() const { throw FileError(_("Error writing to synchronization database:") + L" \n" + L"\"" + errorObjName_ + L"\""); } + + const Zstring errorObjName_; +}; + + + StreamMapping loadStreams(const Zstring& filename) //throw FileError { - if (!zen::fileExists(filename)) - throw FileErrorDatabaseNotExisting(_("Initial synchronization:") + L" \n\n" + - _("One of the FreeFileSync database files is not yet existing:") + L" \n" + - L"\"" + filename + L"\""); try { //read format description (uncompressed) - FileInputStream rawStream(filename); //throw FileError + FileInputStream rawStream(filename); //throw FileError, ErrorNotExisting //read FreeFileSync file identifier char formatDescr[sizeof(FILE_FORMAT_DESCR)] = {}; @@ -80,26 +100,32 @@ StreamMapping loadStreams(const Zstring& filename) //throw FileError wxZlibInputStream decompressed(rawStream, wxZLIB_ZLIB); - CheckedReader cr(decompressed, filename); + CheckedDbReader cr(decompressed, filename); - std::int32_t version = cr.readNumberC<std::int32_t>(); + std::int32_t version = cr.readPOD<std::int32_t>(); if (version != FILE_FORMAT_VER) //read file format version# throw FileError(_("Incompatible synchronization database format:") + L" \n" + L"\"" + filename + L"\""); //read stream lists StreamMapping output; - std::uint32_t dbCount = cr.readNumberC<std::uint32_t>(); //number of databases: one for each sync-pair + std::uint32_t dbCount = cr.readPOD<std::uint32_t>(); //number of databases: one for each sync-pair while (dbCount-- != 0) { //DB id of partner databases - const std::string sessionID = cr.readStringC<std::string>(); - const MemoryStream stream = cr.readStringC<MemoryStream>(); //read db-entry stream (containing DirInformation) + const std::string sessionID = cr.readString<std::string>(); + const MemoryStream stream = cr.readString<MemoryStream>(); //read db-entry stream (containing DirInformation) output.insert(std::make_pair(sessionID, stream)); } return output; } + catch (ErrorNotExisting&) + { + throw FileErrorDatabaseNotExisting(_("Initial synchronization:") + L" \n\n" + + _("One of the FreeFileSync database files is not yet existing:") + L" \n" + + L"\"" + filename + L"\""); + } catch (const std::bad_alloc&) //this is most likely caused by a corrupted database file { throw FileError(_("Error reading from synchronization database:") + L" (bad alloc)"); @@ -107,7 +133,7 @@ StreamMapping loadStreams(const Zstring& filename) //throw FileError } -class StreamParser : private CheckedReader +class StreamParser : private CheckedDbReader { public: static DirInfoPtr execute(const MemoryStream& stream, const Zstring& fileName) //throw FileError -> return value always bound! @@ -127,14 +153,14 @@ public: } private: - StreamParser(wxInputStream& stream, const Zstring& errorObjName, DirInformation& dirInfo) : CheckedReader(stream, errorObjName) + StreamParser(wxInputStream& stream, const Zstring& errorObjName, DirInformation& dirInfo) : CheckedDbReader(stream, errorObjName) { recurse(dirInfo.baseDirContainer); } Zstring readStringUtf8() const { - return utf8CvrtTo<Zstring>(readStringC<Zbase<char>>()); + return utf8CvrtTo<Zstring>(readString<Zbase<char>>()); } FileId readFileId() const @@ -142,39 +168,39 @@ private: assert_static(sizeof(FileId().first ) <= sizeof(std::uint64_t)); assert_static(sizeof(FileId().second) <= sizeof(std::uint64_t)); - const auto devId = static_cast<decltype(FileId().first )>(readNumberC<std::uint64_t>()); // - const auto fId = static_cast<decltype(FileId().second)>(readNumberC<std::uint64_t>()); //silence "loss of precision" compiler warnings + const auto devId = static_cast<decltype(FileId().first )>(readPOD<std::uint64_t>()); // + const auto fId = static_cast<decltype(FileId().second)>(readPOD<std::uint64_t>()); //silence "loss of precision" compiler warnings return std::make_pair(devId, fId); } void recurse(DirContainer& dirCont) const { - while (readNumberC<bool>()) //files + while (readPOD<bool>()) //files { //attention: order of function argument evaluation is undefined! So do it one after the other... const Zstring shortName = readStringUtf8(); //file name - const std::int64_t modTime = readNumberC<std::int64_t>(); - const std::uint64_t fileSize = readNumberC<std::uint64_t>(); + const std::int64_t modTime = readPOD<std::int64_t>(); + const std::uint64_t fileSize = readPOD<std::uint64_t>(); const FileId fileID = readFileId(); dirCont.addSubFile(shortName, FileDescriptor(modTime, fileSize, fileID)); } - while (readNumberC<bool>()) //symlinks + while (readPOD<bool>()) //symlinks { //attention: order of function argument evaluation is undefined! So do it one after the other... const Zstring shortName = readStringUtf8(); //file name - const std::int64_t modTime = readNumberC<std::int64_t>(); + const std::int64_t modTime = readPOD<std::int64_t>(); const Zstring targetPath = readStringUtf8(); //file name - const LinkDescriptor::LinkType linkType = static_cast<LinkDescriptor::LinkType>(readNumberC<std::int32_t>()); + const LinkDescriptor::LinkType linkType = static_cast<LinkDescriptor::LinkType>(readPOD<std::int32_t>()); dirCont.addSubLink(shortName, LinkDescriptor(modTime, targetPath, linkType)); } - while (readNumberC<bool>()) //directories + while (readPOD<bool>()) //directories { const Zstring shortName = readStringUtf8(); //directory name DirContainer& subDir = dirCont.addSubDir(shortName); @@ -201,29 +227,28 @@ void saveFile(const StreamMapping& streamList, const Zstring& filename) //throw 6 1,77 MB - 613 ms 9 (maximal compression) 1,74 MB - 3330 ms */ - CheckedWriter cw(compressed, filename); + CheckedDbWriter cw(compressed, filename); //save file format version - cw.writeNumberC<std::int32_t>(FILE_FORMAT_VER); + cw.writePOD<std::int32_t>(FILE_FORMAT_VER); //save stream list - cw.writeNumberC<std::uint32_t>(static_cast<std::uint32_t>(streamList.size())); //number of database records: one for each sync-pair + cw.writePOD<std::uint32_t>(static_cast<std::uint32_t>(streamList.size())); //number of database records: one for each sync-pair for (auto iter = streamList.begin(); iter != streamList.end(); ++iter) { - cw.writeStringC<std::string >(iter->first ); //sync session id - cw.writeStringC<MemoryStream>(iter->second); //DirInformation stream + cw.writeString<std::string >(iter->first ); //sync session id + cw.writeString<MemoryStream>(iter->second); //DirInformation stream } } - //(try to) hide database file #ifdef FFS_WIN - ::SetFileAttributes(zen::applyLongPathPrefix(filename).c_str(), FILE_ATTRIBUTE_HIDDEN); + ::SetFileAttributes(applyLongPathPrefix(filename).c_str(), FILE_ATTRIBUTE_HIDDEN); //(try to) hide database file #endif } template <SelectedSide side> -class StreamGenerator : private CheckedWriter +class StreamGenerator : private CheckedDbWriter { public: static MemoryStream execute(const BaseDirMapping& baseMapping, const DirContainer* oldDirInfo, const Zstring& errorObjName) @@ -238,7 +263,7 @@ public: } private: - StreamGenerator(const BaseDirMapping& baseMapping, const DirContainer* oldDirInfo, const Zstring& errorObjName, wxOutputStream& stream) : CheckedWriter(stream, errorObjName) + StreamGenerator(const BaseDirMapping& baseMapping, const DirContainer* oldDirInfo, const Zstring& errorObjName, wxOutputStream& stream) : CheckedDbWriter(stream, errorObjName) { recurse(baseMapping, oldDirInfo); } @@ -247,32 +272,36 @@ private: { // for (const auto& fileMap : hierObj.refSubFiles()) { processFile(fileMap, oldDirInfo); }); ! - std::for_each(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), [&](const FileMapping& fileMap) { this->processFile(fileMap, oldDirInfo); }); - writeNumberC<bool>(false); //mark last entry + std::for_each(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), [&](const FileMapping& fileMap) { this->processFile(fileMap, oldDirInfo); }); + writePOD<bool>(false); //mark last entry std::for_each(hierObj.refSubLinks().begin(), hierObj.refSubLinks().end(), [&](const SymLinkMapping& linkObj) { this->processLink(linkObj, oldDirInfo); }); - writeNumberC<bool>(false); //mark last entry - std::for_each(hierObj.refSubDirs ().begin(), hierObj.refSubDirs ().end(), [&](const DirMapping& dirMap) { this->processDir(dirMap, oldDirInfo); }); - writeNumberC<bool>(false); //mark last entry + writePOD<bool>(false); //mark last entry + std::for_each(hierObj.refSubDirs ().begin(), hierObj.refSubDirs ().end(), [&](const DirMapping& dirMap) { this->processDir (dirMap, oldDirInfo); }); + writePOD<bool>(false); //mark last entry } - void writeStringUtf8(const Zstring& str) { writeStringC(utf8CvrtTo<Zbase<char>>(str)); } + void writeStringUtf8(const Zstring& str) { writeString(utf8CvrtTo<Zbase<char>>(str)); } void writeFileId(const FileId& id) { - writeNumberC<std::uint64_t>(id.first ); //device id - writeNumberC<std::uint64_t>(id.second); //file id + writePOD<std::uint64_t>(id.first ); //device id + writePOD<std::uint64_t>(id.second); //file id } +#ifdef _MSC_VER + warn_static("support multiple folder pairs that differ in hard filter only?") +#endif + void processFile(const FileMapping& fileMap, const DirContainer* oldParentDir) { if (fileMap.getCategory() == FILE_EQUAL) //data in sync: write current state { if (!fileMap.isEmpty<side>()) { - writeNumberC<bool>(true); //mark beginning of entry + writePOD<bool>(true); //mark beginning of entry writeStringUtf8(fileMap.getShortName<side>()); //save respecting case! (Windows) - writeNumberC<std:: int64_t>(to<std:: int64_t>(fileMap.getLastWriteTime<side>())); - writeNumberC<std::uint64_t>(to<std::uint64_t>(fileMap.getFileSize<side>())); + writePOD<std:: int64_t>(to<std:: int64_t>(fileMap.getLastWriteTime<side>())); + writePOD<std::uint64_t>(to<std::uint64_t>(fileMap.getFileSize<side>())); writeFileId(fileMap.getFileId<side>()); } } @@ -283,10 +312,10 @@ private: auto iter = oldParentDir->files.find(fileMap.getObjShortName()); if (iter != oldParentDir->files.end()) { - writeNumberC<bool>(true); //mark beginning of entry + writePOD<bool>(true); //mark beginning of entry writeStringUtf8(iter->first); //save respecting case! (Windows) - writeNumberC<std:: int64_t>(to<std:: int64_t>(iter->second.lastWriteTimeRaw)); - writeNumberC<std::uint64_t>(to<std::uint64_t>(iter->second.fileSize)); + writePOD<std:: int64_t>(to<std:: int64_t>(iter->second.lastWriteTimeRaw)); + writePOD<std::uint64_t>(to<std::uint64_t>(iter->second.fileSize)); writeFileId(iter->second.id); } } @@ -299,11 +328,11 @@ private: { if (!linkObj.isEmpty<side>()) { - writeNumberC<bool>(true); //mark beginning of entry + writePOD<bool>(true); //mark beginning of entry writeStringUtf8(linkObj.getShortName<side>()); //save respecting case! (Windows) - writeNumberC<std::int64_t>(to<std::int64_t>(linkObj.getLastWriteTime<side>())); + writePOD<std::int64_t>(to<std::int64_t>(linkObj.getLastWriteTime<side>())); writeStringUtf8(linkObj.getTargetPath<side>()); - writeNumberC<std::int32_t>(linkObj.getLinkType<side>()); + writePOD<std::int32_t>(linkObj.getLinkType<side>()); } } else //not in sync: reuse last synchronous state @@ -313,11 +342,11 @@ private: auto iter = oldParentDir->links.find(linkObj.getObjShortName()); if (iter != oldParentDir->links.end()) { - writeNumberC<bool>(true); //mark beginning of entry + writePOD<bool>(true); //mark beginning of entry writeStringUtf8(iter->first); //save respecting case! (Windows) - writeNumberC<std::int64_t>(to<std::int64_t>(iter->second.lastWriteTimeRaw)); + writePOD<std::int64_t>(to<std::int64_t>(iter->second.lastWriteTimeRaw)); writeStringUtf8(iter->second.targetPath); - writeNumberC<std::int32_t>(iter->second.type); + writePOD<std::int32_t>(iter->second.type); } } } @@ -325,8 +354,8 @@ private: void processDir(const DirMapping& dirMap, const DirContainer* oldParentDir) { - const DirContainer* oldDir = NULL; - const Zstring* oldDirName = NULL; + const DirContainer* oldDir = nullptr; + const Zstring* oldDirName = nullptr; if (oldParentDir) //no data is also a "synchronous state"! { auto iter = oldParentDir->dirs.find(dirMap.getObjShortName()); @@ -343,7 +372,7 @@ private: { if (!dirMap.isEmpty<side>()) { - writeNumberC<bool>(true); //mark beginning of entry + writePOD<bool>(true); //mark beginning of entry writeStringUtf8(dirMap.getShortName<side>()); //save respecting case! (Windows) recurse(dirMap, oldDir); } @@ -352,7 +381,7 @@ private: { if (oldDir) { - writeNumberC<bool>(true); //mark beginning of entry + writePOD<bool>(true); //mark beginning of entry writeStringUtf8(*oldDirName); //save respecting case! (Windows) recurse(dirMap, oldDir); return; @@ -372,7 +401,7 @@ private: assert(false); break; case DIR_DIFFERENT_METADATA: - writeNumberC<bool>(true); + writePOD<bool>(true); writeStringUtf8(dirMap.getShortName<side>()); //ATTENTION: strictly this is a violation of the principle of reporting last synchronous state! //however in this case this will result in "last sync unsuccessful" for this directory within <automatic> algorithm, which is fine @@ -396,30 +425,23 @@ std::pair<DirInfoPtr, DirInfoPtr> zen::loadFromDisk(const BaseDirMapping& baseMa const StreamMapping streamListRight = ::loadStreams(fileNameRight); //throw FileError //find associated session: there can be at most one session within intersection of left and right ids - StreamMapping::const_iterator streamLeft = streamListLeft .end(); - StreamMapping::const_iterator streamRight = streamListRight.end(); for (auto iterLeft = streamListLeft.begin(); iterLeft != streamListLeft.end(); ++iterLeft) { auto iterRight = streamListRight.find(iterLeft->first); if (iterRight != streamListRight.end()) { - streamLeft = iterLeft; - streamRight = iterRight; - break; + //read streams into DirInfo + DirInfoPtr dirInfoLeft = StreamParser::execute(iterLeft ->second, fileNameLeft); //throw FileError + DirInfoPtr dirInfoRight = StreamParser::execute(iterRight->second, fileNameRight); //throw FileError + + return std::make_pair(dirInfoLeft, dirInfoRight); } } - if (streamLeft == streamListLeft .end() || - streamRight == streamListRight.end()) - throw FileErrorDatabaseNotExisting(_("Initial synchronization:") + L" \n\n" + - _("Database files do not share a common synchronization session:") + L" \n" + - L"\"" + fileNameLeft + L"\"\n" + - L"\"" + fileNameRight + L"\""); - //read streams into DirInfo - DirInfoPtr dirInfoLeft = StreamParser::execute(streamLeft ->second, fileNameLeft); //throw FileError - DirInfoPtr dirInfoRight = StreamParser::execute(streamRight->second, fileNameRight); //throw FileError - - return std::make_pair(dirInfoLeft, dirInfoRight); + throw FileErrorDatabaseNotExisting(_("Initial synchronization:") + L" \n\n" + + _("Database files do not share a common synchronization session:") + L" \n" + + L"\"" + fileNameLeft + L"\"\n" + + L"\"" + fileNameRight + L"\""); } @@ -440,75 +462,65 @@ void zen::saveToDisk(const BaseDirMapping& baseMapping) //throw FileError StreamMapping streamListLeft; StreamMapping streamListRight; - try //read file data: list of session ID + DirInfo-stream - { - streamListLeft = ::loadStreams(dbNameLeft); - } - catch (FileError&) {} //if error occurs: just overwrite old file! User is already informed about issues right after comparing! - try - { - streamListRight = ::loadStreams(dbNameRight); - } + //read file data: list of session ID + DirInfo-stream + try { streamListLeft = ::loadStreams(dbNameLeft ); } catch (FileError&) {} + try { streamListRight = ::loadStreams(dbNameRight); } + catch (FileError&) {} + //if error occurs: just overwrite old file! User is already informed about issues right after comparing! //find associated session: there can be at most one session within intersection of left and right ids - StreamMapping::iterator streamLeft = streamListLeft .end(); - StreamMapping::iterator streamRight = streamListRight.end(); + auto streamLeftOld = streamListLeft .cend(); + auto streamRightOld = streamListRight.cend(); for (auto iterLeft = streamListLeft.begin(); iterLeft != streamListLeft.end(); ++iterLeft) { auto iterRight = streamListRight.find(iterLeft->first); if (iterRight != streamListRight.end()) { - streamLeft = iterLeft; - streamRight = iterRight; + streamLeftOld = iterLeft; + streamRightOld = iterRight; break; } } //(try to) read old DirInfo - DirInfoPtr oldDirInfoLeft; - DirInfoPtr oldDirInfoRight; - try - { - if (streamLeft != streamListLeft .end() && - streamRight != streamListRight.end()) + DirInfoPtr dirInfoLeftOld; + DirInfoPtr dirInfoRightOld; + if (streamLeftOld != streamListLeft .end() && + streamRightOld != streamListRight.end()) + try { - oldDirInfoLeft = StreamParser::execute(streamLeft ->second, dbNameLeft ); //throw FileError - oldDirInfoRight = StreamParser::execute(streamRight->second, dbNameRight); //throw FileError + dirInfoLeftOld = StreamParser::execute(streamLeftOld ->second, dbNameLeft ); //throw FileError + dirInfoRightOld = StreamParser::execute(streamRightOld->second, dbNameRight); //throw FileError + } + catch (FileError&) + { + //if error occurs: just overwrite old file! User is already informed about issues right after comparing! + dirInfoLeftOld .reset(); //read both or none! + dirInfoRightOld.reset(); // } - } - catch (FileError&) - { - //if error occurs: just overwrite old file! User is already informed about issues right after comparing! - oldDirInfoLeft .reset(); //read both or none! - oldDirInfoRight.reset(); // - } //create new database entries - MemoryStream newStreamLeft = StreamGenerator<LEFT_SIDE >::execute(baseMapping, oldDirInfoLeft .get() ? &oldDirInfoLeft ->baseDirContainer : NULL, dbNameLeft); - MemoryStream newStreamRight = StreamGenerator<RIGHT_SIDE>::execute(baseMapping, oldDirInfoRight.get() ? &oldDirInfoRight->baseDirContainer : NULL, dbNameRight); + MemoryStream rawStreamLeftNew = StreamGenerator<LEFT_SIDE >::execute(baseMapping, dirInfoLeftOld .get() ? &dirInfoLeftOld ->baseDirContainer : nullptr, dbNameLeft); + MemoryStream rawStreamRightNew = StreamGenerator<RIGHT_SIDE>::execute(baseMapping, dirInfoRightOld.get() ? &dirInfoRightOld->baseDirContainer : nullptr, dbNameRight); //check if there is some work to do at all - { - const bool updateRequiredLeft = streamLeft == streamListLeft .end() || newStreamLeft != streamLeft ->second; - const bool updateRequiredRight = streamRight == streamListRight.end() || newStreamRight != streamRight->second; - //some users monitor the *.ffs_db file with RTS => don't touch the file if it isnt't strictly needed - if (!updateRequiredLeft && !updateRequiredRight) - return; - } - - //create/update DirInfo-streams - std::string sessionID = zen::generateGUID(); + if (streamLeftOld != streamListLeft .end() && rawStreamLeftNew == streamLeftOld ->second && + streamRightOld != streamListRight.end() && rawStreamRightNew == streamRightOld->second) + return; //some users monitor the *.ffs_db file with RTS => don't touch the file if it isnt't strictly needed //erase old session data - if (streamLeft != streamListLeft.end()) - streamListLeft.erase(streamLeft); - if (streamRight != streamListRight.end()) - streamListRight.erase(streamRight); + if (streamLeftOld != streamListLeft.end()) + streamListLeft.erase(streamLeftOld); + if (streamRightOld != streamListRight.end()) + streamListRight.erase(streamRightOld); + + //create/update DirInfo-streams + const std::string sessionID = zen::generateGUID(); //fill in new - streamListLeft .insert(std::make_pair(sessionID, newStreamLeft)); - streamListRight.insert(std::make_pair(sessionID, newStreamRight)); + streamListLeft .insert(std::make_pair(sessionID, rawStreamLeftNew)); + streamListRight.insert(std::make_pair(sessionID, rawStreamRightNew)); //write (temp-) files... zen::ScopeGuard guardTempFileLeft = zen::makeGuard([&] {zen::removeFile(dbNameLeftTmp); }); diff --git a/lib/dir_lock.cpp b/lib/dir_lock.cpp index 88fb19b3..87864ce4 100644 --- a/lib/dir_lock.cpp +++ b/lib/dir_lock.cpp @@ -28,7 +28,6 @@ #elif defined FFS_LINUX #include <sys/stat.h> -#include <cerrno> #include <unistd.h> #endif @@ -76,24 +75,24 @@ public: const char buffer[1] = {' '}; #ifdef FFS_WIN - //ATTENTION: setting file pointer IS required! => use CreateFile/FILE_GENERIC_WRITE + SetFilePointerEx! + //ATTENTION: setting file pointer IS required! => use CreateFile/GENERIC_WRITE + SetFilePointerEx! //although CreateFile/FILE_APPEND_DATA without SetFilePointerEx works locally, it MAY NOT work on some network shares creating a 4 gig file!!! const HANDLE fileHandle = ::CreateFile(applyLongPathPrefix(lockfilename_).c_str(), GENERIC_READ | GENERIC_WRITE, //use both when writing over network, see comment in file_io.cpp FILE_SHARE_READ, - NULL, + nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, - NULL); + nullptr); if (fileHandle == INVALID_HANDLE_VALUE) return; - ZEN_ON_BLOCK_EXIT(::CloseHandle(fileHandle)); + ZEN_ON_SCOPE_EXIT(::CloseHandle(fileHandle)); const LARGE_INTEGER moveDist = {}; if (!::SetFilePointerEx(fileHandle, //__in HANDLE hFile, moveDist, //__in LARGE_INTEGER liDistanceToMove, - NULL, //__out_opt PLARGE_INTEGER lpNewFilePointer, + nullptr, //__out_opt PLARGE_INTEGER lpNewFilePointer, FILE_END)) //__in DWORD dwMoveMethod return; @@ -102,13 +101,13 @@ public: buffer, //__out LPVOID lpBuffer, 1, //__in DWORD nNumberOfBytesToRead, &bytesWritten, //__out_opt LPDWORD lpNumberOfBytesWritten, - NULL); //__inout_opt LPOVERLAPPED lpOverlapped + nullptr); //__inout_opt LPOVERLAPPED lpOverlapped #elif defined FFS_LINUX - const int fileHandle = ::open(lockfilename_.c_str(), O_WRONLY | O_APPEND); //O_EXCL contains a race condition on NFS file systems: http://linux.die.net/man/2/open + const int fileHandle = ::open(lockfilename_.c_str(), O_WRONLY | O_APPEND); if (fileHandle == -1) return; - ZEN_ON_BLOCK_EXIT(::close(fileHandle)); + ZEN_ON_SCOPE_EXIT(::close(fileHandle)); const ssize_t bytesWritten = ::write(fileHandle, buffer, 1); (void)bytesWritten; @@ -127,41 +126,25 @@ UInt64 getLockFileSize(const Zstring& filename) //throw FileError, ErrorNotExist #ifdef FFS_WIN WIN32_FIND_DATA fileInfo = {}; const HANDLE searchHandle = ::FindFirstFile(applyLongPathPrefix(filename).c_str(), &fileInfo); - if (searchHandle == INVALID_HANDLE_VALUE) + if (searchHandle != INVALID_HANDLE_VALUE) { - const DWORD lastError = ::GetLastError(); - - std::wstring errorMessage = _("Error reading file attributes:") + L"\n\"" + filename + L"\"" + L"\n\n" + getLastErrorFormatted(lastError); - - if (lastError == ERROR_FILE_NOT_FOUND || - lastError == ERROR_PATH_NOT_FOUND || - lastError == ERROR_BAD_NETPATH || - lastError == ERROR_NETNAME_DELETED) - throw ErrorNotExisting(errorMessage); - else - throw FileError(errorMessage); + ::FindClose(searchHandle); + return zen::UInt64(fileInfo.nFileSizeLow, fileInfo.nFileSizeHigh); } - ::FindClose(searchHandle); - - return zen::UInt64(fileInfo.nFileSizeLow, fileInfo.nFileSizeHigh); - #elif defined FFS_LINUX struct ::stat fileInfo = {}; - if (::stat(filename.c_str(), &fileInfo) != 0) //follow symbolic links - { - const int lastError = errno; - - std::wstring errorMessage = _("Error reading file attributes:") + L"\n\"" + filename + L"\"" + L"\n\n" + getLastErrorFormatted(lastError); + if (::stat(filename.c_str(), &fileInfo) == 0) //follow symbolic links + return zen::UInt64(fileInfo.st_size); +#endif - if (lastError == ENOENT) - throw ErrorNotExisting(errorMessage); - else - throw FileError(errorMessage); - } + const ErrorCode lastError = getLastError(); + const std::wstring errorMessage = _("Error reading file attributes:") + L"\n\"" + filename + L"\"" + L"\n\n" + getLastErrorFormatted(lastError); - return zen::UInt64(fileInfo.st_size); -#endif + if (errorCodeForNotExisting(lastError)) + throw ErrorNotExisting(errorMessage); + else + throw FileError(errorMessage); } @@ -177,29 +160,6 @@ Zstring deleteAbandonedLockName(const Zstring& lockfilename) //make sure to NOT namespace { -//read string from file stream -inline -std::string readString(wxInputStream& stream) //throw std::exception -{ - const auto strLength = readPOD<std::uint32_t>(stream); - std::string output; - if (strLength > 0) - { - output.resize(strLength); //throw std::bad_alloc - stream.Read(&output[0], strLength); - } - return output; -} - - -inline -void writeString(wxOutputStream& stream, const std::string& str) //write string to filestream -{ - writePOD(stream, static_cast<std::uint32_t>(str.length())); - stream.Write(str.c_str(), str.length()); -} - - std::string getComputerId() //returns empty string on error { const wxString fhn = ::wxGetFullHostName(); @@ -234,9 +194,9 @@ struct LockInformation //some format checking here? - lockId = readString(stream); + lockId = readString<std::string>(stream); procDescr.processId = static_cast<ProcessId>(readPOD<std::uint64_t>(stream)); //possible loss of precision (32/64 bit process) covered by buildId - procDescr.computerId = readString(stream); + procDescr.computerId = readString<std::string>(stream); } void toStream(wxOutputStream& stream) const //write @@ -282,7 +242,7 @@ ProcessStatus getProcessStatus(const LockInformation::ProcessDescription& procDe return PROC_STATUS_NO_IDEA; //lock owned by different computer #ifdef FFS_WIN - if (procDescr.processId == ::GetCurrentProcessId()) //may seem obscure, but it's possible: a lock file is "stolen" and put back while the program is running + if (procDescr.processId == ::GetCurrentProcessId()) //may seem obscure, but it's possible: deletion failed or a lock file is "stolen" and put back while the program is running return PROC_STATUS_ITS_US; //note: ::OpenProcess() is no option as it may successfully return for crashed processes! @@ -291,7 +251,7 @@ ProcessStatus getProcessStatus(const LockInformation::ProcessDescription& procDe 0); //__in DWORD th32ProcessID if (snapshot == INVALID_HANDLE_VALUE) return PROC_STATUS_NO_IDEA; - ZEN_ON_BLOCK_EXIT(::CloseHandle(snapshot)); + ZEN_ON_SCOPE_EXIT(::CloseHandle(snapshot)); PROCESSENTRY32 processEntry = {}; processEntry.dwSize = sizeof(processEntry); @@ -315,7 +275,7 @@ ProcessStatus getProcessStatus(const LockInformation::ProcessDescription& procDe if (procDescr.processId <= 0 || procDescr.processId >= 65536) return PROC_STATUS_NO_IDEA; //invalid process id - return zen::dirExists(Zstr("/proc/") + zen::toString<Zstring>(procDescr.processId)) ? PROC_STATUS_RUNNING : PROC_STATUS_NOT_RUNNING; + return zen::dirExists(Zstr("/proc/") + zen::numberTo<Zstring>(procDescr.processId)) ? PROC_STATUS_RUNNING : PROC_STATUS_NOT_RUNNING; #endif } @@ -374,9 +334,8 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr const zen::UInt64 fileSizeNew = ::getLockFileSize(lockfilename); //throw FileError, ErrorNotExisting wxLongLong currentTime = wxGetLocalTimeMillis(); - if (fileSizeNew != fileSizeOld) + if (fileSizeNew != fileSizeOld) //received life sign from lock { - //received life sign from lock fileSizeOld = fileSizeNew; lockSilentStart = currentTime; } @@ -413,7 +372,7 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr long remainingSeconds = ((DETECT_EXITUS_INTERVAL - (wxGetLocalTimeMillis() - lockSilentStart)) / 1000).ToLong(); remainingSeconds = std::max(0L, remainingSeconds); - const std::wstring remSecMsg = replaceCpy(_P("1 sec", "%x sec", remainingSeconds), L"%x", toString<std::wstring>(remainingSeconds)); + const std::wstring remSecMsg = replaceCpy(_P("1 sec", "%x sec", remainingSeconds), L"%x", numberTo<std::wstring>(remainingSeconds)); callback->reportInfo(infoMsg + L" " + remSecMsg); } @@ -446,10 +405,10 @@ bool tryLock(const Zstring& lockfilename) //throw FileError const HANDLE fileHandle = ::CreateFile(applyLongPathPrefix(lockfilename).c_str(), GENERIC_READ | GENERIC_WRITE, //use both when writing over network, see comment in file_io.cpp FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, + nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, - NULL); + nullptr); if (fileHandle == INVALID_HANDLE_VALUE) { if (::GetLastError() == ERROR_FILE_EXISTS) @@ -473,7 +432,7 @@ bool tryLock(const Zstring& lockfilename) //throw FileError ::close(fileHandle); #endif - ScopeGuard guardLockFile = zen::makeGuard([&] { zen::removeFile(lockfilename); }); + ScopeGuard guardLockFile = zen::makeGuard([&] { removeFile(lockfilename); }); //write UUID at the beginning of the file: this ID is a universal identifier for this lock (no matter what the path is, considering symlinks, etc.) writeLockInfo(lockfilename); //throw FileError @@ -487,7 +446,7 @@ bool tryLock(const Zstring& lockfilename) //throw FileError class DirLock::SharedDirLock { public: - SharedDirLock(const Zstring& lockfilename, DirLockCallback* callback = NULL) : //throw FileError + SharedDirLock(const Zstring& lockfilename, DirLockCallback* callback = nullptr) : //throw FileError lockfilename_(lockfilename) { while (!::tryLock(lockfilename)) //throw FileError @@ -530,17 +489,14 @@ public: FileToUuidMap::const_iterator iterUuid = fileToUuid.find(lockfilename); if (iterUuid != fileToUuid.end()) { - const std::shared_ptr<SharedDirLock>& activeLock = findActive(iterUuid->second); //returns null-lock if not found - if (activeLock) + if (const std::shared_ptr<SharedDirLock>& activeLock = findActive(iterUuid->second)) //returns null-lock if not found return activeLock; //SharedDirLock is still active -> enlarge circle of shared ownership } try //actual check based on lock UUID, deadlock prevention: "lockfilename" may be an alternative name for an already active lock { const std::string lockId = retrieveLockId(lockfilename); //throw FileError, ErrorNotExisting - - const std::shared_ptr<SharedDirLock>& activeLock = findActive(lockId); //returns null-lock if not found - if (activeLock) + if (const std::shared_ptr<SharedDirLock>& activeLock = findActive(lockId)) //returns null-lock if not found { fileToUuid[lockfilename] = lockId; //perf-optimization: update relation return activeLock; @@ -549,8 +505,8 @@ public: catch (FileError&) {} //catch everything, let SharedDirLock constructor deal with errors, e.g. 0-sized/corrupted lock file //not yet in buffer, so create a new directory lock - std::shared_ptr<SharedDirLock> newLock(new SharedDirLock(lockfilename, callback)); //throw FileError - const std::string newLockId = retrieveLockId(lockfilename); //throw FileError, ErrorNotExisting + auto newLock = std::make_shared<SharedDirLock>(lockfilename, callback); //throw FileError + const std::string& newLockId = retrieveLockId(lockfilename); //throw FileError, ErrorNotExisting //update registry fileToUuid[lockfilename] = newLockId; //throw() @@ -564,16 +520,14 @@ private: std::shared_ptr<SharedDirLock> findActive(const std::string& lockId) //returns null-lock if not found { - UuidToLockMap::const_iterator iterLock = uuidToLock.find(lockId); + auto iterLock = uuidToLock.find(lockId); return iterLock != uuidToLock.end() ? iterLock->second.lock() : nullptr; //try to get shared_ptr; throw() } - typedef std::weak_ptr<SharedDirLock> SharedLock; - typedef std::string UniqueId; - typedef std::map<Zstring, UniqueId, LessFilename> FileToUuidMap; //n:1 handle uppper/lower case correctly - typedef std::map<UniqueId, SharedLock> UuidToLockMap; //1:1 + typedef std::map<Zstring, UniqueId, LessFilename> FileToUuidMap; //n:1 handle uppper/lower case correctly + typedef std::map<UniqueId, std::weak_ptr<SharedDirLock>> UuidToLockMap; //1:1 FileToUuidMap fileToUuid; //lockname |-> UUID; locks can be referenced by a lockfilename or alternatively a UUID UuidToLockMap uuidToLock; //UUID |-> "shared lock ownership" @@ -583,7 +537,7 @@ private: DirLock::DirLock(const Zstring& lockfilename, DirLockCallback* callback) //throw FileError { #ifdef FFS_WIN - const DWORD bufferSize = std::max(lockfilename.size(), static_cast<size_t>(10000)); + const DWORD bufferSize = 10000; std::vector<wchar_t> volName(bufferSize); if (::GetVolumePathName(lockfilename.c_str(), //__in LPCTSTR lpszFileName, &volName[0], //__out LPTSTR lpszVolumePathName, diff --git a/lib/dir_lock.h b/lib/dir_lock.h index 9938d554..3e9f2a79 100644 --- a/lib/dir_lock.h +++ b/lib/dir_lock.h @@ -25,11 +25,12 @@ RAII structure to place a directory lock against other FFS processes: - detects and resolves abandoned locks (instantly if lock is associated with local pc, else after 30 seconds) - temporary locks created during abandoned lock resolution keep "lockfilename"'s extension - race-free (Windows, almost on Linux(NFS)) + - currently NOT thread-safe! (static LockAdmin) */ class DirLock { public: - DirLock(const Zstring& lockfilename, DirLockCallback* callback = NULL); //throw FileError, callback only used during construction + DirLock(const Zstring& lockfilename, DirLockCallback* callback = nullptr); //throw FileError, callback only used during construction private: class LockAdmin; diff --git a/lib/error_log.cpp b/lib/error_log.cpp deleted file mode 100644 index a71e72e1..00000000 --- a/lib/error_log.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// ************************************************************************** -// * This file is part of the FreeFileSync project. It is distributed under * -// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * -// * Copyright (C) ZenJu (zhnmju123 AT gmx DOT de) - All Rights Reserved * -// ************************************************************************** - -#include "error_log.h" -#include <zen/time.h> -#include <zen/i18n.h> -#include <algorithm> - -using namespace zen; - - -void ErrorLogging::logMsg(const wxString& message, zen::MessageType type) -{ - Entry newEntry; - newEntry.type = type; - newEntry.time = std::time(NULL); - newEntry.message = message; - - messages.push_back(newEntry); - - ++statistics[type]; -} - - -int ErrorLogging::typeCount(int typeFilter) const -{ - int count = 0; - - if (typeFilter & TYPE_INFO) - count += statistics[TYPE_INFO]; - if (typeFilter & TYPE_WARNING) - count += statistics[TYPE_WARNING]; - if (typeFilter & TYPE_ERROR) - count += statistics[TYPE_ERROR]; - if (typeFilter & TYPE_FATAL_ERROR) - count += statistics[TYPE_FATAL_ERROR]; - - return count; -} - - -std::vector<wxString> ErrorLogging::getFormattedMessages(int typeFilter) const -{ - std::vector<wxString> output; - - std::for_each(messages.begin(), messages.end(), - [&](const Entry& entry) - { - if (entry.type & typeFilter) - output.push_back(formatMessage(entry)); - }); - - return output; -} - - -wxString ErrorLogging::formatMessage(const Entry& msg) -{ - wxString typeName; - switch (msg.type) - { - case TYPE_INFO: - typeName = _("Info"); - break; - case TYPE_WARNING: - typeName = _("Warning"); - break; - case TYPE_ERROR: - typeName = _("Error"); - break; - case TYPE_FATAL_ERROR: - typeName = _("Fatal Error"); - break; - } - - const wxString prefix = L"[" + formatTime<wxString>(FORMAT_TIME, localTime(msg.time)) + L"] " + typeName + L": "; - - wxString formattedText = prefix; - for (auto iter = msg.message.begin(); iter != msg.message.end(); ) - if (*iter == L'\n') - { - formattedText += L'\n'; - - wxString blanks; - blanks.resize(prefix.size(), L' '); - formattedText += blanks; - - do //remove duplicate newlines - { - ++iter; - } - while (iter != msg.message.end() && *iter == L'\n'); - } - else - formattedText += *iter++; - - return formattedText; -} diff --git a/lib/error_log.h b/lib/error_log.h deleted file mode 100644 index 62aac70f..00000000 --- a/lib/error_log.h +++ /dev/null @@ -1,49 +0,0 @@ -// ************************************************************************** -// * This file is part of the FreeFileSync project. It is distributed under * -// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * -// * Copyright (C) ZenJu (zhnmju123 AT gmx DOT de) - All Rights Reserved * -// ************************************************************************** - -#ifndef ERRORLOGGING_H_INCLUDED -#define ERRORLOGGING_H_INCLUDED - -#include <map> -#include <vector> -#include <wx/string.h> - -namespace zen -{ -enum MessageType -{ - TYPE_INFO = 1, - TYPE_WARNING = 2, - TYPE_ERROR = 4, - TYPE_FATAL_ERROR = 8, -}; - -class ErrorLogging -{ -public: - void logMsg(const wxString& message, MessageType type); - - int typeCount(int typeFilter = TYPE_INFO | TYPE_WARNING | TYPE_ERROR | TYPE_FATAL_ERROR) const; - - std::vector<wxString> getFormattedMessages(int typeFilter = TYPE_INFO | TYPE_WARNING | TYPE_ERROR | TYPE_FATAL_ERROR) const; - -private: - struct Entry - { - MessageType type; - time_t time; - wxString message; - }; - - static wxString formatMessage(const Entry& msg); - - std::vector<Entry> messages; //list of non-resolved errors and warnings - - mutable std::map<MessageType, int> statistics; -}; -} - -#endif // ERRORLOGGING_H_INCLUDED diff --git a/lib/hard_filter.cpp b/lib/hard_filter.cpp index fcef6a9f..603d27b0 100644 --- a/lib/hard_filter.cpp +++ b/lib/hard_filter.cpp @@ -57,8 +57,17 @@ HardFilter::FilterRef HardFilter::loadFilter(wxInputStream& stream) } -//-------------------------------------------------------------------------------------------------- -void addFilterEntry(const Zstring& filtername, std::set<Zstring>& fileFilter, std::set<Zstring>& directoryFilter) +namespace +{ +//constructing them in addFilterEntry becomes perf issue for large filter lists +const Zstring asterisk(Zstr('*')); +const Zstring sepAsterisk = FILE_NAME_SEPARATOR + asterisk; +const Zstring asteriskSep = asterisk + FILE_NAME_SEPARATOR; +const Zstring asteriskSepAsterisk = asteriskSep + asterisk; +} + + +void addFilterEntry(const Zstring& filtername, std::vector<Zstring>& fileFilter, std::vector<Zstring>& directoryFilter) { Zstring filterFormatted = filtername; @@ -68,70 +77,73 @@ void addFilterEntry(const Zstring& filtername, std::set<Zstring>& fileFilter, st #elif defined FFS_LINUX //Linux DOES distinguish between upper/lower-case: nothing to do here #endif + if (startsWith(filterFormatted, FILE_NAME_SEPARATOR)) // \abc + filterFormatted = afterFirst(filterFormatted, FILE_NAME_SEPARATOR); //leading separator is optional! - const Zstring sepAsterisk = Zstring(FILE_NAME_SEPARATOR) + Zchar('*'); - const Zstring sepQuestionMark = Zstring(FILE_NAME_SEPARATOR) + Zchar('?'); - const Zstring asteriskSep = Zstring(Zstr('*')) + FILE_NAME_SEPARATOR; - const Zstring questionMarkSep = Zstring(Zstr('?')) + FILE_NAME_SEPARATOR; - - //-------------------------------------------------------------------------------------------------- - //add some syntactic sugar: handle beginning of filtername - if (startsWith(filterFormatted, FILE_NAME_SEPARATOR)) + //some syntactic sugar: + if (filterFormatted == asteriskSepAsterisk) // *\* := match everything except files directly in base directory { - //remove leading separators (keep BEFORE test for Zstring::empty()!) - filterFormatted = afterFirst(filterFormatted, FILE_NAME_SEPARATOR); + fileFilter. push_back(filterFormatted); + directoryFilter.push_back(asterisk); + return; } - else if (startsWith(filterFormatted, asteriskSep) || // *\abc - startsWith(filterFormatted, questionMarkSep)) // ?\abc + //more syntactic sugar: handle beginning of filtername + else if (startsWith(filterFormatted, asteriskSep)) // *\abc { - addFilterEntry(Zstring(filterFormatted.c_str() + 1), fileFilter, directoryFilter); //prevent further recursion by prefix + addFilterEntry(filterFormatted.c_str() + 2, fileFilter, directoryFilter); //recursion is finite } - //-------------------------------------------------------------------------------------------------- //even more syntactic sugar: handle end of filtername if (endsWith(filterFormatted, FILE_NAME_SEPARATOR)) { const Zstring candidate = beforeLast(filterFormatted, FILE_NAME_SEPARATOR); if (!candidate.empty()) - directoryFilter.insert(candidate); //only relevant for directory filtering + directoryFilter.push_back(candidate); //only relevant for directory filtering } - else if (endsWith(filterFormatted, sepAsterisk) || // abc\* - endsWith(filterFormatted, sepQuestionMark)) // abc\? + else if (endsWith(filterFormatted, sepAsterisk)) // abc\* { - fileFilter.insert( filterFormatted); - directoryFilter.insert(filterFormatted); + fileFilter .push_back(filterFormatted); + directoryFilter.push_back(filterFormatted); const Zstring candidate = beforeLast(filterFormatted, FILE_NAME_SEPARATOR); if (!candidate.empty()) - directoryFilter.insert(candidate); //only relevant for directory filtering + directoryFilter.push_back(candidate); //only relevant for directory filtering } else if (!filterFormatted.empty()) { - fileFilter. insert(filterFormatted); - directoryFilter.insert(filterFormatted); + fileFilter. push_back(filterFormatted); + directoryFilter.push_back(filterFormatted); } } namespace { -template <class T> inline -const T* cStringFind(const T* str1, T ch) //strchr() +template <class Char> inline +const Char* cStringFind(const Char* str, Char ch) //strchr() { - while (*str1 != ch) //ch is allowed to be 0 by contract! must return end of string in this case + for (;;) { - if (*str1 == 0) - return NULL; - ++str1; + const Char s = *str; + if (s == ch) //ch is allowed to be 0 by contract! must return end of string in this case + return str; + + if (s == 0) + return nullptr; + ++str; } - return str1; } + bool matchesMask(const Zchar* str, const Zchar* mask) { - for (Zchar ch; (ch = *mask) != 0; ++mask, ++str) + for (;; ++mask, ++str) { - switch (ch) + Zchar m = *mask; + if (m == 0) + return *str == 0; + + switch (m) { case Zstr('?'): if (*str == 0) @@ -139,96 +151,91 @@ bool matchesMask(const Zchar* str, const Zchar* mask) break; case Zstr('*'): - //advance to next non-*/? char + //advance mask to next non-* char do { - ++mask; - ch = *mask; + m = *++mask; } - while (ch == Zstr('*') || ch == Zstr('?')); - //if mask ends with '*': - if (ch == 0) + while (m == Zstr('*')); + + if (m == 0) //mask ends with '*': return true; + //*? - pattern + if (m == Zstr('?')) + { + ++mask; + while (*str++ != 0) + if (matchesMask(str, mask)) + return true; + return false; + } + + //*[letter] - pattern ++mask; - while ((str = cStringFind(str, ch)) != NULL) + for (;;) { + str = cStringFind(str, m); + if (!str) + return false; + ++str; if (matchesMask(str, mask)) return true; } - return false; default: - if (*str != ch) + if (*str != m) return false; } } - return *str == 0; } + //returns true if string matches at least the beginning of mask inline bool matchesMaskBegin(const Zchar* str, const Zchar* mask) { - for (Zchar ch; (ch = *mask) != 0; ++mask, ++str) + for (;; ++mask, ++str) { - if (*str == 0) - return true; + const Zchar m = *mask; + if (m == 0) + return *str == 0; - switch (ch) + switch (m) { case Zstr('?'): + if (*str == 0) + return true; break; case Zstr('*'): return true; default: - if (*str != ch) - return false; + if (*str != m) + return *str == 0; } } - return *str == 0; } } -class MatchFound : public std::unary_function<Zstring, bool> -{ -public: - MatchFound(const Zstring& name) : name_(name) {} - - bool operator()(const Zstring& mask) const - { - return matchesMask(name_.c_str(), mask.c_str()); - } -private: - const Zstring& name_; -}; - - inline -bool matchesFilter(const Zstring& nameFormatted, const std::set<Zstring>& filter) +bool matchesFilter(const Zstring& name, const std::vector<Zstring>& filter) { - return std::find_if(filter.begin(), filter.end(), MatchFound(nameFormatted)) != filter.end(); + return std::any_of(filter.begin(), filter.end(), [&](const Zstring& mask) { return matchesMask(name.c_str(), mask.c_str()); }); } inline -bool matchesFilterBegin(const Zstring& nameFormatted, const std::set<Zstring>& filter) +bool matchesFilterBegin(const Zstring& name, const std::vector<Zstring>& filter) { - for (std::set<Zstring>::const_iterator i = filter.begin(); i != filter.end(); ++i) - if (matchesMaskBegin(nameFormatted.c_str(), i->c_str())) - return true; - return false; - - // return std::find_if(filter.begin(), filter.end(), - // boost::bind(matchesMaskBegin, nameFormatted.c_str(), _1)) != filter.end(); + return std::any_of(filter.begin(), filter.end(), [&](const Zstring& mask) { return matchesMaskBegin(name.c_str(), mask.c_str()); }); } -std::vector<Zstring> compoundStringToFilter(const Zstring& filterString) +std::vector<Zstring> splitByDelimiter(const Zstring& filterString) { //delimiters may be ';' or '\n' std::vector<Zstring> output; @@ -256,16 +263,29 @@ NameFilter::NameFilter(const Zstring& includeFilter, const Zstring& excludeFilte includeFilterTmp(includeFilter), //save constructor arguments for serialization excludeFilterTmp(excludeFilter) { - //no need for regular expressions! In tests wxRegex was by factor of 10 slower than wxString::Matches()!! + //no need for regular expressions: In tests wxRegex was by factor of 10 slower than wxString::Matches() //load filter into vectors of strings //delimiters may be ';' or '\n' - const std::vector<Zstring>& includeList = compoundStringToFilter(includeFilter); - const std::vector<Zstring>& excludeList = compoundStringToFilter(excludeFilter); + const std::vector<Zstring>& includeList = splitByDelimiter(includeFilter); + const std::vector<Zstring>& excludeList = splitByDelimiter(excludeFilter); //setup include/exclude filters for files and directories std::for_each(includeList.begin(), includeList.end(), [&](const Zstring& entry) { addFilterEntry(entry, filterFileIn, filterFolderIn); }); std::for_each(excludeList.begin(), excludeList.end(), [&](const Zstring& entry) { addFilterEntry(entry, filterFileEx, filterFolderEx); }); + + auto removeDuplicates = [](std::vector<Zstring>& cont) + { + std::vector<Zstring> output; + std::set<Zstring> used; + std::copy_if(cont.begin(), cont.end(), std::back_inserter(output), [&](const Zstring& item) { return used.insert(item).second; }); + output.swap(cont); + }; + + removeDuplicates(filterFileIn); + removeDuplicates(filterFolderIn); + removeDuplicates(filterFileEx); + removeDuplicates(filterFolderEx); } @@ -278,14 +298,14 @@ bool NameFilter::passFileFilter(const Zstring& relFilename) const const Zstring& nameFormatted = relFilename; //nothing to do here #endif - return matchesFilter(nameFormatted, filterFileIn) && //process include filters - !matchesFilter(nameFormatted, filterFileEx); //process exclude filters + return matchesFilter(nameFormatted, filterFileIn) && //process include filters + !matchesFilter(nameFormatted, filterFileEx); //process exclude filters } bool NameFilter::passDirFilter(const Zstring& relDirname, bool* subObjMightMatch) const { - assert(subObjMightMatch == NULL || *subObjMightMatch == true); //check correct usage + assert(!subObjMightMatch || *subObjMightMatch == true); //check correct usage #ifdef FFS_WIN //Windows does NOT distinguish between upper/lower-case Zstring nameFormatted = relDirname; @@ -317,6 +337,17 @@ bool NameFilter::passDirFilter(const Zstring& relDirname, bool* subObjMightMatch } +bool NameFilter::isNull(const Zstring& includeFilter, const Zstring& excludeFilter) +{ + Zstring include = includeFilter; + Zstring exclude = excludeFilter; + trim(include); + trim(exclude); + + return include == Zstr("*") && exclude.empty(); + //return NameFilter(includeFilter, excludeFilter).isNull(); -> very expensive for huge lists +} + bool NameFilter::isNull() const { static NameFilter output(Zstr("*"), Zstring()); diff --git a/lib/hard_filter.h b/lib/hard_filter.h index 476f5ac1..1a9943a3 100644 --- a/lib/hard_filter.h +++ b/lib/hard_filter.h @@ -7,7 +7,7 @@ #ifndef FFS_FILTER_H_INCLUDED #define FFS_FILTER_H_INCLUDED -#include <set> +#include <vector> #include <memory> #include <wx/stream.h> #include <zen/zstring.h> @@ -88,7 +88,9 @@ public: virtual bool passFileFilter(const Zstring& relFilename) const; virtual bool passDirFilter(const Zstring& relDirname, bool* subObjMightMatch) const; + virtual bool isNull() const; + static bool isNull(const Zstring& includeFilter, const Zstring& excludeFilter); //*fast* check without expensively constructing NameFilter instance! private: friend class HardFilter; @@ -97,10 +99,10 @@ private: static FilterRef load(wxInputStream& stream); //"serial constructor" virtual bool cmpLessSameType(const HardFilter& other) const; - std::set<Zstring> filterFileIn; //upper case (windows) - std::set<Zstring> filterFolderIn; // - std::set<Zstring> filterFileEx; // - std::set<Zstring> filterFolderEx; // + std::vector<Zstring> filterFileIn; // + std::vector<Zstring> filterFolderIn; //upper case (windows) + unique items by construction + std::vector<Zstring> filterFileEx; // + std::vector<Zstring> filterFolderEx; // const Zstring includeFilterTmp; //save constructor arguments for serialization const Zstring excludeFilterTmp; // @@ -162,7 +164,7 @@ bool NullFilter::passFileFilter(const Zstring& relFilename) const inline bool NullFilter::passDirFilter(const Zstring& relDirname, bool* subObjMightMatch) const { - assert(subObjMightMatch == NULL || *subObjMightMatch == true); //check correct usage + assert(!subObjMightMatch || *subObjMightMatch == true); //check correct usage return true; } diff --git a/lib/icon_buffer.cpp b/lib/icon_buffer.cpp index 647228e3..e1518d30 100644 --- a/lib/icon_buffer.cpp +++ b/lib/icon_buffer.cpp @@ -17,9 +17,7 @@ #include <zen/win_ver.h> #elif defined FFS_LINUX -#include <giomm/file.h> -#include <gtkmm/icontheme.h> -#include <gtkmm/main.h> +#include <gtk/gtk.h> #endif using namespace zen; @@ -59,10 +57,10 @@ public: typedef GdkPixbuf* HandleType; #endif - IconHolder(HandleType handle = 0) : handle_(handle) {} //take ownership! + explicit IconHolder(HandleType handle = 0) : handle_(handle) {} //take ownership! //icon holder has value semantics! - IconHolder(const IconHolder& other) : handle_(other.handle_ == NULL ? NULL : + IconHolder(const IconHolder& other) : handle_(other.handle_ == nullptr ? nullptr : #ifdef FFS_WIN ::CopyIcon(other.handle_) #elif defined FFS_LINUX @@ -70,7 +68,7 @@ public: #endif ) {} - IconHolder(IconHolder&& other) : handle_(other.handle_) { other.handle_ = NULL; } + IconHolder(IconHolder&& other) : handle_(other.handle_) { other.handle_ = nullptr; } IconHolder& operator=(IconHolder other) //unifying assignment: no need for r-value reference optimization! { @@ -80,11 +78,11 @@ public: ~IconHolder() { - if (handle_ != NULL) + if (handle_ != nullptr) #ifdef FFS_WIN ::DestroyIcon(handle_); #elif defined FFS_LINUX - ::g_object_unref(handle_); + ::g_object_unref(handle_); //superseedes "::gdk_pixbuf_unref"! #endif } @@ -92,7 +90,7 @@ public: wxIcon toWxIcon(int expectedSize) const //copy HandleType, caller needs to take ownership! { - if (handle_ == NULL) + if (handle_ == nullptr) return wxNullIcon; IconHolder clone(*this); @@ -107,7 +105,7 @@ public: if (::GetIconInfo(clone.handle_, &icoInfo)) { ::DeleteObject(icoInfo.hbmMask); //nice potential for a GDI leak! - ZEN_ON_BLOCK_EXIT(::DeleteObject(icoInfo.hbmColor)); // + ZEN_ON_SCOPE_EXIT(::DeleteObject(icoInfo.hbmColor)); // BITMAP bmpInfo = {}; if (::GetObject(icoInfo.hbmColor, //__in HGDIOBJ hgdiobj, @@ -130,7 +128,7 @@ public: #elif defined FFS_LINUX // newIcon.SetPixbuf(clone.handle_); // transfer ownership!! #endif // - clone.handle_ = NULL; // + clone.handle_ = nullptr; // return newIcon; } @@ -140,7 +138,7 @@ private: public: //use member pointer as implicit conversion to bool (C++ Templates - Vandevoorde/Josuttis; chapter 20) - operator int ConversionToBool::* () const { return handle_ != NULL ? &ConversionToBool::dummy : NULL; } + operator int ConversionToBool::* () const { return handle_ != nullptr ? &ConversionToBool::dummy : nullptr; } }; @@ -210,13 +208,13 @@ IconHolder getIconByAttribute(LPCWSTR pszPath, DWORD dwFileAttributes, IconBuffe SHGFI_SYSICONINDEX | SHGFI_USEFILEATTRIBUTES); //no need to IUnknown::Release() imgList! if (!imgList) - return NULL; + return IconHolder(); boost::call_once(initGetIconByIndexOnce, []() //thread-safe init { getIconByIndex = DllFun<thumb::GetIconByIndexFct>(thumb::getDllName(), thumb::getIconByIndexFctName); }); - return getIconByIndex ? static_cast<HICON>(getIconByIndex(fileInfo.iIcon, getShilIconType(sz))) : NULL; + return IconHolder(getIconByIndex ? static_cast<HICON>(getIconByIndex(fileInfo.iIcon, getShilIconType(sz))) : nullptr); } @@ -243,19 +241,11 @@ IconHolder getThumbnail(const Zstring& filename, int requestedSize) //return 0 o { getThumbnailIcon = DllFun<GetThumbnailFct>(getDllName(), getThumbnailFctName); }); - return getThumbnailIcon ? static_cast< ::HICON>(getThumbnailIcon(filename.c_str(), requestedSize)) : NULL; + return IconHolder(getThumbnailIcon ? static_cast< ::HICON>(getThumbnailIcon(filename.c_str(), requestedSize)) : nullptr); #elif defined FFS_LINUX - //call Gtk::Main::init_gtkmm_internals() on application startup!! - try - { - Glib::RefPtr<Gdk::Pixbuf> iconPixbuf = Gdk::Pixbuf::create_from_file(filename.c_str(), requestedSize, requestedSize); - if (iconPixbuf) - return IconHolder(iconPixbuf->gobj_copy()); //copy and pass icon ownership (may be 0) - } - catch (const Glib::Error&) {} - - return IconHolder(); + GdkPixbuf* pixBuf = gdk_pixbuf_new_from_file_at_size(filename.c_str(), requestedSize, requestedSize, nullptr); + return IconHolder(pixBuf); //pass ownership (may be 0) #endif } @@ -276,30 +266,11 @@ IconHolder getGenericFileIcon(IconBuffer::IconSize sz) #elif defined FFS_LINUX const int requestedSize = cvrtSize(sz); - try - { - Glib::RefPtr<Gtk::IconTheme> iconTheme = Gtk::IconTheme::get_default(); - if (iconTheme) - { - Glib::RefPtr<Gdk::Pixbuf> iconPixbuf; - std::find_if(mimeFileIcons, mimeFileIcons + sizeof(mimeFileIcons) / sizeof(mimeFileIcons[0]), - [&](const char* mimeName) -> bool - { - try - { - iconPixbuf = iconTheme->load_icon(mimeName, requestedSize, Gtk::ICON_LOOKUP_USE_BUILTIN); - } - catch (const Glib::Error&) { return false; } - - return iconPixbuf; - } - ); - if (iconPixbuf) - return IconHolder(iconPixbuf->gobj_copy()); // transfer ownership!! - } - } - catch (const Glib::Error&) {} + if (GtkIconTheme* defaultTheme = gtk_icon_theme_get_default()) //not owned! + for (auto iter = std::begin(mimeFileIcons); iter != std::end(mimeFileIcons); ++iter) + if (GdkPixbuf* pixBuf = gtk_icon_theme_load_icon(defaultTheme, *iter, requestedSize, GTK_ICON_LOOKUP_USE_BUILTIN, nullptr)) + return IconHolder(pixBuf); //pass ownership (may be nullptr) return IconHolder(); #endif } @@ -343,44 +314,35 @@ IconHolder getAssociatedIcon(const Zstring& filename, IconBuffer::IconSize sz) //http://msdn.microsoft.com/en-us/library/windows/desktop/bb762185(v=vs.85).aspx if (!imgList) - return NULL; + return IconHolder(); //imgList->Release(); //empiric study: crash on XP if we release this! Seems we do not own it... -> also no GDI leak on Win7 -> okay //another comment on http://msdn.microsoft.com/en-us/library/bb762179(v=VS.85).aspx describes exact same behavior on Win7/XP - boost::call_once(initGetIconByIndexOnce, []() //thread-safe init + boost::call_once(initGetIconByIndexOnce, [] //thread-safe init { getIconByIndex = DllFun<thumb::GetIconByIndexFct>(thumb::getDllName(), thumb::getIconByIndexFctName); }); - return getIconByIndex ? static_cast<HICON>(getIconByIndex(fileInfo.iIcon, getShilIconType(sz))) : NULL; + return IconHolder(getIconByIndex ? static_cast<HICON>(getIconByIndex(fileInfo.iIcon, getShilIconType(sz))) : nullptr); #elif defined FFS_LINUX const int requestedSize = cvrtSize(sz); - //call Gtk::Main::init_gtkmm_internals() on application startup!! - try + + GFile* file = g_file_new_for_path(filename.c_str()); //never fails + ZEN_ON_SCOPE_EXIT(g_object_unref(file);) + + if (GFileInfo* fileInfo = g_file_query_info(file, G_FILE_ATTRIBUTE_STANDARD_ICON, G_FILE_QUERY_INFO_NONE, nullptr, nullptr)) { - Glib::RefPtr<Gio::File> fileObj = Gio::File::create_for_path(filename.c_str()); //never fails - Glib::RefPtr<Gio::FileInfo> fileInfo = fileObj->query_info(G_FILE_ATTRIBUTE_STANDARD_ICON); - if (fileInfo) - { - Glib::RefPtr<Gio::Icon> gicon = fileInfo->get_icon(); - if (gicon) - { - Glib::RefPtr<Gtk::IconTheme> iconTheme = Gtk::IconTheme::get_default(); - if (iconTheme) + ZEN_ON_SCOPE_EXIT(g_object_unref(fileInfo);) + + if (GIcon* gicon = g_file_info_get_icon(fileInfo)) //not owned! + if (GtkIconTheme* defaultTheme = gtk_icon_theme_get_default()) //not owned! + if (GtkIconInfo* iconInfo = gtk_icon_theme_lookup_by_gicon(defaultTheme, gicon, requestedSize, GTK_ICON_LOOKUP_USE_BUILTIN)) //this may fail if icon is not installed on system { - Gtk::IconInfo iconInfo = iconTheme->lookup_icon(gicon, requestedSize, Gtk::ICON_LOOKUP_USE_BUILTIN); //this may fail if icon is not installed on system - if (iconInfo) - { - Glib::RefPtr<Gdk::Pixbuf> iconPixbuf = iconInfo.load_icon(); //render icon into Pixbuf - if (iconPixbuf) - return IconHolder(iconPixbuf->gobj_copy()); //copy and pass icon ownership (may be 0) - } + ZEN_ON_SCOPE_EXIT(gtk_icon_info_free(iconInfo);) + if (GdkPixbuf* pixBuf = gtk_icon_info_load_icon(iconInfo, nullptr)) + return IconHolder(pixBuf); //pass ownership (may be nullptr) } - } - } } - catch (const Glib::Error&) {} - //fallback: icon lookup may fail because some icons are currently not present on system return ::getGenericFileIcon(sz); #endif @@ -450,14 +412,14 @@ typedef std::queue<Zstring> IconDbSequence; //entryName class Buffer { public: - bool requestFileIcon(const Zstring& fileName, IconHolder* icon = NULL) + bool requestFileIcon(const Zstring& fileName, IconHolder* icon = nullptr) { boost::lock_guard<boost::mutex> dummy(lockBuffer); auto iter = iconMappping.find(fileName); if (iter != iconMappping.end()) { - if (icon != NULL) + if (icon != nullptr) *icon = iter->second; return true; } @@ -518,8 +480,8 @@ void WorkerThread::operator()() //thread entry //Prerequisites, see thumbnail.h //1. Initialize COM - ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); - ZEN_ON_BLOCK_EXIT(::CoUninitialize()); + ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + ZEN_ON_SCOPE_EXIT(::CoUninitialize()); //2. Initialize system image list typedef BOOL (WINAPI* FileIconInitFun)(BOOL fRestoreCache); diff --git a/lib/icon_buffer.h b/lib/icon_buffer.h index 3f77a520..f3a358ef 100644 --- a/lib/icon_buffer.h +++ b/lib/icon_buffer.h @@ -32,7 +32,7 @@ public: int getSize() const; //*maximum* icon size in pixel - bool requestFileIcon(const Zstring& filename, wxIcon* icon = NULL); //returns false if icon is not in buffer + bool requestFileIcon(const Zstring& filename, wxIcon* icon = nullptr); //returns false if icon is not in buffer void setWorkload(const std::vector<Zstring>& load); //(re-)set new workload of icons to be retrieved; private: diff --git a/lib/localization.cpp b/lib/localization.cpp index e8867129..3c997074 100644 --- a/lib/localization.cpp +++ b/lib/localization.cpp @@ -183,7 +183,7 @@ ExistingTranslations::ExistingTranslations() for (auto i = lngFiles.begin(); i != lngFiles.end(); ++i) try { - std::string stream = loadStream(*i);; //throw XmlFileError + std::string stream = loadStream(*i); //throw XmlFileError try { lngfile::TransHeader lngHeader; @@ -193,8 +193,7 @@ ExistingTranslations::ExistingTranslations() There is some buggy behavior in wxWidgets which maps "zh_TW" to simplified chinese. Fortunately locales can be also entered as description. I changed to "Chinese (Traditional)" which works fine. */ - const wxLanguageInfo* locInfo = wxLocale::FindLanguageInfo(utf8CvrtTo<wxString>(lngHeader.localeName)); - if (locInfo) + if (const wxLanguageInfo* locInfo = wxLocale::FindLanguageInfo(utf8CvrtTo<wxString>(lngHeader.localeName))) { ExistingTranslations::Entry newEntry; newEntry.languageID = locInfo->Language; diff --git a/lib/norm_filter.h b/lib/norm_filter.h index a47fd910..dc73bc6b 100644 --- a/lib/norm_filter.h +++ b/lib/norm_filter.h @@ -29,7 +29,7 @@ NormalizedFilter normalizeFilters(const FilterConfig& global, const FilterConfig inline bool isNullFilter(const FilterConfig& filterCfg) { - return NameFilter(filterCfg.includeFilter, filterCfg.excludeFilter).isNull() && + return NameFilter::isNull(filterCfg.includeFilter, filterCfg.excludeFilter) && SoftFilter(filterCfg.timeSpan, filterCfg.unitTimeSpan, filterCfg.sizeMin, filterCfg.unitSizeMin, filterCfg.sizeMax, filterCfg.unitSizeMax).isNull(); diff --git a/lib/parallel_scan.cpp b/lib/parallel_scan.cpp index 774cbeb7..6c9fd3ee 100644 --- a/lib/parallel_scan.cpp +++ b/lib/parallel_scan.cpp @@ -88,22 +88,22 @@ DiskInfo retrieveDiskInfo(const Zstring& pathName) 0, OPEN_EXISTING, 0, - NULL); + nullptr); if (hVolume == INVALID_HANDLE_VALUE) return output; - ZEN_ON_BLOCK_EXIT(::CloseHandle(hVolume)); + ZEN_ON_SCOPE_EXIT(::CloseHandle(hVolume)); std::vector<char> buffer(sizeof(VOLUME_DISK_EXTENTS) + sizeof(DISK_EXTENT)); //reserve buffer for at most one disk! call below will then fail if volume spans multiple disks! DWORD bytesReturned = 0; if (!::DeviceIoControl(hVolume, // handle to device IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, // dwIoControlCode - NULL, // lpInBuffer + nullptr, // lpInBuffer 0, // nInBufferSize &buffer[0], // output buffer static_cast<DWORD>(buffer.size()), // size of output buffer &bytesReturned, // number of bytes returned - NULL)) // OVERLAPPED structure + nullptr)) // OVERLAPPED structure return output; const VOLUME_DISK_EXTENTS& volDisks = *reinterpret_cast<VOLUME_DISK_EXTENTS*>(&buffer[0]); @@ -254,7 +254,7 @@ public: if (activeCount >= 2) { statusText += L" " + _P("[1 Thread]", "[%x Threads]", activeCount); - replace(statusText, L"%x", toString<std::wstring>(activeCount)); + replace(statusText, L"%x", numberTo<std::wstring>(activeCount)); } statusText += std::wstring(L" \n") + L'\"' + filename + L'\"'; return statusText; @@ -481,7 +481,7 @@ public: void operator()() //thread entry { acb_->incActiveWorker(); - ZEN_ON_BLOCK_EXIT(acb_->decActiveWorker();); + ZEN_ON_SCOPE_EXIT(acb_->decActiveWorker();); std::for_each(workload_.begin(), workload_.end(), [&](std::pair<DirectoryKey, DirectoryValue*>& item) @@ -515,7 +515,7 @@ public: break; } - DstHackCallback* dstCallbackPtr = NULL; + DstHackCallback* dstCallbackPtr = nullptr; #ifdef FFS_WIN DstHackCallbackImpl dstCallback(*acb_, threadID_); dstCallbackPtr = &dstCallback; @@ -546,7 +546,7 @@ void zen::fillBuffer(const std::set<DirectoryKey>& keysToRead, //in std::vector<boost::thread> worker; //note: GCC doesn't allow to construct an array of empty threads since they would be initialized by const boost::thread& worker.reserve(buckets.size()); - zen::ScopeGuard guardWorker = zen::makeGuard([&]() + zen::ScopeGuard guardWorker = zen::makeGuard([&] { std::for_each(worker.begin(), worker.end(), [](boost::thread& wt) { wt.interrupt(); }); //interrupt all at once, then join std::for_each(worker.begin(), worker.end(), [](boost::thread& wt) { wt.join(); }); diff --git a/lib/parse_lng.h b/lib/parse_lng.h index e876c5a9..07932c3a 100644 --- a/lib/parse_lng.h +++ b/lib/parse_lng.h @@ -213,15 +213,6 @@ private: TokenMap tokens; }; -struct IsWhiteSpace : public std::unary_function<char, bool> -{ - bool operator()(char c) const - { - const unsigned char usc = c; //caveat 1: std::isspace() takes an int, but expects an unsigned char - return usc < 128 && //caveat 2: some parts of UTF-8 chars are erroneously seen as whitespace, e.g. the a0 from "\xec\x8b\a0" (MSVC) - std::isspace(usc) != 0; //[!] - } -}; class Scanner { @@ -231,7 +222,7 @@ public: Token nextToken() { //skip whitespace - pos = std::find_if(pos, stream.end(), std::not1(IsWhiteSpace())); + pos = std::find_if(pos, stream.end(), [](char c) { return !zen::isWhiteSpace(c); }); if (pos == stream.end()) return Token(Token::TK_END); @@ -289,7 +280,7 @@ private: static void normalize(std::string& text) { //remmove whitespace from end - while (!text.empty() && IsWhiteSpace()(*text.rbegin())) + while (!text.empty() && zen::isWhiteSpace(*text.rbegin())) text.resize(text.size() - 1); //ensure c-style line breaks diff --git a/lib/parse_plural.h b/lib/parse_plural.h index 297aaafc..3c5820d0 100644 --- a/lib/parse_plural.h +++ b/lib/parse_plural.h @@ -9,6 +9,7 @@ #include <list> #include <memory> +#include <functional> #include <zen/string_base.h> @@ -185,7 +186,7 @@ private: Token nextToken() { //skip whitespace - pos = std::find_if(pos, stream.end(), std::not1(std::ptr_fun(std::iswspace))); + pos = std::find_if(pos, stream.end(), [](char c) { return !zen::isWhiteSpace(c); }); if (pos == stream.end()) return Token(Token::TK_END); @@ -196,12 +197,12 @@ private: return Token(i->second); } - Wstring::const_iterator digitEnd = std::find_if(pos, stream.end(), std::not1(std::ptr_fun(std::iswdigit))); + Wstring::const_iterator digitEnd = std::find_if(pos, stream.end(), [](char c) { return !zen::isDigit(c); }); int digitCount = digitEnd - pos; if (digitCount != 0) { Token out(Token::TK_NUMBER); - out.number = zen::toNumber<int>(Wstring(&*pos, digitCount)); + out.number = zen::stringTo<int>(Wstring(&*pos, digitCount)); pos += digitCount; return out; } @@ -391,8 +392,7 @@ private: template <class T> const T& manageObj(const T& obj) { - std::shared_ptr<Expression> newEntry(new T(obj)); - dump_.push_back(newEntry); + dump_.push_back(std::make_shared<T>(obj)); return static_cast<T&>(*dump_.back()); } diff --git a/lib/process_xml.cpp b/lib/process_xml.cpp index 4ee215b9..7fc7b066 100644 --- a/lib/process_xml.cpp +++ b/lib/process_xml.cpp @@ -79,15 +79,15 @@ wxString xmlAccess::getGlobalConfigFile() void xmlAccess::OptionalDialogs::resetDialogs() { - warningDependentFolders = true; - warningMultiFolderWriteAccess = true; - warningSignificantDifference = true; - warningNotEnoughDiskSpace = true; - warningUnresolvedConflicts = true; - warningSyncDatabase = true; - warningRecyclerMissing = true; - popupOnConfigChange = true; - showSummaryBeforeSync = true; + warningDependentFolders = true; + warningMultiFolderWriteAccess = true; + warningSignificantDifference = true; + warningNotEnoughDiskSpace = true; + warningUnresolvedConflicts = true; + warningSyncDatabase = true; + warningRecyclerMissing = true; + popupOnConfigChange = true; + showSummaryBeforeSync = true; } @@ -496,21 +496,21 @@ void writeText(const UnitTime& value, std::string& output) case UTIME_NONE: output = "Inactive"; break; - // case UTIME_LAST_X_HOURS: - // output = "x-hours"; - // break; case UTIME_TODAY: output = "Today"; break; - case UTIME_THIS_WEEK: - output = "Week"; - break; + //case UTIME_THIS_WEEK: + // output = "Week"; + // break; case UTIME_THIS_MONTH: output = "Month"; break; case UTIME_THIS_YEAR: output = "Year"; break; + case UTIME_LAST_X_DAYS: + output = "x-days"; + break; } } @@ -521,16 +521,16 @@ bool readText(const std::string& input, UnitTime& value) zen::trim(tmp); if (tmp == "Inactive") value = UTIME_NONE; - // else if (tmp == "x-hours") - // value = UTIME_LAST_X_HOURS; else if (tmp == "Today") value = UTIME_TODAY; - else if (tmp == "Week") - value = UTIME_THIS_WEEK; + //else if (tmp == "Week") + // value = UTIME_THIS_WEEK; else if (tmp == "Month") value = UTIME_THIS_MONTH; else if (tmp == "Year") value = UTIME_THIS_YEAR; + else if (tmp == "x-days") + value = UTIME_LAST_X_DAYS; else return false; return true; @@ -540,13 +540,13 @@ bool readText(const std::string& input, UnitTime& value) template <> inline void writeText(const ColumnTypeRim& value, std::string& output) { - output = toString<std::string>(value); + output = numberTo<std::string>(value); } template <> inline bool readText(const std::string& input, ColumnTypeRim& value) { - value = static_cast<ColumnTypeRim>(toNumber<int>(input)); + value = static_cast<ColumnTypeRim>(stringTo<int>(input)); return true; } @@ -554,13 +554,13 @@ bool readText(const std::string& input, ColumnTypeRim& value) template <> inline void writeText(const ColumnTypeNavi& value, std::string& output) { - output = toString<std::string>(value); + output = numberTo<std::string>(value); } template <> inline bool readText(const std::string& input, ColumnTypeNavi& value) { - value = static_cast<ColumnTypeNavi>(toNumber<int>(input)); + value = static_cast<ColumnTypeNavi>(stringTo<int>(input)); return true; } @@ -740,8 +740,7 @@ void readConfig(const XmlIn& in, FolderPairEnh& enhPair) //########################################################### //alternate comp configuration (optional) - XmlIn inAltCmp = in["CompareConfig"]; - if (inAltCmp) + if (XmlIn inAltCmp = in["CompareConfig"]) { CompConfig altCmpCfg; readConfig(inAltCmp, altCmpCfg); @@ -750,8 +749,7 @@ void readConfig(const XmlIn& in, FolderPairEnh& enhPair) } //########################################################### //alternate sync configuration (optional) - XmlIn inAltSync = in["SyncConfig"]; - if (inAltSync) + if (XmlIn inAltSync = in["SyncConfig"]) { SyncConfig altSyncCfg; readConfig(inAltSync, altSyncCfg); @@ -874,6 +872,7 @@ void readConfig(const XmlIn& in, XmlGlobalSettings& config) inWnd["ManualDeletionUseRecycler"](config.gui.useRecyclerForManualDeletion); inWnd["RespectCaseOnSearch" ](config.gui.textSearchRespectCase); + inWnd["ShowIcons"](config.gui.showIcons); inWnd["IconSize"](config.gui.iconSize); //########################################################### @@ -929,7 +928,7 @@ void readConfig(const Zstring& filename, XmlType type, ConfigType& config) ::readConfig(in, config); if (in.errorsOccured()) - throw FfsXmlError(_("Error parsing configuration file:") + L"\n\"" + filename + L"\"\n\n" + + throw FfsXmlError(_("Configuration loaded partially only:") + L"\n\"" + filename + L"\"\n\n" + getErrorMessageFormatted(in), FfsXmlError::WARNING); } } @@ -1139,6 +1138,7 @@ void writeConfig(const XmlGlobalSettings& config, XmlOut& out) outWnd["ManualDeletionUseRecycler"](config.gui.useRecyclerForManualDeletion); outWnd["RespectCaseOnSearch" ](config.gui.textSearchRespectCase); + outWnd["ShowIcons"](config.gui.showIcons); outWnd["IconSize"](config.gui.iconSize); //########################################################### diff --git a/lib/process_xml.h b/lib/process_xml.h index 5abbfdc9..801deede 100644 --- a/lib/process_xml.h +++ b/lib/process_xml.h @@ -161,6 +161,7 @@ struct XmlGlobalSettings #elif defined FFS_LINUX textSearchRespectCase(true), #endif + showIcons(true), iconSize(ICON_SIZE_SMALL), lastUpdateCheck(0) { @@ -209,6 +210,7 @@ struct XmlGlobalSettings bool useRecyclerForManualDeletion; bool textSearchRespectCase; + bool showIcons; FileIconSize iconSize; long lastUpdateCheck; //time of last update check diff --git a/lib/recycler.cpp b/lib/recycler.cpp index 11ed77f7..1c743a0c 100644 --- a/lib/recycler.cpp +++ b/lib/recycler.cpp @@ -22,8 +22,9 @@ #include "IFileOperation/file_op.h" #elif defined FFS_LINUX +#include <zen/scope_guard.h> #include <sys/stat.h> -#include <giomm/file.h> +#include <gio/gio.h> #endif using namespace zen; @@ -52,7 +53,7 @@ void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw F static bool useIFileOperation = false; static boost::once_flag once = BOOST_ONCE_INIT; //caveat: function scope static initialization is not thread-safe in VS 2010! - boost::call_once(once, []() { useIFileOperation = vistaOrLater(); }); + boost::call_once(once, [] { useIFileOperation = vistaOrLater(); }); if (useIFileOperation) //new recycle bin usage: available since Vista { @@ -65,8 +66,8 @@ void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw F const DllFun<GetLastErrorFct> getLastError (getDllName(), getLastErrorFctName); if (!moveToRecycler || !getLastError) - throw FileError(_("Error moving to Recycle Bin:") + L"\n\"" + fileNames[0] + L"\"" + //report first file only... better than nothing - L"\n\n" + _("Could not load a required DLL:") + L" \"" + getDllName() + L"\""); + throw FileError(replaceCpy(_("Unable to move %x to the Recycle Bin!"), L"%x", std::wstring(L"\"") + fileNames[0] + L"\"") + L"\n\n" + //report first file only... better than nothing + replaceCpy(_("Cannot load file %x."), L"%x", std::wstring(L"\"") + getDllName() + L"\"")); //#warning moving long file paths to recycler does not work! clarify! // std::vector<Zstring> temp; @@ -76,10 +77,11 @@ void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw F if (!moveToRecycler(&fileNames[0], //array must not be empty fileNames.size())) { - wchar_t errorMessage[2000]; - getLastError(errorMessage, 2000); - throw FileError(_("Error moving to Recycle Bin:") + L"\n\"" + fileNames[0] + L"\"" + //report first file only... better than nothing - L"\n\n" + L"(" + errorMessage + L")"); + std::vector<wchar_t> msgBuffer(2000); + getLastError(&msgBuffer[0], msgBuffer.size()); + + throw FileError(replaceCpy(_("Unable to move %x to the Recycle Bin!"), L"%x", std::wstring(L"\"") + fileNames[0] + L"\"") + L"\n\n" + //report first file only... better than nothing + &msgBuffer[0]); } } else //regular recycle bin usage: available since XP @@ -95,18 +97,18 @@ void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw F } SHFILEOPSTRUCT fileOp = {}; - fileOp.hwnd = NULL; + fileOp.hwnd = nullptr; fileOp.wFunc = FO_DELETE; fileOp.pFrom = filenameDoubleNull.c_str(); - fileOp.pTo = NULL; + fileOp.pTo = nullptr; fileOp.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI; fileOp.fAnyOperationsAborted = false; - fileOp.hNameMappings = NULL; - fileOp.lpszProgressTitle = NULL; + fileOp.hNameMappings = nullptr; + fileOp.lpszProgressTitle = nullptr; if (::SHFileOperation(&fileOp) != 0 || fileOp.fAnyOperationsAborted) { - throw FileError(_("Error moving to Recycle Bin:") + L"\n\"" + filenameDoubleNull + L"\""); //report first file only... better than nothing + throw FileError(replaceCpy(_("Unable to move %x to the Recycle Bin!"), L"%x", std::wstring(L"\"") + filenameDoubleNull.c_str() + L"\"")); //report first file only... better than nothing } } } @@ -128,17 +130,20 @@ bool zen::moveToRecycleBin(const Zstring& filename) //throw FileError ::moveToWindowsRecycler(fileNames); //throw FileError #elif defined FFS_LINUX - Glib::RefPtr<Gio::File> fileObj = Gio::File::create_for_path(filename.c_str()); //never fails - try - { - if (!fileObj->trash()) - throw FileError(_("Error moving to Recycle Bin:") + L"\n\"" + filename + L"\"" + - L"\n\n" + L"(unknown error)"); - } - catch (const Glib::Error& errorObj) + GFile* file = g_file_new_for_path(filename.c_str()); //never fails according to docu + ZEN_ON_SCOPE_EXIT(g_object_unref(file);) + + GError* error = nullptr; + ZEN_ON_SCOPE_EXIT(if (error) g_error_free(error);); + + if (!g_file_trash(file, nullptr, &error)) { + if (!error) + throw FileError(replaceCpy(_("Unable to move %x to the Recycle Bin!"), L"%x", L"\"" + filename + L"\"") + L"\n\n" + + L"Unknown error."); + //implement same behavior as in Windows: if recycler is not existing, delete permanently - if (errorObj.code() == G_IO_ERROR_NOT_SUPPORTED) + if (error->code == G_IO_ERROR_NOT_SUPPORTED) { struct stat fileInfo = {}; if (::lstat(filename.c_str(), &fileInfo) != 0) @@ -152,11 +157,11 @@ bool zen::moveToRecycleBin(const Zstring& filename) //throw FileError } //assemble error message - const std::wstring errorMessage = L"Glib Error Code " + toString<std::wstring>(errorObj.code()) + /* L", " + - g_quark_to_string(errorObj.domain()) + */ L": " + utf8CvrtTo<std::wstring>(errorObj.what()); + const std::wstring errorMessage = L"Glib Error Code " + numberTo<std::wstring>(error->code) + /* L", " + + g_quark_to_string(error->domain) + */ L": " + utf8CvrtTo<std::wstring>(error->message); - throw FileError(_("Error moving to Recycle Bin:") + L"\n\"" + filename + L"\"" + - L"\n\n" + L"(" + errorMessage + L")"); + throw FileError(replaceCpy(_("Unable to move %x to the Recycle Bin!"), L"%x", L"\"" + filename + L"\"") + L"\n\n" + + errorMessage); } #endif return true; @@ -166,10 +171,11 @@ bool zen::moveToRecycleBin(const Zstring& filename) //throw FileError #ifdef FFS_WIN zen::StatusRecycler zen::recycleBinStatus(const Zstring& pathName) { - std::vector<wchar_t> buffer(MAX_PATH + 1); - if (::GetVolumePathName(applyLongPathPrefix(pathName).c_str(), //__in LPCTSTR lpszFileName, - &buffer[0], //__out LPTSTR lpszVolumePathName, - static_cast<DWORD>(buffer.size()))) //__in DWORD cchBufferLength + const DWORD bufferSize = MAX_PATH + 1; + std::vector<wchar_t> buffer(bufferSize); + if (::GetVolumePathName(pathName.c_str(), //__in LPCTSTR lpszFileName, + &buffer[0], //__out LPTSTR lpszVolumePathName, + bufferSize)) //__in DWORD cchBufferLength { Zstring rootPath = &buffer[0]; if (!endsWith(rootPath, FILE_NAME_SEPARATOR)) //a trailing backslash is required diff --git a/lib/recycler.h b/lib/recycler.h index 37b9250e..8eab5b21 100644 --- a/lib/recycler.h +++ b/lib/recycler.h @@ -19,12 +19,14 @@ namespace zen Windows ------- -Recycler always available: during runtime either SHFileOperation or (since Vista) IFileOperation will be dynamically selected +Recycler API always available: during runtime either SHFileOperation or IFileOperation (since Vista) will be dynamically selected Linux ----- -Compiler flag: `pkg-config --cflags gtkmm-2.4` -Linker flag: `pkg-config --libs gtkmm-2.4` +Compiler flags: `pkg-config --cflags gio-2.0` +Linker flags: `pkg-config --libs gio-2.0` + +Already included in package "gtk+-2.0"! */ //move a file or folder to Recycle Bin (deletes permanently if recycle is not available) diff --git a/lib/resolve_path.cpp b/lib/resolve_path.cpp index 178e70e2..1b241956 100644 --- a/lib/resolve_path.cpp +++ b/lib/resolve_path.cpp @@ -30,17 +30,17 @@ namespace Zstring resolveRelativePath(Zstring relativeName) //note: ::GetFullPathName() is documented not threadsafe! { const DWORD bufferSize = 10000; - std::vector<Zchar> fullPath(bufferSize); + std::vector<wchar_t> buffer(bufferSize); - const DWORD rv = ::GetFullPathName(applyLongPathPrefix(relativeName).c_str(), //__in LPCTSTR lpFileName, - bufferSize, //__in DWORD nBufferLength, - &fullPath[0], //__out LPTSTR lpBuffer, - NULL); //__out LPTSTR *lpFilePart - if (rv == 0 || rv >= bufferSize) //theoretically, rv can never be == bufferSize + const DWORD charsWritten = ::GetFullPathName(applyLongPathPrefix(relativeName).c_str(), //__in LPCTSTR lpFileName, + bufferSize, //__in DWORD nBufferLength, + &buffer[0], //__out LPTSTR lpBuffer, + nullptr); //__out LPTSTR *lpFilePart + if (charsWritten == 0 || charsWritten >= bufferSize) //theoretically, charsWritten can never be == bufferSize //ERROR! Don't do anything return relativeName; - return Zstring(&fullPath[0], rv); + return Zstring(&buffer[0], charsWritten); } #elif defined FFS_LINUX @@ -52,7 +52,7 @@ Zstring resolveRelativePath(const Zstring& relativeName) if (!startsWith(relativeName, FILE_NAME_SEPARATOR)) //absolute names are exactly those starting with a '/' { std::vector<char> buffer(10000); - if (::getcwd(&buffer[0], buffer.size()) != NULL) + if (::getcwd(&buffer[0], buffer.size()) != nullptr) { Zstring workingDir = &buffer[0]; if (!endsWith(workingDir, FILE_NAME_SEPARATOR)) @@ -64,10 +64,10 @@ Zstring resolveRelativePath(const Zstring& relativeName) return relativeName; /* - char* absPath = ::realpath(relativeName.c_str(), NULL); + char* absPath = ::realpath(relativeName.c_str(), nullptr); if (!absPath) return relativeName; //ERROR! Don't do anything - ZEN_ON_BLOCK_EXIT(::free(absPath)); + ZEN_ON_SCOPE_EXIT(::free(absPath)); return Zstring(absPath); */ @@ -93,9 +93,9 @@ private: auto addCsidl = [&](int csidl, const Zstring& paramName) { wchar_t buffer[MAX_PATH]; - if (SUCCEEDED(::SHGetFolderPath(NULL, //__in HWND hwndOwner, + if (SUCCEEDED(::SHGetFolderPath(nullptr, //__in HWND hwndOwner, csidl | CSIDL_FLAG_DONT_VERIFY, //__in int nFolder, - NULL, //__in HANDLE hToken, + nullptr, //__in HANDLE hToken, 0 /* == SHGFP_TYPE_CURRENT*/, //__in DWORD dwFlags, buffer))) //__out LPTSTR pszPath { @@ -294,41 +294,44 @@ Zstring volumenNameToPath(const Zstring& volumeName) //return empty string on er HANDLE hVol = ::FindFirstVolume(&volGuid[0], static_cast<DWORD>(volGuid.size())); if (hVol != INVALID_HANDLE_VALUE) { - ZEN_ON_BLOCK_EXIT(::FindVolumeClose(hVol)); + ZEN_ON_SCOPE_EXIT(::FindVolumeClose(hVol)); do { std::vector<wchar_t> volName(MAX_PATH + 1); - if (::GetVolumeInformation(&volGuid[0], //__in_opt LPCTSTR lpRootPathName, - &volName[0], //__out LPTSTR lpVolumeNameBuffer, + if (::GetVolumeInformation(&volGuid[0], //__in_opt LPCTSTR lpRootPathName, + &volName[0], //__out LPTSTR lpVolumeNameBuffer, static_cast<DWORD>(volName.size()), //__in DWORD nVolumeNameSize, - NULL, //__out_opt LPDWORD lpVolumeSerialNumber, - NULL, //__out_opt LPDWORD lpMaximumComponentLength, - NULL, //__out_opt LPDWORD lpFileSystemFlags, - NULL, //__out LPTSTR lpFileSystemNameBuffer, - 0)) //__in DWORD nFileSystemNameSize + nullptr, //__out_opt LPDWORD lpVolumeSerialNumber, + nullptr, //__out_opt LPDWORD lpMaximumComponentLength, + nullptr, //__out_opt LPDWORD lpFileSystemFlags, + nullptr, //__out LPTSTR lpFileSystemNameBuffer, + 0)) //__in DWORD nFileSystemNameSize { if (EqualFilename()(volumeName, Zstring(&volName[0]))) { //GetVolumePathNamesForVolumeName is not available for Windows 2000! typedef BOOL (WINAPI* GetVolumePathNamesForVolumeNameWFunc)(LPCWSTR lpszVolumeName, - LPWCH lpszVolumePathNames, - DWORD cchBufferLength, + LPWCH lpszVolumePathNames, + DWORD cchBufferLength, PDWORD lpcchReturnLength); const SysDllFun<GetVolumePathNamesForVolumeNameWFunc> getVolumePathNamesForVolumeName(L"kernel32.dll", "GetVolumePathNamesForVolumeNameW"); if (getVolumePathNamesForVolumeName) { - std::vector<wchar_t> volPath(10000); - + std::vector<wchar_t> buffer(10000); DWORD returnedLen = 0; - if (getVolumePathNamesForVolumeName(&volGuid[0], //__in LPCTSTR lpszVolumeName, - &volPath[0], //__out LPTSTR lpszVolumePathNames, - static_cast<DWORD>(volPath.size()), //__in DWORD cchBufferLength, - &returnedLen)) //__out PDWORD lpcchReturnLength + if (getVolumePathNamesForVolumeName(&volGuid[0], //__in LPCTSTR lpszVolumeName, + &buffer[0], //__out LPTSTR lpszVolumePathNames, + static_cast<DWORD>(buffer.size()), //__in DWORD cchBufferLength, + &returnedLen)) //__out PDWORD lpcchReturnLength { - return &volPath[0]; //return first path name in double-null terminated list! + //Attention: in contrast to documentation, this function may write a *single* 0 into + //buffer if volGuid does not have any associated volume paths (e.g. a hidden volume) + const Zstring volPath(&buffer[0]); + if (!volPath.empty()) + return volPath; //return first path name in double-null terminated list! } } return &volGuid[0]; //GUID looks ugly, but should be working correctly @@ -364,10 +367,10 @@ Zstring volumePathToName(const Zstring& volumePath) //return empty string on err if (::GetVolumeInformation(volumePath.c_str(), //__in_opt LPCTSTR lpRootPathName, &volName[0], //__out LPTSTR lpVolumeNameBuffer, bufferSize, //__in DWORD nVolumeNameSize, - NULL, //__out_opt LPDWORD lpVolumeSerialNumber, - NULL, //__out_opt LPDWORD lpMaximumComponentLength, - NULL, //__out_opt LPDWORD lpFileSystemFlags, - NULL, //__out LPTSTR lpFileSystemNameBuffer, + nullptr, //__out_opt LPDWORD lpVolumeSerialNumber, + nullptr, //__out_opt LPDWORD lpMaximumComponentLength, + nullptr, //__out_opt LPDWORD lpFileSystemFlags, + nullptr, //__out LPTSTR lpFileSystemNameBuffer, 0)) //__in DWORD nFileSystemNameSize { return &volName[0]; @@ -612,8 +615,8 @@ void zen::loginNetworkShare(const Zstring& dirnameOrig, bool allowUserInteractio //note: following function call may block heavily if network is not reachable!!! DWORD rv2 = ::WNetAddConnection2(&trgRes, // __in LPNETRESOURCE lpNetResource, - NULL, // __in LPCTSTR lpPassword, - NULL, // __in LPCTSTR lpUsername, + nullptr, // __in LPCTSTR lpPassword, + nullptr, // __in LPCTSTR lpUsername, allowUserInteraction ? CONNECT_INTERACTIVE : 0); //__in DWORD dwFlags if (rv2 == NO_ERROR) return; //mapping reestablished @@ -647,8 +650,8 @@ void zen::loginNetworkShare(const Zstring& dirnameOrig, bool allowUserInteractio //note: following function call may block heavily if network is not reachable!!! DWORD rv2 = ::WNetAddConnection2(&trgRes, // __in LPNETRESOURCE lpNetResource, - NULL, // __in LPCTSTR lpPassword, - NULL, // __in LPCTSTR lpUsername, + nullptr, // __in LPCTSTR lpPassword, + nullptr, // __in LPCTSTR lpUsername, allowUserInteraction ? CONNECT_INTERACTIVE : 0); //__in DWORD dwFlags if (rv2 == NO_ERROR) return; //mapping reestablished @@ -661,7 +664,7 @@ void zen::loginNetworkShare(const Zstring& dirnameOrig, bool allowUserInteractio DWORD bufferSize = sizeof(NETRESOURCE) + 20000; std::vector<char> buffer(bufferSize); - LPTSTR relPath = NULL; + LPTSTR relPath = nullptr; //note: following function call may block heavily if network is not reachable!!! const DWORD rv = WNetGetResourceInformation(&nr, // __in LPNETRESOURCE lpNetResource, @@ -680,8 +683,8 @@ void zen::loginNetworkShare(const Zstring& dirnameOrig, bool allowUserInteractio { //note: following function call may block heavily if network is not reachable!!! DWORD rv2 = ::WNetAddConnection2(&trgRes, // __in LPNETRESOURCE lpNetResource, - NULL, // __in LPCTSTR lpPassword, - NULL, // __in LPCTSTR lpUsername, + nullptr, // __in LPCTSTR lpPassword, + nullptr, // __in LPCTSTR lpUsername, allowUserInteraction ? CONNECT_INTERACTIVE : 0); //__in DWORD dwFlags if (rv2 == NO_ERROR) return; //mapping reestablished diff --git a/lib/resolve_path.h b/lib/resolve_path.h index 2fd5008e..bc74441a 100644 --- a/lib/resolve_path.h +++ b/lib/resolve_path.h @@ -12,6 +12,7 @@ namespace zen { +//resolve environment variables, relative paths, ect. and append file name separator Zstring getFormattedDirectoryName(const Zstring& dirString); //throw() - non-blocking! no I/O! #ifdef FFS_WIN diff --git a/lib/resources.cpp b/lib/resources.cpp index e47065e6..f5def2c6 100644 --- a/lib/resources.cpp +++ b/lib/resources.cpp @@ -46,18 +46,19 @@ void loadAnimFromZip(wxZipInputStream& zipInput, wxAnimation& anim) GlobalResources::GlobalResources() { - wxFFileInputStream input(toWx(zen::getResourceDir()) + wxT("Resources.zip")); + wxFFileInputStream input(toWx(zen::getResourceDir()) + L"Resources.zip"); if (input.IsOk()) //if not... we don't want to react too harsh here { //activate support for .png files wxImage::AddHandler(new wxPNGHandler); //ownership passed - wxZipInputStream resourceFile(input); + wxZipInputStream resourceFile(input, wxConvUTF8); + //do NOT rely on wxConvLocal! May result in "Cannot convert from the charset 'Unknown encoding (-1)'!" while (true) { std::unique_ptr<wxZipEntry> entry(resourceFile.GetNextEntry()); //take ownership! - if (entry.get() == NULL) + if (entry.get() == nullptr) break; const wxString name = entry->GetName(); diff --git a/lib/shadow.cpp b/lib/shadow.cpp index d00aa2f3..0a34ae5a 100644 --- a/lib/shadow.cpp +++ b/lib/shadow.cpp @@ -20,7 +20,6 @@ namespace { bool runningWOW64() //test if process is running under WOW64 (reference http://msdn.microsoft.com/en-us/library/ms684139(VS.85).aspx) { - //dynamically load windows API function typedef BOOL (WINAPI* IsWow64ProcessFun)(HANDLE hProcess, PBOOL Wow64Process); const SysDllFun<IsWow64ProcessFun> isWow64Process(L"kernel32.dll", "IsWow64Process"); @@ -47,41 +46,36 @@ public: getShadowVolume (getDllName(), getShadowVolumeFctName), backupHandle(nullptr) { - //check if shadow copy dll was loaded correctly - if (!createShadowCopy || !releaseShadowCopy || !getShadowVolume) - throw FileError(_("Error accessing Volume Shadow Copy Service!") + L"\n" + - _("Could not load a required DLL:") + L" \"" + getDllName() + L"\""); - //VSS does not support running under WOW64 except for Windows XP and Windows Server 2003 //(Reference: http://msdn.microsoft.com/en-us/library/aa384627(VS.85).aspx) if (runningWOW64()) throw FileError(_("Error accessing Volume Shadow Copy Service!") + L"\n" + _("Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.")); + + //check if shadow copy dll was loaded correctly + if (!createShadowCopy || !releaseShadowCopy || !getShadowVolume) + throw FileError(_("Error accessing Volume Shadow Copy Service!") + L"\n" + + replaceCpy(_("Cannot load file %x."), L"%x", std::wstring(L"\"") + getDllName() + L"\"")); + //--------------------------------------------------------------------------------------------------------- //start shadow volume copy service: - wchar_t errorMessage[1000]; + const unsigned int BUFFER_SIZE = 10000; + std::vector<wchar_t> msgBuffer(BUFFER_SIZE); backupHandle = createShadowCopy(volumeNameFormatted.c_str(), - errorMessage, - 1000); + &msgBuffer[0], BUFFER_SIZE); if (!backupHandle) throw FileError(_("Error accessing Volume Shadow Copy Service!") + L"\n" + - L"(" + errorMessage + L" Volume: \"" + volumeNameFormatted + L"\")"); + &msgBuffer[0] + L" Volume: \"" + volumeNameFormatted + L"\""); - wchar_t shadowVolName[1000]; - getShadowVolume(backupHandle, shadowVolName, 1000); - shadowVol = Zstring(shadowVolName) + FILE_NAME_SEPARATOR; //shadowVolName NEVER has a trailing backslash + std::vector<wchar_t> volBuffer(BUFFER_SIZE); + getShadowVolume(backupHandle, &volBuffer[0], BUFFER_SIZE); + shadowVol = Zstring(&volBuffer[0]) + FILE_NAME_SEPARATOR; //shadowVolName NEVER has a trailing backslash } - ~ShadowVolume() - { - releaseShadowCopy(backupHandle); //fast! no performance optimization necessary - } + ~ShadowVolume() { releaseShadowCopy(backupHandle); } //fast! no performance optimization necessary - Zstring getShadowVolumeName() const //trailing path separator - { - return shadowVol; - } + Zstring getShadowVolumeName() const { return shadowVol; } //with trailing path separator private: ShadowVolume(const ShadowVolume&); @@ -100,14 +94,13 @@ private: Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile) { - wchar_t volumeNameRaw[1000]; - + std::vector<wchar_t> volBuffer(1000); if (!::GetVolumePathName(inputFile.c_str(), //__in LPCTSTR lpszFileName, - volumeNameRaw, //__out LPTSTR lpszVolumePathName, - 1000)) //__in DWORD cchBufferLength - throw FileError(_("Could not determine volume name for file:") + L"\n\"" + inputFile + L"\""); + &volBuffer[0], //__out LPTSTR lpszVolumePathName, + static_cast<DWORD>(volBuffer.size()))) //__in DWORD cchBufferLength + throw FileError(_("Cannot determine volume name for file:") + L"\n\"" + inputFile + L"\""); - Zstring volumeNameFormatted = volumeNameRaw; + Zstring volumeNameFormatted = &volBuffer[0]; if (!endsWith(volumeNameFormatted, FILE_NAME_SEPARATOR)) volumeNameFormatted += FILE_NAME_SEPARATOR; @@ -115,7 +108,7 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile) const size_t pos = inputFile.find(volumeNameFormatted); //inputFile needs NOT to begin with volumeNameFormatted: consider for example \\?\ prefix! if (pos == Zstring::npos) { - std::wstring msg = _("Volume name %x not part of filename %y!"); + std::wstring msg = _("Volume name %x not part of file name %y!"); replace(msg, L"%x", std::wstring(L"\"") + volumeNameFormatted + L"\"", false); replace(msg, L"%y", std::wstring(L"\"") + inputFile + L"\"", false); throw FileError(msg); @@ -125,7 +118,7 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile) VolNameShadowMap::const_iterator iter = shadowVol.find(volumeNameFormatted); if (iter == shadowVol.end()) { - std::shared_ptr<ShadowVolume> newEntry(new ShadowVolume(volumeNameFormatted)); + auto newEntry = std::make_shared<ShadowVolume>(volumeNameFormatted); iter = shadowVol.insert(std::make_pair(volumeNameFormatted, newEntry)).first; } diff --git a/lib/statistics.cpp b/lib/statistics.cpp index 9914d455..7b3bceae 100644 --- a/lib/statistics.cpp +++ b/lib/statistics.cpp @@ -6,14 +6,13 @@ #include "statistics.h" -#include <wx/ffile.h> -#include <zen/basic_math.h> -#include "status_handler.h" -#include <wx+/format_unit.h> #include <limits> +#include <wx/ffile.h> #include <wx/stopwatch.h> +#include <zen/basic_math.h> #include <zen/assert_static.h> #include <zen/i18n.h> +#include <wx+/format_unit.h> using namespace zen; @@ -29,11 +28,11 @@ RetrieveStatistics::~RetrieveStatistics() std::for_each(data.begin(), data.end(), [&](const StatEntry& entry) { - outputFile.Write(toString<wxString>(entry.time)); + outputFile.Write(numberTo<wxString>(entry.time)); outputFile.Write(wxT(";")); - outputFile.Write(toString<wxString>(entry.objects)); + outputFile.Write(numberTo<wxString>(entry.objects)); outputFile.Write(wxT(";")); - outputFile.Write(toString<wxString>(entry.value)); + outputFile.Write(numberTo<wxString>(entry.value)); outputFile.Write(wxT("\n")); }); } diff --git a/lib/status_handler.h b/lib/status_handler.h index a37d2257..b246e49c 100644 --- a/lib/status_handler.h +++ b/lib/status_handler.h @@ -7,6 +7,7 @@ #ifndef STATUSHANDLER_H_INCLUDED #define STATUSHANDLER_H_INCLUDED +#include "../process_callback.h" #include <string> #include <zen/int64.h> @@ -19,64 +20,9 @@ void updateUiNow(); //do the updating Updating GUI is fast! time per single call to ProcessCallback::forceUiRefresh() - Comparison 25 µs - - Synchronization 0.6 ms (despite complex graph!) + - Synchronization 0.6 ms (despite complex graph control!) */ -//interfaces for status updates (can be implemented by GUI or Batch mode) - - -//report status during comparison and synchronization -struct ProcessCallback -{ - virtual ~ProcessCallback() {} - - //identifiers of different phases - enum Process - { - PROCESS_NONE = 10, - PROCESS_SCANNING, - PROCESS_COMPARING_CONTENT, - PROCESS_SYNCHRONIZING - }; - - //these methods have to be implemented in the derived classes to handle error and status information - virtual void initNewProcess(int objectsTotal, zen::Int64 dataTotal, Process processID) = 0; //informs about the total amount of data that will be processed from now on - - //note: this one must NOT throw in order to properly allow undoing setting of statistics! - //it is in general paired with a call to requestUiRefresh() to compensate! - virtual void updateProcessedData(int objectsDelta, zen::Int64 dataDelta) = 0; //throw()!! - virtual void updateTotalData (int objectsDelta, zen::Int64 dataDelta) = 0; // - /*the estimated total may change *during* sync: - 1. move file -> fallback to copy + delete - 2. file copy, actual size changed after comparison - 3. auto-resolution for failed create operations due to missing source - 4. directory deletion: may contain more items than scanned by FFS: excluded by filter - 5. delete directory to recycler or move to user-defined dir on same volume: no matter how many sub-elements exist, this is only 1 object to process! - 6. user-defined deletion directory on different volume: full file copy required (instead of move) */ - - //opportunity to abort must be implemented in a frequently executed method like requestUiRefresh() - virtual void requestUiRefresh() = 0; //throw ? - virtual void forceUiRefresh () = 0; //throw ? - call before starting long running task which doesn't update regularly - - //called periodically after data was processed: expected(!) to request GUI update - virtual void reportStatus(const std::wstring& text) = 0; //status info only, should not be logged! - - //called periodically after data was processed: expected(!) to request GUI update - virtual void reportInfo(const std::wstring& text) = 0; - - virtual void reportWarning(const std::wstring& warningMessage, bool& warningActive) = 0; - - //error handling: - enum Response - { - IGNORE_ERROR = 10, - RETRY - }; - virtual Response reportError (const std::wstring& errorMessage) = 0; //recoverable error situation - virtual void reportFatalError(const std::wstring& errorMessage) = 0; //non-recoverable error situation -}; - - //gui may want to abort process struct AbortCallback { @@ -108,6 +54,4 @@ private: bool abortRequested; }; - - #endif // STATUSHANDLER_H_INCLUDED diff --git a/lib/status_handler_impl.h b/lib/status_handler_impl.h new file mode 100644 index 00000000..7141d75c --- /dev/null +++ b/lib/status_handler_impl.h @@ -0,0 +1,34 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) ZenJu (zhnmju123 AT gmx DOT de) - All Rights Reserved * +// ************************************************************************** + +#ifndef STATUSHANDLER_IMPL_H_INCLUDED +#define STATUSHANDLER_IMPL_H_INCLUDED + +#include <zen/file_error.h> +#include "status_handler.h" + +template <typename Function> inline +bool tryReportingError(Function cmd, ProcessCallback& handler) //return "true" on success, "false" if error was ignored +{ + for (;;) + try + { + cmd(); //throw FileError + return true; + } + catch (zen::FileError& error) + { + switch (handler.reportError(error.toString())) //may throw! + { + case ProcessCallback::IGNORE_ERROR: + return false; + case ProcessCallback::RETRY: + break; //continue with loop + } + } +} + +#endif //STATUSHANDLER_IMPL_H_INCLUDED diff --git a/lib/xml_base.cpp b/lib/xml_base.cpp index e6b1e840..10bb698a 100644 --- a/lib/xml_base.cpp +++ b/lib/xml_base.cpp @@ -63,13 +63,17 @@ void xmlAccess::loadXmlDocument(const Zstring& filename, XmlDoc& doc) //throw Ff const std::wstring xmlAccess::getErrorMessageFormatted(const XmlIn& in) { - std::wstring errorMessage = _("Could not read values for the following XML nodes:") + L"\n"; + std::wstring msg; - std::vector<std::wstring> failedNodes = in.getErrorsAs<std::wstring>(); - std::for_each(failedNodes.begin(), failedNodes.end(), - [&](const std::wstring& str) { errorMessage += str + L'\n'; }); + const auto& failedElements = in.getErrorsAs<std::wstring>(); + if (!failedElements.empty()) + { + msg = _("Cannot read the following XML elements:") + L"\n"; + std::for_each(failedElements.begin(), failedElements.end(), + [&](const std::wstring& str) { msg += str + L'\n'; }); + } - return errorMessage; + return msg; } diff --git a/process_callback.h b/process_callback.h new file mode 100644 index 00000000..77b2987f --- /dev/null +++ b/process_callback.h @@ -0,0 +1,67 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) ZenJu (zhnmju123 AT gmx DOT de) - All Rights Reserved * +// ************************************************************************** + +#ifndef PROC_HEADER_48257827842345454545 +#define PROC_HEADER_48257827842345454545 + +#include <string> +#include <zen/int64.h> + +//interface for comparison and synchronization process status updates (used by GUI or Batch mode) + + +//report status during comparison and synchronization +struct ProcessCallback +{ + virtual ~ProcessCallback() {} + + //identifiers of different phases + enum Process + { + PROCESS_NONE = 10, + PROCESS_SCANNING, + PROCESS_COMPARING_CONTENT, + PROCESS_SYNCHRONIZING + }; + + //these methods have to be implemented in the derived classes to handle error and status information + virtual void initNewProcess(int objectsTotal, zen::Int64 dataTotal, Process processID) = 0; //informs about the total amount of data that will be processed from now on + + //note: this one must NOT throw in order to properly allow undoing setting of statistics! + //it is in general paired with a call to requestUiRefresh() to compensate! + virtual void updateProcessedData(int objectsDelta, zen::Int64 dataDelta) = 0; //throw()!! + virtual void updateTotalData (int objectsDelta, zen::Int64 dataDelta) = 0; // + /*the estimated total may change *during* sync: + 1. move file -> fallback to copy + delete + 2. file copy, actual size changed after comparison + 3. auto-resolution for failed create operations due to missing source + 4. directory deletion: may contain more items than scanned by FFS: excluded by filter + 5. delete directory to recycler or move to user-defined dir on same volume: no matter how many sub-elements exist, this is only 1 object to process! + 6. user-defined deletion directory on different volume: full file copy required (instead of move) */ + + //opportunity to abort must be implemented in a frequently executed method like requestUiRefresh() + virtual void requestUiRefresh() = 0; //throw ? + virtual void forceUiRefresh () = 0; //throw ? - call before starting long running task which doesn't update regularly + + //called periodically after data was processed: expected(!) to request GUI update + virtual void reportStatus(const std::wstring& text) = 0; //UI info only, should not be logged! + + //called periodically after data was processed: expected(!) to request GUI update + virtual void reportInfo(const std::wstring& text) = 0; + + virtual void reportWarning(const std::wstring& warningMessage, bool& warningActive) = 0; + + //error handling: + enum Response + { + IGNORE_ERROR = 10, + RETRY + }; + virtual Response reportError (const std::wstring& errorMessage) = 0; //recoverable error situation + virtual void reportFatalError(const std::wstring& errorMessage) = 0; //non-recoverable error situation +}; + +#endif //PROC_HEADER_48257827842345454545
\ No newline at end of file diff --git a/resource.rc b/resource.rc index 1fbcc7f6..093036e9 100644 --- a/resource.rc +++ b/resource.rc @@ -19,11 +19,11 @@ BEGIN BEGIN BLOCK "FFFF04B0" BEGIN - VALUE "FileDescription", "FreeFileSync - Open Source Synchronization Software\0" + VALUE "FileDescription", "Folder Comparison and Synchronization\0" VALUE "FileVersion", VER_FREEFILESYNC_STR VALUE "ProductName", "FreeFileSync\0" VALUE "ProductVersion", VER_FREEFILESYNC_STR - VALUE "LegalCopyright", "(c) 2008 - 2011 ZenJu\0" + VALUE "LegalCopyright", "ZenJu - All Rights Reserved\0" END END BLOCK "VarFileInfo" diff --git a/structures.cpp b/structures.cpp index c53fc454..0a7eda2b 100644 --- a/structures.cpp +++ b/structures.cpp @@ -9,6 +9,7 @@ #include <stdexcept> #include <ctime> #include <zen/i18n.h> +#include <zen/time.h> using namespace zen; @@ -220,58 +221,63 @@ int daysSinceBeginOfWeek(int dayOfWeek) //0-6, 0=Monday, 6=Sunday return dayOfWeek; //let all weeks begin with monday } -zen::Int64 resolve(size_t value, UnitTime unit, zen::Int64 defaultVal) + +Int64 resolve(size_t value, UnitTime unit, Int64 defaultVal) { - const time_t utcTimeNow = ::time(NULL); - struct tm* localTimeFmt = ::localtime (&utcTimeNow); //utc to local + TimeComp locTimeStruc = zen::localTime(); switch (unit) { case UTIME_NONE: return defaultVal; - - // case UTIME_LAST_X_HOURS: - // return Int64(utcTimeNow) - Int64(value) * 3600; - + case UTIME_TODAY: - localTimeFmt->tm_sec = 0; //0-61 - localTimeFmt->tm_min = 0; //0-59 - localTimeFmt->tm_hour = 0; //0-23 - return ::mktime(localTimeFmt); //convert local time back to UTC + locTimeStruc.second = 0; //0-61 + locTimeStruc.minute = 0; //0-59 + locTimeStruc.hour = 0; //0-23 + return localToTimeT(locTimeStruc); //convert local time back to UTC - case UTIME_THIS_WEEK: - { - localTimeFmt->tm_sec = 0; //0-61 - localTimeFmt->tm_min = 0; //0-59 - localTimeFmt->tm_hour = 0; //0-23 - const time_t timeFrom = ::mktime(localTimeFmt); + //case UTIME_THIS_WEEK: + //{ + // localTimeFmt->tm_sec = 0; //0-61 + // localTimeFmt->tm_min = 0; //0-59 + // localTimeFmt->tm_hour = 0; //0-23 + // const time_t timeFrom = ::mktime(localTimeFmt); - int dayOfWeek = (localTimeFmt->tm_wday + 6) % 7; //tm_wday := days since Sunday 0-6 - // +6 == -1 in Z_7 + // int dayOfWeek = (localTimeFmt->tm_wday + 6) % 7; //tm_wday := days since Sunday 0-6 + // // +6 == -1 in Z_7 + + // return Int64(timeFrom) - daysSinceBeginOfWeek(dayOfWeek) * 24 * 3600; + //} - return Int64(timeFrom) - daysSinceBeginOfWeek(dayOfWeek) * 24 * 3600; - } case UTIME_THIS_MONTH: - localTimeFmt->tm_sec = 0; //0-61 - localTimeFmt->tm_min = 0; //0-59 - localTimeFmt->tm_hour = 0; //0-23 - localTimeFmt->tm_mday = 1; //1-31 - return ::mktime(localTimeFmt); //convert local time back to UTC + locTimeStruc.second = 0; //0-61 + locTimeStruc.minute = 0; //0-59 + locTimeStruc.hour = 0; //0-23 + locTimeStruc.day = 1; //1-31 + return localToTimeT(locTimeStruc); case UTIME_THIS_YEAR: - localTimeFmt->tm_sec = 0; //0-61 - localTimeFmt->tm_min = 0; //0-59 - localTimeFmt->tm_hour = 0; //0-23 - localTimeFmt->tm_mday = 1; //1-31 - localTimeFmt->tm_mon = 0; //0-11 - return ::mktime(localTimeFmt); //convert local time back to UTC + locTimeStruc.second = 0; //0-61 + locTimeStruc.minute = 0; //0-59 + locTimeStruc.hour = 0; //0-23 + locTimeStruc.day = 1; //1-31 + locTimeStruc.month = 1; //1-12 + return localToTimeT(locTimeStruc); + + case UTIME_LAST_X_DAYS: + locTimeStruc.second = 0; //0-61 + locTimeStruc.minute = 0; //0-59 + locTimeStruc.hour = 0; //0-23 + return localToTimeT(locTimeStruc) - Int64(value) * 24 * 3600; } assert(false); - return utcTimeNow; + return localToTimeT(locTimeStruc); } -zen::UInt64 resolve(size_t value, UnitSize unit, zen::UInt64 defaultVal) + +UInt64 resolve(size_t value, UnitSize unit, UInt64 defaultVal) { double out = 0; switch (unit) diff --git a/structures.h b/structures.h index 5d79862f..39d6c03a 100644 --- a/structures.h +++ b/structures.h @@ -251,11 +251,11 @@ enum UnitSize enum UnitTime { UTIME_NONE, - //UTIME_LAST_X_HOURS, UTIME_TODAY, - UTIME_THIS_WEEK, + // UTIME_THIS_WEEK, UTIME_THIS_MONTH, - UTIME_THIS_YEAR + UTIME_THIS_YEAR, + UTIME_LAST_X_DAYS }; struct FilterConfig diff --git a/synchronization.cpp b/synchronization.cpp index 10ec2f5a..1528ac27 100644 --- a/synchronization.cpp +++ b/synchronization.cpp @@ -14,7 +14,6 @@ #include <wx+/string_conv.h> #include <wx+/format_unit.h> #include <zen/scope_guard.h> -#include "lib/status_handler.h" #include <zen/file_handling.h> #include "lib/resolve_path.h" #include "lib/recycler.h" @@ -23,6 +22,7 @@ #include "lib/cmp_filetime.h" #include <zen/file_io.h> #include <zen/time.h> +#include "lib/status_handler_impl.h" #ifdef FFS_WIN #include <zen/long_path_prefix.h> @@ -338,31 +338,6 @@ FolderPairSyncCfg::FolderPairSyncCfg(bool automaticMode, custDelFolder(zen::getFormattedDirectoryName(custDelDir)) {} //----------------------------------------------------------------------------------------------------------- - -template <typename Function> inline -bool tryReportingError(ProcessCallback& handler, Function cmd) //return "true" on success, "false" if error was ignored -{ - while (true) - { - try - { - cmd(); //throw FileError - return true; - } - catch (FileError& error) - { - ProcessCallback::Response rv = handler.reportError(error.toString()); //may throw! - if (rv == ProcessCallback::IGNORE_ERROR) - return false; - else if (rv == ProcessCallback::RETRY) - ; //continue with loop - else - throw std::logic_error("Programming Error: Unknown return value!"); - } - } -} - - /* add some postfix to alternate deletion directory: deletionDirectory\<prefix>2010-06-30 12-59-12\ */ @@ -383,7 +358,7 @@ Zstring getSessionDeletionDir(const Zstring& deletionDirectory, const Zstring& p //ensure uniqueness for (int i = 1; zen::somethingExists(output); ++i) - output = formattedDir + Zchar('_') + toString<Zstring>(i); + output = formattedDir + Zchar('_') + numberTo<Zstring>(i); output += FILE_NAME_SEPARATOR; return output; @@ -422,7 +397,7 @@ public: void tryCleanup(); //throw FileError -> call this in non-exceptional coding, i.e. somewhere after sync! void removeFile (const Zstring& relativeName) const; //throw FileError - void removeFolder(const Zstring& relativeName) const { removeFolderInt(relativeName, NULL, NULL); }; //throw FileError + void removeFolder(const Zstring& relativeName) const { removeFolderInt(relativeName, nullptr, nullptr); }; //throw FileError void removeFolderUpdateStatistics(const Zstring& relativeName, int objectsExpected, Int64 dataExpected) const { removeFolderInt(relativeName, &objectsExpected, &dataExpected); }; //throw FileError //in contrast to "removeFolder()" this function will update statistics! @@ -636,7 +611,7 @@ void DeletionHandling::removeFile(const Zstring& relativeName) const case MOVE_TO_CUSTOM_DIRECTORY: { - CallbackMoveFileImpl callBack(*procCallback_, *this, NULL); //we do *not* report statistics in this method + CallbackMoveFileImpl callBack(*procCallback_, *this, nullptr); //we do *not* report statistics in this method const Zstring targetFile = sessionDelDir + relativeName; //ends with path separator try //... to get away cheaply! @@ -673,7 +648,7 @@ void DeletionHandling::removeFolderInt(const Zstring& relativeName, const int* o { case DELETE_PERMANENTLY: { - CallbackRemoveDirImpl remDirCallback(*procCallback_, *this, objectsExpected ? &objectsReported : NULL); + CallbackRemoveDirImpl remDirCallback(*procCallback_, *this, objectsExpected ? &objectsReported : nullptr); removeDirectory(fullName, &remDirCallback); } break; @@ -716,7 +691,7 @@ void DeletionHandling::removeFolderInt(const Zstring& relativeName, const int* o case MOVE_TO_CUSTOM_DIRECTORY: { - CallbackMoveFileImpl callBack(*procCallback_, *this, objectsExpected ? &objectsReported : NULL); + CallbackMoveFileImpl callBack(*procCallback_, *this, objectsExpected ? &objectsReported : nullptr); const Zstring targetDir = sessionDelDir + relativeName; try //... to get away cheaply! @@ -1009,8 +984,8 @@ namespace template <class Mapping> inline bool haveNameClash(const Zstring& shortname, Mapping& m) { - return std::find_if(m.begin(), m.end(), - [&](const typename Mapping::value_type& obj) { return EqualFilename()(obj.getObjShortName(), shortname); }) != m.end(); + return std::any_of(m.begin(), m.end(), + [&](const typename Mapping::value_type& obj) { return EqualFilename()(obj.getObjShortName(), shortname); }); } @@ -1020,7 +995,7 @@ Zstring findUniqueTempName(const Zstring& filename) //ensure uniqueness for (int i = 1; somethingExists(output); ++i) - output = filename + Zchar('_') + toString<Zstring>(i) + zen::TEMP_FILE_ENDING; + output = filename + Zchar('_') + numberTo<Zstring>(i) + zen::TEMP_FILE_ENDING; return output; } @@ -1158,7 +1133,13 @@ void SynchronizeFolderPair::runZeroPass(HierarchyObject& hierObj) FileMapping* sourceObj = &fileObj; if (FileMapping* targetObj = dynamic_cast<FileMapping*>(FileSystemObject::retrieve(fileObj.getMoveRef()))) { - if (!tryReportingError(procCallback_, [&] { return syncOp == SO_MOVE_LEFT_SOURCE ? this->manageFileMove<LEFT_SIDE>(*sourceObj, *targetObj) : this->manageFileMove<RIGHT_SIDE>(*sourceObj, *targetObj); })) + if (!tryReportingError([&] + { + if (syncOp == SO_MOVE_LEFT_SOURCE) + this->manageFileMove<LEFT_SIDE>(*sourceObj, *targetObj); + else + this->manageFileMove<RIGHT_SIDE>(*sourceObj, *targetObj); + }, procCallback_)) { //move operation has failed! We cannot allow to continue and have move source's parent directory deleted, messing up statistics! // => revert to ordinary "copy + delete" @@ -1173,8 +1154,8 @@ void SynchronizeFolderPair::runZeroPass(HierarchyObject& hierObj) }; const auto statBefore = getStat(); - sourceObj->setMoveRef(NULL); - targetObj->setMoveRef(NULL); + sourceObj->setMoveRef(nullptr); + targetObj->setMoveRef(nullptr); const auto statAfter = getStat(); //fix statistics to total to match "copy + delete" procCallback_.updateTotalData(statAfter.first - statBefore.first, statAfter.second - statBefore.second); @@ -1313,7 +1294,7 @@ void SynchronizeFolderPair::runPass(HierarchyObject& hierObj) [&](FileMapping& fileObj) { if (pass == getPass(fileObj)) - tryReportingError(procCallback_, [&] { synchronizeFile(fileObj); }); + tryReportingError([&] { synchronizeFile(fileObj); }, procCallback_); }); //synchronize symbolic links: @@ -1321,7 +1302,7 @@ void SynchronizeFolderPair::runPass(HierarchyObject& hierObj) [&](SymLinkMapping& linkObj) { if (pass == getPass(linkObj)) - tryReportingError(procCallback_, [&] { synchronizeLink(linkObj); }); + tryReportingError([&] { synchronizeLink(linkObj); }, procCallback_); }); //synchronize folders: @@ -1329,7 +1310,7 @@ void SynchronizeFolderPair::runPass(HierarchyObject& hierObj) [&](DirMapping& dirObj) { if (pass == getPass(dirObj)) - tryReportingError(procCallback_, [&] { synchronizeFolder(dirObj); }); + tryReportingError([&] { synchronizeFolder(dirObj); }, procCallback_); this->runPass<pass>(dirObj); //recurse }); @@ -1963,7 +1944,7 @@ void SyncProcess::startSynchronizationProcess(const std::vector<FolderPairSyncCf auto checkSpace = [&](const Zstring& baseDirPf, const Int64& spaceRequired) { wxLongLong freeDiskSpace; - if (wxGetDiskSpace(toWx(baseDirPf), NULL, &freeDiskSpace)) + if (wxGetDiskSpace(toWx(baseDirPf), nullptr, &freeDiskSpace)) { if (0 < freeDiskSpace && //zero disk space is either an error or not: in both cases this warning message is obsolete (WebDav seems to report 0) freeDiskSpace.GetValue() < spaceRequired) @@ -2068,9 +2049,9 @@ void SyncProcess::startSynchronizationProcess(const std::vector<FolderPairSyncCf std::vector<Zstring> conflictDirs; for (auto iter = dirReadWriteCount.cbegin(); iter != dirReadWriteCount.cend(); ++iter) { - const auto& countRef = iter->second; - if (countRef.second >= 2 || //multiple write accesses - (countRef.second == 1 && countRef.first >= 1)) //read/write access + const std::pair<size_t, size_t>& countRef = iter->second; //# read/write accesses + + if (countRef.first + countRef.second >= 2 && countRef.second >= 1) //race condition := multiple accesses of which at least one is a write conflictDirs.push_back(iter->first); } @@ -2087,7 +2068,7 @@ void SyncProcess::startSynchronizationProcess(const std::vector<FolderPairSyncCf #ifdef FFS_WIN //shadow copy buffer: per sync-instance, not folder pair - boost::scoped_ptr<shadow::ShadowCopy> shadowCopyHandler(copyLockedFiles_ ? new shadow::ShadowCopy : NULL); + std::unique_ptr<shadow::ShadowCopy> shadowCopyHandler(copyLockedFiles_ ? new shadow::ShadowCopy : nullptr); #endif try @@ -2114,7 +2095,7 @@ void SyncProcess::startSynchronizationProcess(const std::vector<FolderPairSyncCf makeSameLength(left, right); const std::wstring statusTxt = _("Processing folder pair:") + L" \n" + - L" " + left + L"\"" + j->getBaseDirPf<LEFT_SIDE>() + L"\"" + L" \n" + + L" " + left + L"\"" + j->getBaseDirPf<LEFT_SIDE >() + L"\"" + L" \n" + L" " + right + L"\"" + j->getBaseDirPf<RIGHT_SIDE>() + L"\""; procCallback.reportInfo(statusTxt); @@ -2124,14 +2105,14 @@ void SyncProcess::startSynchronizationProcess(const std::vector<FolderPairSyncCf const Zstring dirnameLeft = beforeLast(j->getBaseDirPf<LEFT_SIDE>(), FILE_NAME_SEPARATOR); if (!dirnameLeft.empty() && !dirExistsUpdating(dirnameLeft, false, procCallback)) { - if (!tryReportingError(procCallback, [&]() { createDirectory(dirnameLeft); })) //may throw in error-callback! - continue; //skip this folder pair + if (!tryReportingError([&] { createDirectory(dirnameLeft); }, procCallback)) //may throw in error-callback! + continue; //skip this folder pair } const Zstring dirnameRight = beforeLast(j->getBaseDirPf<RIGHT_SIDE>(), FILE_NAME_SEPARATOR); if (!dirnameRight.empty() && !dirExistsUpdating(dirnameRight, false, procCallback)) { - if (!tryReportingError(procCallback, [&]() { createDirectory(dirnameRight); })) //may throw in error-callback! - continue; //skip this folder pair + if (!tryReportingError([&] { createDirectory(dirnameRight); }, procCallback)) //may throw in error-callback! + continue; //skip this folder pair } //------------------------------------------------------------------------------------------ //execute synchronization recursively @@ -2140,19 +2121,20 @@ void SyncProcess::startSynchronizationProcess(const std::vector<FolderPairSyncCf zen::ScopeGuard guardUpdateDb = zen::makeGuard([&] { if (folderPairCfg.inAutomaticMode) - zen::saveToDisk(*j); //throw FileError + try { zen::saveToDisk(*j); } + catch (...) {} //throw FileError }); //guarantee removal of invalid entries (where element on both sides is empty) - ZEN_ON_BLOCK_EXIT(BaseDirMapping::removeEmpty(*j);); + ZEN_ON_SCOPE_EXIT(BaseDirMapping::removeEmpty(*j);); bool copyPermissionsFp = false; - tryReportingError(procCallback, [&] + tryReportingError([&] { copyPermissionsFp = copyFilePermissions_ && //copy permissions only if asked for and supported by *both* sides! supportsPermissions(beforeLast(j->getBaseDirPf<LEFT_SIDE >(), FILE_NAME_SEPARATOR)) && //throw FileError supportsPermissions(beforeLast(j->getBaseDirPf<RIGHT_SIDE>(), FILE_NAME_SEPARATOR)); - }); //show error dialog if necessary + }, procCallback); //show error dialog if necessary SynchronizeFolderPair syncFP(procCallback, verifyCopiedFiles_, copyPermissionsFp, transactionalFileCopy_, #ifdef FFS_WIN @@ -2163,8 +2145,8 @@ void SyncProcess::startSynchronizationProcess(const std::vector<FolderPairSyncCf syncFP.startSync(*j); //(try to gracefully) cleanup temporary folders (Recycle bin optimization) -> will be done in ~DeletionHandling anyway... - tryReportingError(procCallback, [&] { delHandlerFp.first .tryCleanup(); }); //show error dialog if necessary - tryReportingError(procCallback, [&] { delHandlerFp.second.tryCleanup(); }); // + tryReportingError([&] { delHandlerFp.first .tryCleanup(); }, procCallback); //show error dialog if necessary + tryReportingError([&] { delHandlerFp.second.tryCleanup(); }, procCallback); // //(try to gracefully) write database file (will be done in ~EnforceUpdateDatabase anyway...) if (folderPairCfg.inAutomaticMode) @@ -2172,13 +2154,13 @@ void SyncProcess::startSynchronizationProcess(const std::vector<FolderPairSyncCf procCallback.reportStatus(_("Generating database...")); procCallback.forceUiRefresh(); - tryReportingError(procCallback, [&]() { zen::saveToDisk(*j); }); //throw FileError + tryReportingError([&] { zen::saveToDisk(*j); }, procCallback); //throw FileError guardUpdateDb.dismiss(); } } if (!synchronizationNeeded(statisticsTotal)) - procCallback.reportInfo(_("Nothing to synchronize according to configuration!")); //inform about this special case + procCallback.reportInfo(_("Nothing to synchronize!")); //inform about this special case } catch (const std::exception& e) { @@ -2266,7 +2248,7 @@ void SynchronizeFolderPair::copyFileUpdatingTo(const FileMapping& fileObj, const catch (ErrorFileLocked&) { //if file is locked (try to) use Windows Volume Shadow Copy Service - if (shadowCopyHandler_ == NULL) + if (!shadowCopyHandler_) throw; try { @@ -2275,8 +2257,7 @@ void SynchronizeFolderPair::copyFileUpdatingTo(const FileMapping& fileObj, const } catch (const FileError& e) { - const std::wstring errorMsg = replaceCpy(_("Error copying locked file %x!"), L"%x", std::wstring(L"\"") + source + L"\""); - throw FileError(errorMsg + L"\n\n" + e.toString()); + throw FileError(replaceCpy(_("Unable to copy locked file %x!"), L"%x", std::wstring(L"\"") + source + L"\"") + L"\n\n" + e.toString()); } //now try again @@ -2326,7 +2307,7 @@ void verifyFiles(const Zstring& source, const Zstring& target, VerifyCallback& c wxFile file1(::open(source.c_str(), O_RDONLY)); //utilize UTF-8 filename #endif if (!file1.IsOpened()) - throw FileError(_("Error opening file:") + L" \"" + source + L"\""); + throw FileError(_("Error reading file:") + L" \"" + source + L"\""); #ifdef FFS_WIN wxFile file2(applyLongPathPrefix(target).c_str(), wxFile::read); //don't use buffered file input for verification! @@ -2334,18 +2315,18 @@ void verifyFiles(const Zstring& source, const Zstring& target, VerifyCallback& c wxFile file2(::open(target.c_str(), O_RDONLY)); //utilize UTF-8 filename #endif if (!file2.IsOpened()) //NO cleanup necessary for (wxFile) file1 - throw FileError(_("Error opening file:") + L" \"" + target + L"\""); + throw FileError(_("Error reading file:") + L" \"" + target + L"\""); do { const size_t length1 = file1.Read(&memory1[0], memory1.size()); if (file1.Error()) - throw FileError(_("Error reading file:") + L" \"" + source + L"\""); + throw FileError(_("Error reading file:") + L" \"" + source + L"\"" + L" (r)"); callback.updateStatus(); //send progress updates const size_t length2 = file2.Read(&memory2[0], memory2.size()); if (file2.Error()) - throw FileError(_("Error reading file:") + L" \"" + target + L"\""); + throw FileError(_("Error reading file:") + L" \"" + target + L"\"" + L" (r)"); callback.updateStatus(); //send progress updates if (length1 != length2 || ::memcmp(&memory1[0], &memory2[0], length1) != 0) @@ -2376,5 +2357,5 @@ void SynchronizeFolderPair::verifyFileCopy(const Zstring& source, const Zstring& VerifyStatusUpdater callback(procCallback_); - tryReportingError(procCallback_, [&]() { ::verifyFiles(source, target, callback);}); + tryReportingError([&] { ::verifyFiles(source, target, callback); }, procCallback_); } diff --git a/synchronization.h b/synchronization.h index a9fd5d0c..cbe3937d 100644 --- a/synchronization.h +++ b/synchronization.h @@ -9,7 +9,7 @@ #include "file_hierarchy.h" #include "lib/process_xml.h" -#include "lib/status_handler.h" +#include "process_callback.h" #include <zen/process_status.h> diff --git a/ui/Taskbar_Seven/taskbar.cpp b/ui/Taskbar_Seven/taskbar.cpp index be662242..6c1365a4 100644 --- a/ui/Taskbar_Seven/taskbar.cpp +++ b/ui/Taskbar_Seven/taskbar.cpp @@ -27,7 +27,7 @@ ComPtr<ITaskbarList3> getInstance() ComPtr<ITaskbarList3> taskbarlist; HRESULT hr = ::CoCreateInstance(CLSID_TaskbarList, - NULL, + nullptr, CLSCTX_ALL, IID_PPV_ARGS(taskbarlist.init())); if (FAILED(hr)) diff --git a/ui/batch_config.cpp b/ui/batch_config.cpp index dac14637..0ed13399 100644 --- a/ui/batch_config.cpp +++ b/ui/batch_config.cpp @@ -14,7 +14,7 @@ #include <zen/file_handling.h> #include "msg_popup.h" #include "gui_generated.h" -#include <wx/dnd.h> +//#include <wx/dnd.h> #include <wx/msgdlg.h> #include <wx+/button.h> #include <wx+/choice_enum.h> @@ -28,7 +28,7 @@ class DirectoryPairBatch; class BatchDialog: public BatchDlgGenerated { - friend class BatchFileDropEvent; + // friend class BatchFileDropEvent; template <class GuiPanel> friend class FolderPairCallback; @@ -52,8 +52,8 @@ private: void OnGlobalFilterContext(wxCommandEvent& event); virtual void OnCheckSaveLog( wxCommandEvent& event); virtual void OnChangeMaxLogCountTxt(wxCommandEvent& event); - virtual void OnClose( wxCloseEvent& event); - virtual void OnCancel( wxCommandEvent& event); + virtual void OnClose( wxCloseEvent& event) { EndModal(0); } + virtual void OnCancel( wxCommandEvent& event) { EndModal(0); } virtual void OnSaveBatchJob( wxCommandEvent& event); virtual void OnLoadBatchJob( wxCommandEvent& event); virtual void OnAddFolderPair( wxCommandEvent& event); @@ -151,7 +151,6 @@ private: batchDlg.updateGui(); } - virtual void removeAltSyncCfg() { FolderPairPanelBasic<GuiPanel>::removeAltSyncCfg(); @@ -160,7 +159,6 @@ private: virtual void OnLocalFilterCfgChange() {} - BatchDialog& batchDlg; }; @@ -267,13 +265,13 @@ BatchDialog::BatchDialog(wxWindow* window, //init handling of first folder pair firstFolderPair.reset(new DirectoryPairBatchFirst(*this)); - m_bpButtonCmpConfig ->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(BatchDialog::OnCompSettingsContext), NULL, this); - m_bpButtonSyncConfig->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(BatchDialog::OnSyncSettingsContext), NULL, this); - m_bpButtonFilter ->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(BatchDialog::OnGlobalFilterContext), NULL, this); + m_bpButtonCmpConfig ->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(BatchDialog::OnCompSettingsContext), nullptr, this); + m_bpButtonSyncConfig->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(BatchDialog::OnSyncSettingsContext), nullptr, this); + m_bpButtonFilter ->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(BatchDialog::OnGlobalFilterContext), nullptr, this); //prepare drag & drop for loading of *.ffs_batch files setupFileDrop(*this); - Connect(EVENT_DROP_FILE, FileDropEventHandler(BatchDialog::OnFilesDropped), NULL, this); + Connect(EVENT_DROP_FILE, FileDropEventHandler(BatchDialog::OnFilesDropped), nullptr, this); logfileDir.reset(new DirectoryName<FolderHistoryBox>(*m_panelBatchSettings, *m_dirPickerLogfileDir, *m_comboBoxLogfileDir)); @@ -335,7 +333,7 @@ void BatchDialog::OnSyncSettings(wxCommandEvent& event) if (showSyncConfigDlg(localBatchCfg.mainCfg.cmpConfig.compareVar, localBatchCfg.mainCfg.syncCfg, - NULL, + nullptr, &ewfCfg) == ReturnSyncConfig::BUTTON_OKAY) //optional input parameter { updateGui(); @@ -434,7 +432,7 @@ void BatchDialog::OnGlobalFilterContext(wxCommandEvent& event) localBatchCfg.mainCfg.globalFilter = FilterConfig(); updateGui(); }; - menu.addItem( _("Clear filter settings"), clearFilter, NULL, !isNullFilter(localBatchCfg.mainCfg.globalFilter)); + menu.addItem( _("Clear filter settings"), clearFilter, nullptr, !isNullFilter(localBatchCfg.mainCfg.globalFilter)); menu.popup(*this); } @@ -516,40 +514,28 @@ void BatchDialog::showNotebookpage(wxWindow* page, const wxString& pageName, boo } */ -void BatchDialog::OnClose(wxCloseEvent& event) -{ - EndModal(ReturnBatchConfig::BUTTON_CANCEL); -} - - -void BatchDialog::OnCancel(wxCommandEvent& event) -{ - EndModal(ReturnBatchConfig::BUTTON_CANCEL); -} - - void BatchDialog::OnSaveBatchJob(wxCommandEvent& event) { //get a filename wxString defaultFileName = proposedBatchFileName.empty() ? wxT("SyncJob.ffs_batch") : proposedBatchFileName; //attention: proposedBatchFileName may be an imported *.ffs_gui file! We don't want to overwrite it with a BATCH config! - if (defaultFileName.EndsWith(wxT(".ffs_gui"))) - defaultFileName.Replace(wxT(".ffs_gui"), wxT(".ffs_batch"), false); + if (endsWith(defaultFileName, L".ffs_gui")) + replace(defaultFileName, L".ffs_gui", L".ffs_batch"); wxFileDialog filePicker(this, wxEmptyString, wxEmptyString, defaultFileName, - wxString(_("FreeFileSync batch file")) + wxT(" (*.ffs_batch)|*.ffs_batch"), + wxString(_("FreeFileSync batch file")) + L" (*.ffs_batch)|*.ffs_batch", wxFD_SAVE /*| wxFD_OVERWRITE_PROMPT*/); //creating this on freestore leads to memleak! if (filePicker.ShowModal() == wxID_OK) { const wxString newFileName = filePicker.GetPath(); - //create batch file - if (saveBatchFile(newFileName)) - EndModal(ReturnBatchConfig::BATCH_FILE_SAVED); + saveBatchFile(newFileName); + //if () + // EndModal(ReturnBatchConfig::BATCH_FILE_SAVED); } } @@ -782,8 +768,8 @@ void BatchDialog::updateGuiForFolderPair() //adapt local filter and sync cfg for first folder pair if (additionalFolderPairs.empty() && - firstFolderPair->getAltCompConfig().get() == NULL && - firstFolderPair->getAltSyncConfig().get() == NULL && + firstFolderPair->getAltCompConfig().get() == nullptr && + firstFolderPair->getAltSyncConfig().get() == nullptr && isNullFilter(firstFolderPair->getAltFilterConfig())) { m_bpButtonAltCompCfg ->Hide(); @@ -830,7 +816,7 @@ void BatchDialog::addFolderPair(const std::vector<zen::FolderPairEnh>& newPairs, //add folder pairs for (std::vector<zen::FolderPairEnh>::const_iterator i = newPairs.begin(); i != newPairs.end(); ++i) { - DirectoryPairBatch* newPair = new DirectoryPairBatch(m_scrolledWindow6, *this); + DirectoryPairBatch* newPair = new DirectoryPairBatch(m_scrolledWindow6, *this); //owned by m_scrolledWindow6! //init dropdown history newPair->m_directoryLeft ->init(folderHistLeft_); @@ -848,7 +834,7 @@ void BatchDialog::addFolderPair(const std::vector<zen::FolderPairEnh>& newPairs, } //register events - newPair->m_bpButtonRemovePair->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BatchDialog::OnRemoveFolderPair), NULL, this ); + newPair->m_bpButtonRemovePair->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BatchDialog::OnRemoveFolderPair), nullptr, this ); //set alternate configuration newPair->setValues(toWx(i->leftDirectory), @@ -913,10 +899,10 @@ bool BatchDialog::createBatchFile(const wxString& filename) { //create shell link (instead of batch file) for full Unicode support HRESULT hResult = E_FAIL; - IShellLink* pShellLink = NULL; + IShellLink* pShellLink = nullptr; if (FAILED(CoCreateInstance(CLSID_ShellLink, //class identifier - NULL, //object isn't part of an aggregate + nullptr, //object isn't part of an aggregate CLSCTX_INPROC_SERVER, //context for running executable code IID_IShellLink, //interface identifier (void**)&pShellLink))) //pointer to storage of interface pointer @@ -936,7 +922,7 @@ bool BatchDialog::createBatchFile(const wxString& filename) if (FAILED(pShellLink->SetDescription(_("FreeFileSync Batch Job")))) return false; - IPersistFile* pPersistFile = NULL; + IPersistFile* pPersistFile = nullptr; if (FAILED(pShellLink->QueryInterface(IID_IPersistFile, (void**)&pPersistFile))) return false; CleanUp<IPersistFile> cleanOnExit2(pPersistFile); @@ -959,13 +945,13 @@ bool BatchDialog::createBatchFile(const wxString& filename) */ -ReturnBatchConfig::ButtonPressed zen::showSyncBatchDlg(const wxString& referenceFile, - const xmlAccess::XmlBatchConfig& batchCfg, - const std::shared_ptr<FolderHistory>& folderHistLeft, - const std::shared_ptr<FolderHistory>& folderHistRight, - std::vector<std::wstring>& execFinishedhistory, - size_t execFinishedhistoryMax) +void zen::showSyncBatchDlg(const wxString& referenceFile, + const xmlAccess::XmlBatchConfig& batchCfg, + const std::shared_ptr<FolderHistory>& folderHistLeft, + const std::shared_ptr<FolderHistory>& folderHistRight, + std::vector<std::wstring>& execFinishedhistory, + size_t execFinishedhistoryMax) { - BatchDialog batchDlg(NULL, referenceFile, batchCfg, folderHistLeft, folderHistRight, execFinishedhistory, execFinishedhistoryMax); - return static_cast<ReturnBatchConfig::ButtonPressed>(batchDlg.ShowModal()); + BatchDialog batchDlg(nullptr, referenceFile, batchCfg, folderHistLeft, folderHistRight, execFinishedhistory, execFinishedhistoryMax); + batchDlg.ShowModal(); } diff --git a/ui/batch_config.h b/ui/batch_config.h index 5d47f64d..472f21bf 100644 --- a/ui/batch_config.h +++ b/ui/batch_config.h @@ -12,21 +12,12 @@ namespace zen { -struct ReturnBatchConfig -{ - enum ButtonPressed - { - BUTTON_CANCEL, - BATCH_FILE_SAVED = 1 - }; -}; - -ReturnBatchConfig::ButtonPressed showSyncBatchDlg(const wxString& referenceFile, - const xmlAccess::XmlBatchConfig& batchCfg, - const std::shared_ptr<FolderHistory>& folderHistLeft, - const std::shared_ptr<FolderHistory>& folderHistRight, - std::vector<std::wstring>& execFinishedhistory, - size_t execFinishedhistoryMax); +void showSyncBatchDlg(const wxString& referenceFile, + const xmlAccess::XmlBatchConfig& batchCfg, + const std::shared_ptr<FolderHistory>& folderHistLeft, + const std::shared_ptr<FolderHistory>& folderHistRight, + std::vector<std::wstring>& execFinishedhistory, + size_t execFinishedhistoryMax); } diff --git a/ui/batch_status_handler.cpp b/ui/batch_status_handler.cpp index 6308842f..0c45db3f 100644 --- a/ui/batch_status_handler.cpp +++ b/ui/batch_status_handler.cpp @@ -17,6 +17,7 @@ #include <zen/time.h> #include "exec_finished_box.h" #include <wx+/shell_execute.h> +#include "../lib/status_handler_impl.h" using namespace zen; @@ -36,7 +37,7 @@ public: } virtual std::shared_ptr<TraverseCallback> - onDir (const Zchar* shortName, const Zstring& fullName) { return nullptr; } //DON'T traverse into subdirs + onDir (const Zchar* shortName, const Zstring& fullName) { return nullptr; } //DON'T traverse into subdirs virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) {} virtual HandleError onError (const std::wstring& errorText) { return TRAV_ERROR_IGNORE; } //errors are not really critical in this context @@ -54,7 +55,7 @@ public: jobName_(jobName), //throw FileError logfileName(findUniqueLogname(logfileDirectory, jobName)) { - logFile.Open(toWx(logfileName), wxT("w")); + logFile.Open(toWx(logfileName), L"w"); if (!logFile.IsOpened()) throw FileError(_("Unable to create log file!") + L"\"" + logfileName + L"\""); @@ -62,33 +63,39 @@ public: wxString headerLine = wxString(L"FreeFileSync - ") + _("Batch execution") + L" - " + formatTime<wxString>(FORMAT_DATE); logFile.Write(headerLine + wxChar('\n')); - logFile.Write(wxString().Pad(headerLine.Len(), wxChar('-')) + wxChar('\n') + wxChar('\n')); + logFile.Write(wxString().Pad(headerLine.Len(), L'=') + L'\n'); logItemStart = formatTime<wxString>(L"[%X] ") + _("Start"); totalTime.Start(); //measure total time } - void writeLog(const ErrorLogging& log, const wxString& finalStatus) + void writeLog(const ErrorLog& log, const std::wstring& finalStatus) { - logFile.Write(finalStatus + L"\n\n"); //highlight result by placing at beginning of file + const size_t sepLineLen = finalStatus.size(); + + //result + statistics + logFile.Write(wxString().Pad(sepLineLen, L'_') + L'\n'); + logFile.Write(L"\n" + finalStatus + L"\n"); + logFile.Write(wxString().Pad(sepLineLen, L'_') + L"\n\n"); logFile.Write(logItemStart + L"\n\n"); //write actual logfile - const std::vector<wxString>& messages = log.getFormattedMessages(); - for (std::vector<wxString>::const_iterator i = messages.begin(); i != messages.end(); ++i) - logFile.Write(*i + L'\n'); + const auto& entries = log.getEntries(); + for (auto iter = entries.begin(); iter != entries.end(); ++iter) + { + const std::string& msg = utf8CvrtTo<std::string>(formatMessage(*iter)); + logFile.Write(msg.c_str(), msg.size()); //better do UTF8 conversion ourselves rather than to rely on wxWidgets + logFile.Write(L'\n'); + } - //write ending + //write footer logFile.Write(L'\n'); - - const long time = totalTime.Time(); //retrieve total time - - logFile.Write(wxString(L"[") + formatTime<wxString>(FORMAT_TIME) + L"] " + _("Stop") + L" (" + _("Total time:") + L" " + wxTimeSpan::Milliseconds(time).Format() + L")\n"); + logFile.Write(formatTime<wxString>(L"[%X] ") + _("Stop") + L" (" + _("Total time:") + L" " + wxTimeSpan::Milliseconds(totalTime.Time()).Format() + L")\n"); } - void limitLogfileCount(size_t maxCount) const + void limitLogfileCount(size_t maxCount) const //throw() { std::vector<Zstring> logFiles; FindLogfiles traverseCallback(toZ(jobName_), logFiles); @@ -101,7 +108,7 @@ public: return; //delete oldest logfiles - std::sort(logFiles.begin(), logFiles.end()); //take advantage of logfile naming convention to sort by age + std::nth_element(logFiles.begin(), logFiles.end() - maxCount, logFiles.end()); //take advantage of logfile naming convention to find oldest files std::for_each(logFiles.begin(), logFiles.end() - maxCount, [](const Zstring& filename) { try { zen::removeFile(filename); } catch (FileError&) {} }); @@ -130,7 +137,7 @@ private: Zstring output = logfileName + Zstr(".log"); for (int i = 1; zen::somethingExists(output); ++i) - output = logfileName + Zstr('_') + zen::toString<Zstring>(i) + Zstr(".log"); + output = logfileName + Zstr('_') + zen::numberTo<Zstring>(i) + Zstr(".log"); return output; } @@ -158,34 +165,31 @@ BatchStatusHandler::BatchStatusHandler(bool showProgress, handleError_(handleError), currentProcess(StatusHandler::PROCESS_NONE), returnValue(returnVal), - syncStatusFrame(*this, NULL, SyncStatus::SCANNING, showProgress, jobName, execWhenFinished, execFinishedHistory) + syncStatusFrame(*this, nullptr, SyncStatus::SCANNING, showProgress, jobName, execWhenFinished, execFinishedHistory) { if (logFileCountMax > 0) { - try - { - logFile = std::make_shared<LogFile>(toZ(logfileDirectory), jobName); //throw FileError - logFile->limitLogfileCount(logFileCountMax); //throw FileError - } - catch (zen::FileError& error) + if (!tryReportingError([&] + { + logFile = std::make_shared<LogFile>(toZ(logfileDirectory), jobName); //throw FileError + logFile->limitLogfileCount(logFileCountMax); //throw() + }, *this)) { - if (handleError_ == xmlAccess::ON_ERROR_POPUP) - wxMessageBox(error.toString(), _("Error"), wxOK | wxICON_ERROR); returnValue = -7; throw BatchAbortProcess(); } - - //::wxSetEnv(L"logfile", logFile->getLogfileName()); } + + //::wxSetEnv(L"logfile", logFile->getLogfileName()); } BatchStatusHandler::~BatchStatusHandler() { - const int totalErrors = errorLog.typeCount(TYPE_ERROR | TYPE_FATAL_ERROR); //evaluate before finalizing log + const int totalErrors = errorLog.getItemCount(TYPE_ERROR | TYPE_FATAL_ERROR); //evaluate before finalizing log //finalize error log - wxString finalStatus; + std::wstring finalStatus; if (abortIsRequested()) { returnValue = -4; @@ -345,7 +349,7 @@ void BatchStatusHandler::reportWarning(const std::wstring& warningMessage, bool& break; case ReturnWarningDlg::BUTTON_SWITCH: - errorLog.logMsg(_("Switching to FreeFileSync GUI mode..."), TYPE_WARNING); + errorLog.logMsg(_("Switching to FreeFileSync GUI mode..."), TYPE_INFO); switchToGuiRequested = true; abortThisProcess(); break; diff --git a/ui/batch_status_handler.h b/ui/batch_status_handler.h index d5a18322..0657e881 100644 --- a/ui/batch_status_handler.h +++ b/ui/batch_status_handler.h @@ -7,9 +7,9 @@ #ifndef BATCHSTATUSHANDLER_H_INCLUDED #define BATCHSTATUSHANDLER_H_INCLUDED +#include <zen/error_log.h> #include "../lib/status_handler.h" #include "../lib/process_xml.h" -#include "../lib/error_log.h" #include "progress_indicator.h" #include "switch_to_gui.h" @@ -52,7 +52,7 @@ private: bool showFinalResults; bool switchToGuiRequested; xmlAccess::OnError handleError_; - zen::ErrorLogging errorLog; //list of non-resolved errors and warnings + zen::ErrorLog errorLog; //list of non-resolved errors and warnings Process currentProcess; int& returnValue; diff --git a/ui/check_version.cpp b/ui/check_version.cpp index 61af5b48..ba922f97 100644 --- a/ui/check_version.cpp +++ b/ui/check_version.cpp @@ -63,7 +63,7 @@ std::vector<size_t> parseVersion(const wxString& version) while (tkz.HasMoreTokens()) { const wxString& token = tkz.GetNextToken(); - output.push_back(zen::toNumber<size_t>(token)); + output.push_back(zen::stringTo<size_t>(token)); } return output; } @@ -114,7 +114,7 @@ void zen::checkForUpdatePeriodically(long& lastUpdateCheck) if (lastUpdateCheck == 0) { const bool checkRegularly = showQuestionDlg(ReturnQuestionDlg::BUTTON_YES | ReturnQuestionDlg::BUTTON_NO, - wxString(_("Do you want FreeFileSync to automatically check for updates every week?")) + wxT("\n") + + _("Do you want FreeFileSync to automatically check for updates every week?") + L"\n" + _("(Requires an Internet connection!)")) == ReturnQuestionDlg::BUTTON_YES; if (checkRegularly) { diff --git a/ui/column_attr.h b/ui/column_attr.h index 275c9dd7..517961f4 100644 --- a/ui/column_attr.h +++ b/ui/column_attr.h @@ -110,7 +110,7 @@ std::vector<ColumnAttributeNavi> getDefaultColumnAttributesNavi() newEntry.type_ = COL_TYPE_NAVI_BYTES; newEntry.visible_ = true; - newEntry.width_ = 55; + newEntry.width_ = 60; //GTK needs a few pixels more attr.push_back(newEntry); return attr; diff --git a/ui/custom_grid.cpp b/ui/custom_grid.cpp index df1e9145..465a1b6f 100644 --- a/ui/custom_grid.cpp +++ b/ui/custom_grid.cpp @@ -29,10 +29,10 @@ const wxColour COLOR_ORANGE (238, 201, 0); const wxColour COLOR_GREY (212, 208, 200); const wxColour COLOR_YELLOW (247, 252, 62); const wxColour COLOR_YELLOW_LIGHT(253, 252, 169); -const wxColour COLOR_CMP_RED (249, 163, 165); -const wxColour COLOR_SYNC_BLUE (201, 203, 247); -const wxColour COLOR_SYNC_GREEN (197, 248, 190); -const wxColour COLOR_NOT_ACTIVE(228, 228, 228); //light grey +const wxColour COLOR_CMP_RED (255, 185, 187); +const wxColour COLOR_SYNC_BLUE (185, 188, 255); +const wxColour COLOR_SYNC_GREEN (196, 255, 185); +const wxColour COLOR_NOT_ACTIVE (228, 228, 228); //light grey const Zstring ICON_FILE_FOLDER = Zstr("folder"); @@ -40,7 +40,7 @@ const Zstring ICON_FILE_FOLDER = Zstr("folder"); const int CHECK_BOX_IMAGE = 12; //width of checkbox image const int CHECK_BOX_WIDTH = CHECK_BOX_IMAGE + 2; //width of first block -const size_t MIN_ROW_COUNT = 10; +const size_t ROW_COUNT_NO_DATA = 10; /* class hierarchy: @@ -57,7 +57,7 @@ class hierarchy: -void refreshCell(Grid& grid, int row, ColumnType colType, size_t compPos) +void refreshCell(Grid& grid, size_t row, ColumnType colType, size_t compPos) { wxRect cellArea = grid.getCellArea(row, colType, compPos); //returns empty rect if column not found; absolute coordinates! if (cellArea.height > 0) @@ -68,7 +68,7 @@ void refreshCell(Grid& grid, int row, ColumnType colType, size_t compPos) } -std::pair<int, int> getVisibleRows(Grid& grid) //returns range [from, to) +std::pair<ptrdiff_t, ptrdiff_t> getVisibleRows(Grid& grid) //returns range [from, to) { const wxSize clientSize = grid.getMainWin().GetClientSize(); if (clientSize.GetHeight() > 0) @@ -76,10 +76,10 @@ std::pair<int, int> getVisibleRows(Grid& grid) //returns range [from, to) wxPoint topLeft = grid.CalcUnscrolledPosition(wxPoint(0, 0)); wxPoint bottom = grid.CalcUnscrolledPosition(wxPoint(0, clientSize.GetHeight() - 1)); - int rowFrom = grid.getRowAtPos(topLeft.y); //returns < 0 if column not found; absolute coordinates! + ptrdiff_t rowFrom = grid.getRowAtPos(topLeft.y); //returns < 0 if column not found; absolute coordinates! if (rowFrom >= 0) { - int rowEnd = grid.getRowAtPos(bottom.y); //returns < 0 if column not found; absolute coordinates! + ptrdiff_t rowEnd = grid.getRowAtPos(bottom.y); //returns < 0 if column not found; absolute coordinates! if (rowEnd < 0) rowEnd = grid.getRowCount(); else @@ -137,18 +137,18 @@ public: //don't check too often! give worker thread some time to fetch data if (iconMgr_) { - const std::pair<int, int>& rowsOnScreen = getVisibleRows(refGrid()); + const auto& rowsOnScreen = getVisibleRows(refGrid()); //loop over all visible rows - const int firstRow = rowsOnScreen.first; - const int rowCount = rowsOnScreen.second - firstRow; + const ptrdiff_t firstRow = rowsOnScreen.first; + const ptrdiff_t rowCount = rowsOnScreen.second - firstRow; - for (int i = 0; i < rowCount; ++i) + for (ptrdiff_t i = 0; i < rowCount; ++i) { //alternate when adding rows: first, last, first + 1, last - 1 ... -> Icon buffer will then load reversely, i.e. from inside out - const int currentRow = firstRow + (i % 2 == 0 ? - i / 2 : - rowCount - 1 - (i - 1) / 2); + const ptrdiff_t currentRow = firstRow + (i % 2 == 0 ? + i / 2 : + rowCount - 1 - (i - 1) / 2); if (isFailedLoad(currentRow)) //find failed attempts to load icon { @@ -182,7 +182,7 @@ public: bool isFailedLoad(size_t row) const { return row < failedLoads.size() ? failedLoads[row] != 0 : false; } protected: - virtual void renderRowBackgound(wxDC& dc, const wxRect& rect, int row, bool enabled, bool selected, bool hasFocus) + virtual void renderRowBackgound(wxDC& dc, const wxRect& rect, size_t row, bool enabled, bool selected, bool hasFocus) { if (enabled) { @@ -196,7 +196,7 @@ protected: clearArea(dc, rect, wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); } - wxColor getBackGroundColor(int row) const + wxColor getBackGroundColor(size_t row) const { wxColor backGroundCol = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); @@ -230,12 +230,24 @@ protected: return backGroundCol; } - const FileSystemObject* getRawData(int row) const { return gridDataView_ ? gridDataView_->getObject(row) : NULL; } + const FileSystemObject* getRawData(size_t row) const { return gridDataView_ ? gridDataView_->getObject(row) : nullptr; } private: - virtual size_t getRowCount() const { return std::max(MIN_ROW_COUNT, gridDataView_ ? gridDataView_->rowsOnView() : 0); } + virtual size_t getRowCount() const + { + if (gridDataView_) + { + if (gridDataView_->rowsTotal() == 0) + return ROW_COUNT_NO_DATA; + return gridDataView_->rowsOnView(); + } + else + return ROW_COUNT_NO_DATA; + + //return std::max(MIN_ROW_COUNT, gridDataView_ ? gridDataView_->rowsOnView() : 0); + } - virtual wxString getValue(int row, ColumnType colType) const + virtual wxString getValue(size_t row, ColumnType colType) const { if (const FileSystemObject* fsObj = getRawData(row)) { @@ -346,7 +358,7 @@ private: static const int CELL_BORDER = 2; - virtual void renderCell(Grid& grid, wxDC& dc, const wxRect& rect, int row, ColumnType colType) + virtual void renderCell(Grid& grid, wxDC& dc, const wxRect& rect, size_t row, ColumnType colType) { wxRect rectTmp = drawCellBorder(dc, rect); @@ -358,93 +370,82 @@ private: }(); //draw file icon - if (static_cast<ColumnTypeRim>(colType) == COL_TYPE_FILENAME) + if (static_cast<ColumnTypeRim>(colType) == COL_TYPE_FILENAME && + iconMgr_) { - if (iconMgr_) + rectTmp.x += CELL_BORDER; + rectTmp.width -= CELL_BORDER; + + const int iconSize = iconMgr_->iconBuffer.getSize(); + if (rectTmp.GetWidth() >= iconSize) { - rectTmp.x += CELL_BORDER; - rectTmp.width -= CELL_BORDER; + // Partitioning: + // _______________________________ + // | border | icon | border | text | + // ------------------------------- - const int iconSize = iconMgr_->iconBuffer.getSize(); - if (rectTmp.GetWidth() >= iconSize) + const Zstring fileName = getIconFile(row); + if (!fileName.empty()) { - // Partitioning: - // _______________________________ - // | border | icon | border | text | - // ------------------------------- + wxIcon icon; - const Zstring fileName = getIconFile(row); - if (!fileName.empty()) + //first check if it is a directory icon: + if (fileName == ICON_FILE_FOLDER) + icon = iconMgr_->iconBuffer.genericDirIcon(); + else //retrieve file icon { - wxIcon icon; - - //first check if it is a directory icon: - if (fileName == ICON_FILE_FOLDER) - icon = iconMgr_->iconBuffer.genericDirIcon(); - else //retrieve file icon + if (!iconMgr_->iconBuffer.requestFileIcon(fileName, &icon)) //returns false if icon is not in buffer { - if (!iconMgr_->iconBuffer.requestFileIcon(fileName, &icon)) //returns false if icon is not in buffer - { - icon = iconMgr_->iconBuffer.genericFileIcon(); //better than nothing - setFailedLoad(row, true); //save status of failed icon load -> used for async. icon loading - //falsify only! we want to avoid writing incorrect success values when only partially updating the DC, e.g. when scrolling, - //see repaint behavior of ::ScrollWindow() function! - } + icon = iconMgr_->iconBuffer.genericFileIcon(); //better than nothing + setFailedLoad(row, true); //save status of failed icon load -> used for async. icon loading + //falsify only! we want to avoid writing incorrect success values when only partially updating the DC, e.g. when scrolling, + //see repaint behavior of ::ScrollWindow() function! } + } - if (icon.IsOk()) - { - //center icon if it is too small - const int posX = rectTmp.GetX() + std::max(0, (iconSize - icon.GetWidth()) / 2); - const int posY = rectTmp.GetY() + std::max(0, (rectTmp.GetHeight() - icon.GetHeight()) / 2); + if (icon.IsOk()) + { + //center icon if it is too small + const int posX = rectTmp.GetX() + std::max(0, (iconSize - icon.GetWidth()) / 2); + const int posY = rectTmp.GetY() + std::max(0, (rectTmp.GetHeight() - icon.GetHeight()) / 2); - drawIconRtlNoMirror(dc, icon, wxPoint(posX, posY), buffer); + drawIconRtlNoMirror(dc, icon, wxPoint(posX, posY), buffer); - //convert icon to greyscale if row is not active - if (!isActive) - { - wxBitmap bmp(icon.GetWidth(), icon.GetHeight()); - wxMemoryDC memDc(bmp); - memDc.Blit(0, 0, icon.GetWidth(), icon.GetHeight(), &dc, posX, posY); //blit in + //convert icon to greyscale if row is not active + if (!isActive) + { + wxBitmap bmp(icon.GetWidth(), icon.GetHeight()); + wxMemoryDC memDc(bmp); + memDc.Blit(0, 0, icon.GetWidth(), icon.GetHeight(), &dc, posX, posY); //blit in - bmp = wxBitmap(bmp.ConvertToImage().ConvertToGreyscale(1.0/3, 1.0/3, 1.0/3)); //treat all channels equally! - memDc.SelectObject(bmp); + bmp = wxBitmap(bmp.ConvertToImage().ConvertToGreyscale(1.0/3, 1.0/3, 1.0/3)); //treat all channels equally! + memDc.SelectObject(bmp); - dc.Blit(posX, posY, icon.GetWidth(), icon.GetHeight(), &memDc, 0, 0); //blit out - } + dc.Blit(posX, posY, icon.GetWidth(), icon.GetHeight(), &memDc, 0, 0); //blit out } } } - rectTmp.x += iconSize; - rectTmp.width -= iconSize; } + rectTmp.x += iconSize; + rectTmp.width -= iconSize; + } - rectTmp.x += CELL_BORDER; + //draw text + if (static_cast<ColumnTypeRim>(colType) == COL_TYPE_SIZE && grid.GetLayoutDirection() != wxLayout_RightToLeft) + { + //have file size right-justified (but don't change for RTL languages) rectTmp.width -= CELL_BORDER; - - drawCellText(dc, rectTmp, getValue(row, colType), isActive, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + drawCellText(dc, rectTmp, getValue(row, colType), isActive, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); } else { - int alignment = wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL; - - //have file size right-justified (but don't change for RTL languages) - if (static_cast<ColumnTypeRim>(colType) == COL_TYPE_SIZE && grid.GetLayoutDirection() != wxLayout_RightToLeft) - { - rectTmp.width -= CELL_BORDER; - alignment = wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL; - } - else - { - rectTmp.x += CELL_BORDER; - rectTmp.width -= CELL_BORDER; - } - - drawCellText(dc, rectTmp, getValue(row, colType), isActive, alignment); + rectTmp.x += CELL_BORDER; + rectTmp.width -= CELL_BORDER; + drawCellText(dc, rectTmp, getValue(row, colType), isActive, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); } } - virtual size_t getBestSize(wxDC& dc, int row, ColumnType colType) + virtual size_t getBestSize(wxDC& dc, size_t row, ColumnType colType) { // Partitioning: // ________________________________________ @@ -523,12 +524,12 @@ private: virtual void visit(const SymLinkMapping& linkObj) { iconName = linkObj.getLinkType<side>() == LinkDescriptor::TYPE_DIR ? - Zstr("folder") : + ICON_FILE_FOLDER : linkObj.getFullName<side>(); } virtual void visit(const DirMapping& dirObj) { - iconName = Zstr("folder"); + iconName = ICON_FILE_FOLDER; } Zstring iconName; @@ -539,7 +540,7 @@ private: return Zstring(); } - virtual wxString getToolTip(int row, ColumnType colType) const + virtual wxString getToolTip(size_t row, ColumnType colType) const { wxString toolTip; const FileSystemObject* fsObj = getRawData(row); @@ -575,7 +576,7 @@ private: } std::shared_ptr<const zen::GridView> gridDataView_; - std::shared_ptr<IconManager> iconMgr_; + std::shared_ptr<IconManager> iconMgr_; //optional std::vector<char> failedLoads; //effectively a vector<bool> of size "number of rows" const size_t compPos_; std::unique_ptr<wxBitmap> buffer; //avoid costs of recreating this temporal variable @@ -595,7 +596,7 @@ public: } private: - virtual void renderRowBackgound(wxDC& dc, const wxRect& rect, int row, bool enabled, bool selected, bool hasFocus) + virtual void renderRowBackgound(wxDC& dc, const wxRect& rect, size_t row, bool enabled, bool selected, bool hasFocus) { GridDataRim<LEFT_SIDE>::renderRowBackgound(dc, rect, row, enabled, selected, hasFocus); @@ -675,27 +676,24 @@ public: gridDataView_(gridDataView), syncPreviewActive(true) {} - void onSelectBegin(const wxPoint& clientPos, int row, ColumnType colType) + void onSelectBegin(const wxPoint& clientPos, size_t row, ColumnType colType) { if (static_cast<ColumnTypeMiddle>(colType) == COL_TYPE_MIDDLE_VALUE) { refGrid().clearSelection(gridview::COMP_MIDDLE); - dragSelection.reset(new std::pair<int, BlockPosition>(row, mousePosToBlock(clientPos, row))); + dragSelection.reset(new std::pair<size_t, BlockPosition>(row, mousePosToBlock(clientPos, row))); } } - void onSelectEnd(int row) + void onSelectEnd(size_t rowFrom, size_t rowTo) //we cannot reuse row from "onSelectBegin": rowFrom and rowTo may be different if user is holding shift { refGrid().clearSelection(gridview::COMP_MIDDLE); //issue custom event if (dragSelection) { - const int rowFrom = dragSelection->first; - const int rowTo = row; - - if (0 <= rowFrom && rowFrom < static_cast<int>(refGrid().getRowCount()) && - 0 <= rowTo && rowTo < static_cast<int>(refGrid().getRowCount())) //row is -1 on capture lost! + if (rowFrom < refGrid().getRowCount() && + rowTo < refGrid().getRowCount()) //row is -1 on capture lost! { if (wxEvtHandler* evtHandler = refGrid().GetEventHandler()) switch (dragSelection->second) @@ -733,7 +731,7 @@ public: } } - void onMouseMovement(const wxPoint& clientPos, int row, ColumnType colType, size_t compPos) + void onMouseMovement(const wxPoint& clientPos, size_t row, ColumnType colType, size_t compPos) { //manage block highlighting and custom tooltip if (dragSelection) @@ -747,7 +745,7 @@ public: if (highlight) //refresh old highlight refreshCell(refGrid(), highlight->first, static_cast<ColumnType>(COL_TYPE_MIDDLE_VALUE), gridview::COMP_MIDDLE); - highlight.reset(new std::pair<int, BlockPosition>(row, mousePosToBlock(clientPos, row))); + highlight.reset(new std::pair<size_t, BlockPosition>(row, mousePosToBlock(clientPos, row))); refreshCell(refGrid(), highlight->first, static_cast<ColumnType>(COL_TYPE_MIDDLE_VALUE), gridview::COMP_MIDDLE); //show custom tooltip @@ -772,26 +770,25 @@ public: void setSyncPreviewActive(bool value) { syncPreviewActive = value; } private: - virtual size_t getRowCount() const { return std::max(MIN_ROW_COUNT, gridDataView_ ? gridDataView_->rowsOnView() : 0); } + virtual size_t getRowCount() const { return 0; /*if there are multiple grid components, only the first one will be polled for row count!*/ } - virtual wxString getValue(int row, ColumnType colType) const + virtual wxString getValue(size_t row, ColumnType colType) const { if (static_cast<ColumnTypeMiddle>(colType) == COL_TYPE_MIDDLE_VALUE) { - const FileSystemObject* fsObj = getRawData(row); - if (fsObj) + if (const FileSystemObject* fsObj = getRawData(row)) return syncPreviewActive ? getSymbol(fsObj->getSyncOperation()) : getSymbol(fsObj->getCategory()); } return wxEmptyString; } - virtual void renderRowBackgound(wxDC& dc, const wxRect& rect, int row, bool enabled, bool selected, bool hasFocus) + virtual void renderRowBackgound(wxDC& dc, const wxRect& rect, size_t row, bool enabled, bool selected, bool hasFocus) { drawCellBackground(dc, rect, enabled, selected, hasFocus, getBackGroundColor(row)); } - virtual void renderCell(Grid& grid, wxDC& dc, const wxRect& rect, int row, ColumnType colType) + virtual void renderCell(Grid& grid, wxDC& dc, const wxRect& rect, size_t row, ColumnType colType) { switch (static_cast<ColumnTypeMiddle>(colType)) { @@ -799,15 +796,14 @@ private: { wxRect rectInside = drawCellBorder(dc, rect); - const FileSystemObject* fsObj = getRawData(row); - if (fsObj) + if (const FileSystemObject* fsObj = getRawData(row)) { //draw checkbox wxRect checkBoxArea = rectInside; checkBoxArea.SetWidth(CHECK_BOX_WIDTH); - const bool rowHighlighted = dragSelection ? row == dragSelection->first : highlight ? row == highlight->first : false; - const BlockPosition highlightBlock = dragSelection ? dragSelection->second : highlight ? highlight->second : BLOCKPOS_CHECK_BOX; + const bool rowHighlighted = dragSelection ? row == dragSelection->first : highlight ? row == highlight->first : false; + const BlockPosition highlightBlock = dragSelection ? dragSelection->second : highlight ? highlight->second : BLOCKPOS_CHECK_BOX; if (rowHighlighted && highlightBlock == BLOCKPOS_CHECK_BOX) drawBitmapRtlMirror(dc, GlobalResources::getImage(fsObj->isActive() ? L"checkboxTrueFocus" : L"checkboxFalseFocus"), checkBoxArea, wxALIGN_CENTER, buffer); @@ -826,13 +822,13 @@ private: case BLOCKPOS_CHECK_BOX: break; case BLOCKPOS_LEFT: - drawBitmapRtlMirror(dc, getSyncOpImage(fsObj->testSyncOperation(SYNC_DIR_LEFT, true)), rectInside, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, buffer); + drawBitmapRtlMirror(dc, getSyncOpImage(fsObj->testSyncOperation(SYNC_DIR_LEFT)), rectInside, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, buffer); break; case BLOCKPOS_MIDDLE: - drawBitmapRtlMirror(dc, getSyncOpImage(fsObj->testSyncOperation(SYNC_DIR_NONE, true)), rectInside, wxALIGN_CENTER, buffer); + drawBitmapRtlMirror(dc, getSyncOpImage(fsObj->testSyncOperation(SYNC_DIR_NONE)), rectInside, wxALIGN_CENTER, buffer); break; case BLOCKPOS_RIGHT: - drawBitmapRtlMirror(dc, getSyncOpImage(fsObj->testSyncOperation(SYNC_DIR_RIGHT, true)), rectInside, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, buffer); + drawBitmapRtlMirror(dc, getSyncOpImage(fsObj->testSyncOperation(SYNC_DIR_RIGHT)), rectInside, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, buffer); break; } else //default @@ -856,13 +852,16 @@ private: switch (static_cast<ColumnTypeMiddle>(colType)) { case COL_TYPE_MIDDLE_VALUE: - drawColumnLabelBackground(dc, rect, highlighted); + { + wxRect rectInside = drawColumnLabelBorder(dc, rect); + drawColumnLabelBackground(dc, rectInside, highlighted); if (syncPreviewActive) - dc.DrawLabel(wxEmptyString, GlobalResources::getImage(wxT("syncViewSmall")), rect, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL); + dc.DrawLabel(wxEmptyString, GlobalResources::getImage(L"syncSmall"), rectInside, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL); else - dc.DrawLabel(wxEmptyString, GlobalResources::getImage(wxT("cmpViewSmall")), rect, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL); - break; + dc.DrawLabel(wxEmptyString, GlobalResources::getImage(L"compareSmall"), rectInside, wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL); + } + break; case COL_TYPE_BORDER: drawCellBackground(dc, rect, true, false, true, wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW)); @@ -870,12 +869,11 @@ private: } } - const FileSystemObject* getRawData(int row) const { return gridDataView_ ? gridDataView_->getObject(row) : NULL; } + const FileSystemObject* getRawData(size_t row) const { return gridDataView_ ? gridDataView_->getObject(row) : nullptr; } - wxColor getBackGroundColor(int row) const + wxColor getBackGroundColor(size_t row) const { - const FileSystemObject* fsObj = getRawData(row); - if (fsObj) + if (const FileSystemObject* fsObj = getRawData(row)) { if (!fsObj->isActive()) return COLOR_NOT_ACTIVE; @@ -920,6 +918,7 @@ private: case FILE_RIGHT_SIDE_ONLY: case FILE_RIGHT_NEWER: return COLOR_SYNC_GREEN; //COLOR_CMP_GREEN; + case FILE_DIFFERENT: return COLOR_CMP_RED; case FILE_EQUAL: @@ -944,7 +943,7 @@ private: }; //determine blockposition within cell - BlockPosition mousePosToBlock(const wxPoint& clientPos, int row) const + BlockPosition mousePosToBlock(const wxPoint& clientPos, size_t row) const { const int absX = refGrid().CalcUnscrolledPosition(clientPos).x; @@ -976,10 +975,9 @@ private: return BLOCKPOS_CHECK_BOX; } - void showToolTip(int row, wxPoint posScreen) + void showToolTip(size_t row, wxPoint posScreen) { - const FileSystemObject* fsObj = getRawData(row); - if (fsObj) + if (const FileSystemObject* fsObj = getRawData(row)) { if (syncPreviewActive) //synchronization preview { @@ -1064,8 +1062,8 @@ private: std::shared_ptr<const zen::GridView> gridDataView_; bool syncPreviewActive; - std::unique_ptr<std::pair<int, BlockPosition>> highlight; //(row, block) current mouse highlight - std::unique_ptr<std::pair<int, BlockPosition>> dragSelection; //(row, block) + std::unique_ptr<std::pair<size_t, BlockPosition>> highlight; //(row, block) current mouse highlight + std::unique_ptr<std::pair<size_t, BlockPosition>> dragSelection; //(row, block) std::unique_ptr<wxBitmap> buffer; //avoid costs of recreating this temporal variable zen::Tooltip toolTip; }; @@ -1080,23 +1078,22 @@ public: GridDataMiddle& provMiddle, GridDataRight& provRight) : grid_(grid), provLeft_(provLeft), provMiddle_(provMiddle), provRight_(provRight) { - grid_.Connect(EVENT_GRID_COL_RESIZE, GridColumnResizeEventHandler(GridEventManager::onResizeColumn), NULL, this); + grid_.Connect(EVENT_GRID_COL_RESIZE, GridColumnResizeEventHandler(GridEventManager::onResizeColumn), nullptr, this); - grid_.getMainWin().Connect(wxEVT_MOTION, wxMouseEventHandler(GridEventManager::onMouseMovement), NULL, this); - grid_.getMainWin().Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(GridEventManager::onMouseLeave ), NULL, this); - grid_.getMainWin().Connect(wxEVT_KEY_DOWN, wxKeyEventHandler (GridEventManager::onKeyDown ), NULL, this); + grid_.getMainWin().Connect(wxEVT_MOTION, wxMouseEventHandler(GridEventManager::onMouseMovement), nullptr, this); + grid_.getMainWin().Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(GridEventManager::onMouseLeave ), nullptr, this); + grid_.getMainWin().Connect(wxEVT_KEY_DOWN, wxKeyEventHandler (GridEventManager::onKeyDown ), nullptr, this); - grid_.Connect(EVENT_GRID_MOUSE_LEFT_DOWN, GridClickEventHandler (GridEventManager::onSelectBegin), NULL, this); - grid_.Connect(EVENT_GRID_SELECT_RANGE, GridRangeSelectEventHandler(GridEventManager::onSelectEnd ), NULL, this); + grid_.Connect(EVENT_GRID_MOUSE_LEFT_DOWN, GridClickEventHandler (GridEventManager::onSelectBegin), nullptr, this); + grid_.Connect(EVENT_GRID_SELECT_RANGE, GridRangeSelectEventHandler(GridEventManager::onSelectEnd ), nullptr, this); } private: void onMouseMovement(wxMouseEvent& event) { const wxPoint& topLeftAbs = grid_.CalcUnscrolledPosition(event.GetPosition()); - const Opt<std::pair<ColumnType, size_t>> colInfo = grid_.getColumnAtPos(topLeftAbs.x); const int row = grid_.getRowAtPos(topLeftAbs.y); //returns < 0 if column not found; absolute coordinates! - if (colInfo) + if (auto colInfo = grid_.getColumnAtPos(topLeftAbs.x)) //(column type, component position) { //redirect mouse movement to middle grid component provMiddle_.onMouseMovement(event.GetPosition(), row, colInfo->first, colInfo->second); @@ -1120,7 +1117,7 @@ private: void onSelectEnd(GridRangeSelectEvent& event) { if (event.compPos_ == gridview::COMP_MIDDLE) - provMiddle_.onSelectEnd(event.rowTo_); + provMiddle_.onSelectEnd(event.rowFrom_, event.rowTo_); event.Skip(); } @@ -1141,9 +1138,7 @@ private: //skip middle component when navigating via keyboard - int row = grid_.getGridCursor().first; - if (row < 0) - row = 0; + const auto row = grid_.getGridCursor().first; if (event.ShiftDown()) ; @@ -1282,7 +1277,7 @@ class IconUpdater : private wxEvtHandler //update file icons periodically: use S public: IconUpdater(GridDataLeft& provLeft, GridDataRight& provRight, IconBuffer& iconBuffer) : provLeft_(provLeft), provRight_(provRight), iconBuffer_(iconBuffer) { - timer.Connect(wxEVT_TIMER, wxEventHandler(IconUpdater::loadIconsAsynchronously), NULL, this); + timer.Connect(wxEVT_TIMER, wxEventHandler(IconUpdater::loadIconsAsynchronously), nullptr, this); timer.Start(50); //timer interval in ms } @@ -1302,20 +1297,28 @@ private: }; } - -void gridview::setIconSize(Grid& grid, IconBuffer::IconSize sz) +void gridview::setupIcons(Grid& grid, bool show, IconBuffer::IconSize sz) { auto* provLeft = dynamic_cast<GridDataLeft*>(grid.getDataProvider(gridview::COMP_LEFT)); auto* provRight = dynamic_cast<GridDataRight*>(grid.getDataProvider(gridview::COMP_RIGHT)); if (provLeft && provRight) { - std::shared_ptr<IconManager> iconMgr = std::make_shared<IconManager>(sz); - iconMgr->iconUpdater.reset(new IconUpdater(*provLeft, *provRight, iconMgr->iconBuffer)); + if (show) + { + auto iconMgr = std::make_shared<IconManager>(sz); + iconMgr->iconUpdater.reset(new IconUpdater(*provLeft, *provRight, iconMgr->iconBuffer)); - provLeft ->setIconManager(iconMgr); - provRight->setIconManager(iconMgr); - grid.setRowHeight(iconMgr->iconBuffer.getSize() + 1); //+ 1 for line between rows + provLeft ->setIconManager(iconMgr); + provRight->setIconManager(iconMgr); + grid.setRowHeight(iconMgr->iconBuffer.getSize() + 1); //+ 1 for line between rows + } + else + { + provLeft ->setIconManager(nullptr); + provRight->setIconManager(nullptr); + grid.setRowHeight(IconBuffer(IconBuffer::SIZE_SMALL).getSize() + 1); //+ 1 for line between rows + } grid.Refresh(); } else diff --git a/ui/custom_grid.h b/ui/custom_grid.h index 4c07c150..8993777b 100644 --- a/ui/custom_grid.h +++ b/ui/custom_grid.h @@ -28,7 +28,7 @@ std::vector<ColumnAttributeRim> convertConfig(const std::vector<Grid::ColumnA void setSyncPreviewActive(Grid& grid, bool value); -void setIconSize(Grid& grid, IconBuffer::IconSize sz); +void setupIcons(Grid& grid, bool show, IconBuffer::IconSize sz); void clearSelection(Grid& grid); //clear all components @@ -51,22 +51,22 @@ extern const wxEventType EVENT_GRID_SYNC_DIRECTION; struct CheckRowsEvent : public wxCommandEvent { - CheckRowsEvent(int rowFrom, int rowTo, bool setIncluded) : wxCommandEvent(EVENT_GRID_CHECK_ROWS), rowFrom_(rowFrom), rowTo_(rowTo), setIncluded_(setIncluded) {} + CheckRowsEvent(ptrdiff_t rowFrom, ptrdiff_t rowTo, bool setIncluded) : wxCommandEvent(EVENT_GRID_CHECK_ROWS), rowFrom_(rowFrom), rowTo_(rowTo), setIncluded_(setIncluded) {} virtual wxEvent* Clone() const { return new CheckRowsEvent(*this); } - const int rowFrom_; - const int rowTo_; + const ptrdiff_t rowFrom_; + const ptrdiff_t rowTo_; const bool setIncluded_; }; struct SyncDirectionEvent : public wxCommandEvent { - SyncDirectionEvent(int rowFrom, int rowTo, SyncDirection direction) : wxCommandEvent(EVENT_GRID_SYNC_DIRECTION), rowFrom_(rowFrom), rowTo_(rowTo), direction_(direction) {} + SyncDirectionEvent(ptrdiff_t rowFrom, ptrdiff_t rowTo, SyncDirection direction) : wxCommandEvent(EVENT_GRID_SYNC_DIRECTION), rowFrom_(rowFrom), rowTo_(rowTo), direction_(direction) {} virtual wxEvent* Clone() const { return new SyncDirectionEvent(*this); } - const int rowFrom_; - const int rowTo_; + const ptrdiff_t rowFrom_; + const ptrdiff_t rowTo_; const SyncDirection direction_; }; diff --git a/ui/dir_name.cpp b/ui/dir_name.cpp index 84670356..cf43accf 100644 --- a/ui/dir_name.cpp +++ b/ui/dir_name.cpp @@ -24,7 +24,8 @@ void setDirectoryNameImpl(const wxString& dirname, wxDirPickerCtrl* dirPicker, w { const wxString dirFormatted = toWx(getFormattedDirectoryName(toZ(dirname))); - tooltipWnd.SetToolTip(dirFormatted); //wxComboBox bug: the edit control is not updated... http://trac.wxwidgets.org/ticket/12659 + tooltipWnd.SetToolTip(nullptr); //workaround wxComboBox bug http://trac.wxwidgets.org/ticket/10512 / http://trac.wxwidgets.org/ticket/12659 + tooltipWnd.SetToolTip(dirFormatted); //only lord knows when the real bugfix reaches mere mortals via an official release if (staticText) { @@ -89,25 +90,25 @@ DirectoryName<NameControl>::DirectoryName(wxWindow& dropWindow, { //prepare drag & drop setupFileDrop(dropWindow); - dropWindow.Connect(EVENT_DROP_FILE, FileDropEventHandler(DirectoryName::OnFilesDropped), NULL, this); + dropWindow.Connect(EVENT_DROP_FILE, FileDropEventHandler(DirectoryName::OnFilesDropped), nullptr, this); if (dropWindow2) { setupFileDrop(*dropWindow2); - dropWindow2->Connect(EVENT_DROP_FILE, FileDropEventHandler(DirectoryName::OnFilesDropped), NULL, this); + dropWindow2->Connect(EVENT_DROP_FILE, FileDropEventHandler(DirectoryName::OnFilesDropped), nullptr, this); } //keep dirPicker and dirName synchronous - dirName_ .Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DirectoryName::OnWriteDirManually), NULL, this); - dirPicker_.Connect(wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler(DirectoryName::OnDirSelected ), NULL, this); + dirName_ .Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DirectoryName::OnWriteDirManually), nullptr, this); + dirPicker_.Connect(wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler(DirectoryName::OnDirSelected ), nullptr, this); } template <class NameControl> DirectoryName<NameControl>::~DirectoryName() { - dirName_ .Disconnect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DirectoryName::OnWriteDirManually), NULL, this); - dirPicker_.Disconnect(wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler(DirectoryName::OnDirSelected ), NULL, this); + dirName_ .Disconnect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DirectoryName::OnWriteDirManually), nullptr, this); + dirPicker_.Disconnect(wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler(DirectoryName::OnDirSelected ), nullptr, this); } @@ -144,7 +145,7 @@ void DirectoryName<NameControl>::OnFilesDropped(FileDropEvent& event) template <class NameControl> void DirectoryName<NameControl>::OnWriteDirManually(wxCommandEvent& event) { - setDirectoryName(event.GetString(), static_cast<NameControl*>(NULL), &dirPicker_, dirName_, staticText_, 100); //potentially slow network access: wait 100 ms at most + setDirectoryName(event.GetString(), static_cast<NameControl*>(nullptr), &dirPicker_, dirName_, staticText_, 100); //potentially slow network access: wait 100 ms at most event.Skip(); } @@ -153,7 +154,7 @@ template <class NameControl> void DirectoryName<NameControl>::OnDirSelected(wxFileDirPickerEvent& event) { const wxString newPath = event.GetPath(); - setDirectoryName(newPath, &dirName_, NULL, dirName_, staticText_); + setDirectoryName(newPath, &dirName_, nullptr, dirName_, staticText_); event.Skip(); } diff --git a/ui/dir_name.h b/ui/dir_name.h index d491cacc..e49b9302 100644 --- a/ui/dir_name.h +++ b/ui/dir_name.h @@ -25,8 +25,8 @@ public: DirectoryName(wxWindow& dropWindow, wxDirPickerCtrl& dirPicker, NameControl& dirName, - wxStaticText* staticText = NULL, - wxWindow* dropWindow2 = NULL); //optional + wxStaticText* staticText = nullptr, + wxWindow* dropWindow2 = nullptr); //optional ~DirectoryName(); diff --git a/ui/exec_finished_box.cpp b/ui/exec_finished_box.cpp index 06fad778..a8ee9f4a 100644 --- a/ui/exec_finished_box.cpp +++ b/ui/exec_finished_box.cpp @@ -108,19 +108,19 @@ ExecFinishedBox::ExecFinishedBox(wxWindow* parent, const wxValidator& validator, const wxString& name) : wxComboBox(parent, id, value, pos, size, n, choices, style, validator, name), - history_(NULL), + history_(nullptr), defaultCommands(getDefaultCommands()) { //##################################### /*##*/ SetMinSize(wxSize(150, -1)); //## workaround yet another wxWidgets bug: default minimum size is much too large for a wxComboBox //##################################### - Connect(wxEVT_KEY_DOWN, wxKeyEventHandler (ExecFinishedBox::OnKeyEvent ), NULL, this); - Connect(wxEVT_LEFT_DOWN, wxEventHandler (ExecFinishedBox::OnUpdateList), NULL, this); - Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(ExecFinishedBox::OnSelection ), NULL, this); - Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler (ExecFinishedBox::OnMouseWheel), NULL, this); + Connect(wxEVT_KEY_DOWN, wxKeyEventHandler (ExecFinishedBox::OnKeyEvent ), nullptr, this); + Connect(wxEVT_LEFT_DOWN, wxEventHandler (ExecFinishedBox::OnUpdateList), nullptr, this); + Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(ExecFinishedBox::OnSelection ), nullptr, this); + Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler (ExecFinishedBox::OnMouseWheel), nullptr, this); - Connect(wxEVT_REPLACE_BUILT_IN_COMMANDS, wxCommandEventHandler(ExecFinishedBox::OnReplaceBuiltInCmds), NULL, this); + Connect(wxEVT_REPLACE_BUILT_IN_COMMANDS, wxCommandEventHandler(ExecFinishedBox::OnReplaceBuiltInCmds), nullptr, this); } diff --git a/ui/exec_finished_box.h b/ui/exec_finished_box.h index 87108a7d..7578acc6 100644 --- a/ui/exec_finished_box.h +++ b/ui/exec_finished_box.h @@ -31,7 +31,7 @@ public: const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, int n = 0, - const wxString choices[] = NULL, + const wxString choices[] = nullptr, long style = 0, const wxValidator& validator = wxDefaultValidator, const wxString& name = wxComboBoxNameStr); diff --git a/ui/folder_history_box.cpp b/ui/folder_history_box.cpp index 7f7b08ef..76ed785e 100644 --- a/ui/folder_history_box.cpp +++ b/ui/folder_history_box.cpp @@ -31,14 +31,14 @@ FolderHistoryBox::FolderHistoryBox(wxWindow* parent, /*##*/ SetMinSize(wxSize(150, -1)); //## workaround yet another wxWidgets bug: default minimum size is much too large for a wxComboBox //##################################### - Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(FolderHistoryBox::OnKeyEvent ), NULL, this); - Connect(wxEVT_LEFT_DOWN, wxEventHandler(FolderHistoryBox::OnUpdateList), NULL, this); - Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(FolderHistoryBox::OnSelection ), NULL, this); - Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(FolderHistoryBox::OnMouseWheel), NULL, this); + Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(FolderHistoryBox::OnKeyEvent ), nullptr, this); + Connect(wxEVT_LEFT_DOWN, wxEventHandler(FolderHistoryBox::OnUpdateList), nullptr, this); + Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(FolderHistoryBox::OnSelection ), nullptr, this); + Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(FolderHistoryBox::OnMouseWheel), nullptr, this); #if wxCHECK_VERSION(2, 9, 1) - Connect(wxEVT_COMMAND_COMBOBOX_DROPDOWN, wxCommandEventHandler(FolderHistoryBox::OnShowDropDown), NULL, this); - Connect(wxEVT_COMMAND_COMBOBOX_CLOSEUP, wxCommandEventHandler(FolderHistoryBox::OnHideDropDown), NULL, this); + Connect(wxEVT_COMMAND_COMBOBOX_DROPDOWN, wxCommandEventHandler(FolderHistoryBox::OnShowDropDown), nullptr, this); + Connect(wxEVT_COMMAND_COMBOBOX_CLOSEUP, wxCommandEventHandler(FolderHistoryBox::OnHideDropDown), nullptr, this); #endif } @@ -152,7 +152,7 @@ void FolderHistoryBox::OnMouseWheel(wxMouseEvent& event) if (!wnd) break; - if (dynamic_cast<wxScrolledWindow*>(wnd) != NULL) + if (dynamic_cast<wxScrolledWindow*>(wnd) != nullptr) { wnd->GetEventHandler()->AddPendingEvent(event); break; diff --git a/ui/folder_history_box.h b/ui/folder_history_box.h index d28f3c72..24ff1725 100644 --- a/ui/folder_history_box.h +++ b/ui/folder_history_box.h @@ -71,7 +71,7 @@ public: const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, int n = 0, - const wxString choices[] = NULL, + const wxString choices[] = nullptr, long style = 0, const wxValidator& validator = wxDefaultValidator, const wxString& name = wxComboBoxNameStr); diff --git a/ui/folder_pair.h b/ui/folder_pair.h index 010d6162..7b1e7643 100644 --- a/ui/folder_pair.h +++ b/ui/folder_pair.h @@ -71,12 +71,12 @@ public: //test for Null-filter if (isNullFilter(localFilter)) { - setImage(*basicPanel_.m_bpButtonLocalFilter, GlobalResources::getImage(wxT("filterSmallGrey"))); + setImage(*basicPanel_.m_bpButtonLocalFilter, GlobalResources::getImage(L"filterOffSmall")); basicPanel_.m_bpButtonLocalFilter->SetToolTip(_("No filter selected")); } else { - setImage(*basicPanel_.m_bpButtonLocalFilter, GlobalResources::getImage(wxT("filterSmall"))); + setImage(*basicPanel_.m_bpButtonLocalFilter, GlobalResources::getImage(L"filterOnSmall")); basicPanel_.m_bpButtonLocalFilter->SetToolTip(_("Filter is active")); } } @@ -86,13 +86,13 @@ protected: basicPanel_(basicPanel) { //register events for removal of alternate configuration - basicPanel_.m_bpButtonAltCompCfg ->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(FolderPairPanelBasic::OnAltCompCfgContext ), NULL, this); - basicPanel_.m_bpButtonAltSyncCfg ->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(FolderPairPanelBasic::OnAltSyncCfgContext ), NULL, this); - basicPanel_.m_bpButtonLocalFilter->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(FolderPairPanelBasic::OnLocalFilterCfgContext), NULL, this); + basicPanel_.m_bpButtonAltCompCfg ->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(FolderPairPanelBasic::OnAltCompCfgContext ), nullptr, this); + basicPanel_.m_bpButtonAltSyncCfg ->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(FolderPairPanelBasic::OnAltSyncCfgContext ), nullptr, this); + basicPanel_.m_bpButtonLocalFilter->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(FolderPairPanelBasic::OnLocalFilterCfgContext), nullptr, this); - basicPanel_.m_bpButtonAltCompCfg-> Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FolderPairPanelBasic::OnAltCompCfg ), NULL, this); - basicPanel_.m_bpButtonAltSyncCfg-> Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FolderPairPanelBasic::OnAltSyncCfg ), NULL, this); - basicPanel_.m_bpButtonLocalFilter->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FolderPairPanelBasic::OnLocalFilterCfg), NULL, this); + basicPanel_.m_bpButtonAltCompCfg-> Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FolderPairPanelBasic::OnAltCompCfg ), nullptr, this); + basicPanel_.m_bpButtonAltSyncCfg-> Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FolderPairPanelBasic::OnAltSyncCfg ), nullptr, this); + basicPanel_.m_bpButtonLocalFilter->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FolderPairPanelBasic::OnLocalFilterCfg), nullptr, this); basicPanel_.m_bpButtonRemovePair->SetBitmapLabel(GlobalResources::getImage(L"removeFolderPair")); } @@ -119,21 +119,21 @@ private: void OnAltCompCfgContext(wxCommandEvent& event) { ContextMenu menu; - menu.addItem(_("Remove alternate settings"), [this] { this->removeAltCompCfg(); }, NULL, altCompConfig.get() != NULL); + menu.addItem(_("Remove alternate settings"), [this] { this->removeAltCompCfg(); }, nullptr, altCompConfig.get() != nullptr); menu.popup(basicPanel_); } void OnAltSyncCfgContext(wxCommandEvent& event) { ContextMenu menu; - menu.addItem(_("Remove alternate settings"), [this] { this->removeAltSyncCfg(); }, NULL, altSyncConfig.get() != NULL); + menu.addItem(_("Remove alternate settings"), [this] { this->removeAltSyncCfg(); }, nullptr, altSyncConfig.get() != nullptr); menu.popup(basicPanel_); } void OnLocalFilterCfgContext(wxCommandEvent& event) { ContextMenu menu; - menu.addItem(_("Clear filter settings"), [this] { this->removeLocalFilterCfg(); }, NULL, !isNullFilter(localFilter)); + menu.addItem(_("Clear filter settings"), [this] { this->removeLocalFilterCfg(); }, nullptr, !isNullFilter(localFilter)); menu.popup(basicPanel_); } @@ -169,8 +169,8 @@ private: if (showSyncConfigDlg(cmpCfg.compareVar, syncCfg, - NULL, - NULL) == ReturnSyncConfig::BUTTON_OKAY) //optional input parameter + nullptr, + nullptr) == ReturnSyncConfig::BUTTON_OKAY) //optional input parameter { altSyncConfig = std::make_shared<SyncConfig>(syncCfg); refreshButtons(); @@ -196,7 +196,7 @@ private: GuiPanel& basicPanel_; //panel to be enhanced by this template //alternate configuration attached to it - AltCompCfgPtr altCompConfig; //optional: present if non-NULL + AltCompCfgPtr altCompConfig; //optional AltSyncCfgPtr altSyncConfig; // FilterConfig localFilter; }; diff --git a/ui/grid_view.cpp b/ui/grid_view.cpp index 8460b238..2a3e84e3 100644 --- a/ui/grid_view.cpp +++ b/ui/grid_view.cpp @@ -94,13 +94,13 @@ void GridView::updateView(Predicate pred) } -int GridView::findRowDirect(FileSystemObject::ObjectIdConst objId) const +ptrdiff_t GridView::findRowDirect(FileSystemObject::ObjectIdConst objId) const { auto iter = rowPositions.find(objId); return iter != rowPositions.end() ? iter->second : -1; } -int GridView::findRowFirstChild(const HierarchyObject* hierObj) const +ptrdiff_t GridView::findRowFirstChild(const HierarchyObject* hierObj) const { auto iter = rowPositionsFirstChild.find(hierObj); return iter != rowPositionsFirstChild.end() ? iter->second : -1; @@ -289,7 +289,7 @@ void GridView::removeInvalidRows() rowPositionsFirstChild.clear(); //remove rows that have been deleted meanwhile - vector_remove_if(sortedRef, [&](const RefIndex& refIdx) { return FileSystemObject::retrieve(refIdx.objId) == NULL; }); + vector_remove_if(sortedRef, [&](const RefIndex& refIdx) { return FileSystemObject::retrieve(refIdx.objId) == nullptr; }); } @@ -356,9 +356,9 @@ public: const FileSystemObject* fsObjA = FileSystemObject::retrieve(a.objId); const FileSystemObject* fsObjB = FileSystemObject::retrieve(b.objId); - if (fsObjA == NULL) //invalid rows shall appear at the end + if (!fsObjA) //invalid rows shall appear at the end return false; - else if (fsObjB == NULL) + else if (!fsObjB) return true; return lessRelativeName<ascending>(*fsObjA, *fsObjB); @@ -374,9 +374,9 @@ public: { const FileSystemObject* fsObjA = FileSystemObject::retrieve(a.objId); const FileSystemObject* fsObjB = FileSystemObject::retrieve(b.objId); - if (fsObjA == NULL) //invalid rows shall appear at the end + if (!fsObjA) //invalid rows shall appear at the end return false; - else if (fsObjB == NULL) + else if (!fsObjB) return true; return lessShortFileName<ascending, side>(*fsObjA, *fsObjB); @@ -392,9 +392,9 @@ public: { const FileSystemObject* fsObjA = FileSystemObject::retrieve(a.objId); const FileSystemObject* fsObjB = FileSystemObject::retrieve(b.objId); - if (fsObjA == NULL) //invalid rows shall appear at the end + if (!fsObjA) //invalid rows shall appear at the end return false; - else if (fsObjB == NULL) + else if (!fsObjB) return true; return lessFilesize<ascending, side>(*fsObjA, *fsObjB); @@ -410,9 +410,9 @@ public: { const FileSystemObject* fsObjA = FileSystemObject::retrieve(a.objId); const FileSystemObject* fsObjB = FileSystemObject::retrieve(b.objId); - if (fsObjA == NULL) //invalid rows shall appear at the end + if (!fsObjA) //invalid rows shall appear at the end return false; - else if (fsObjB == NULL) + else if (!fsObjB) return true; return lessFiletime<ascending, side>(*fsObjA, *fsObjB); @@ -428,9 +428,9 @@ public: { const FileSystemObject* fsObjA = FileSystemObject::retrieve(a.objId); const FileSystemObject* fsObjB = FileSystemObject::retrieve(b.objId); - if (fsObjA == NULL) //invalid rows shall appear at the end + if (!fsObjA) //invalid rows shall appear at the end return false; - else if (fsObjB == NULL) + else if (!fsObjB) return true; return lessExtension<ascending, side>(*fsObjA, *fsObjB); @@ -446,9 +446,9 @@ public: { const FileSystemObject* fsObjA = FileSystemObject::retrieve(a.objId); const FileSystemObject* fsObjB = FileSystemObject::retrieve(b.objId); - if (fsObjA == NULL) //invalid rows shall appear at the end + if (!fsObjA) //invalid rows shall appear at the end return false; - else if (fsObjB == NULL) + else if (!fsObjB) return true; return lessCmpResult<ascending>(*fsObjA, *fsObjB); @@ -464,9 +464,9 @@ public: { const FileSystemObject* fsObjA = FileSystemObject::retrieve(a.objId); const FileSystemObject* fsObjB = FileSystemObject::retrieve(b.objId); - if (fsObjA == NULL) //invalid rows shall appear at the end + if (!fsObjA) //invalid rows shall appear at the end return false; - else if (fsObjB == NULL) + else if (!fsObjB) return true; return lessSyncDirection<ascending>(*fsObjA, *fsObjB); diff --git a/ui/grid_view.h b/ui/grid_view.h index 8623f11f..fc828f91 100644 --- a/ui/grid_view.h +++ b/ui/grid_view.h @@ -19,13 +19,13 @@ class GridView { public: //direct data access via row number - const FileSystemObject* getObject(size_t row) const; //returns NULL if object is not found; complexity: constant! + const FileSystemObject* getObject(size_t row) const; //returns nullptr if object is not found; complexity: constant! /**/ FileSystemObject* getObject(size_t row); // size_t rowsOnView() const { return viewRef .size(); } //only visible elements size_t rowsTotal () const { return sortedRef.size(); } //total rows available - //get references to FileSystemObject: no NULL-check needed! Everything's bound. + //get references to FileSystemObject: no nullptr-check needed! Everything's bound. void getAllFileRef(const std::set<size_t>& rows, std::vector<FileSystemObject*>& output); struct StatusCmpResult @@ -109,17 +109,17 @@ public: bool onLeft_; bool ascending_; }; - const SortInfo* getSortInfo() const { return currentSort.get(); } //return NULL if currently not sorted + const SortInfo* getSortInfo() const { return currentSort.get(); } //return nullptr if currently not sorted - int findRowDirect(FileSystemObject::ObjectIdConst objId) const; // find an object's row position on view list directly, return < 0 if not found - int findRowFirstChild(const HierarchyObject* hierObj) const; // find first child of DirMapping or BaseDirMapping *on sorted sub view* + ptrdiff_t findRowDirect(FileSystemObject::ObjectIdConst objId) const; // find an object's row position on view list directly, return < 0 if not found + ptrdiff_t findRowFirstChild(const HierarchyObject* hierObj) const; // find first child of DirMapping or BaseDirMapping *on sorted sub view* //"hierObj" may be invalid, it is NOT dereferenced, return < 0 if not found private: struct RefIndex { - RefIndex(unsigned int folderInd, FileSystemObject::ObjectId id) : - folderIndex(folderInd), + RefIndex(size_t folderInd, FileSystemObject::ObjectId id) : + folderIndex(static_cast<unsigned int>(folderInd)), objId(id) {} unsigned int folderIndex; FileSystemObject::ObjectId objId; @@ -184,10 +184,8 @@ private: inline const FileSystemObject* GridView::getObject(size_t row) const { - if (row < rowsOnView()) - return FileSystemObject::retrieve(viewRef[row]); - else - return NULL; + return row < rowsOnView() ? + FileSystemObject::retrieve(viewRef[row]) : nullptr; } inline diff --git a/ui/gui_generated.cpp b/ui/gui_generated.cpp index 124354e6..9caa466a 100644 --- a/ui/gui_generated.cpp +++ b/ui/gui_generated.cpp @@ -1,19 +1,10 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Dec 2 2011) +// C++ code generated with wxFormBuilder (version Mar 17 2012) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! /////////////////////////////////////////////////////////////////////////// -#include "../wx+/button.h" -#include "../wx+/dir_picker.h" -#include "../wx+/graph.h" -#include "../wx+/grid.h" -#include "../wx+/toggle_button.h" -#include "exec_finished_box.h" -#include "folder_history_box.h" -#include "wx_form_build_hide_warnings.h" - #include "gui_generated.h" /////////////////////////////////////////////////////////////////////////// @@ -40,8 +31,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const #endif m_menuFile->Append( m_menuItem11 ); - wxMenuItem* m_separator1; - m_separator1 = m_menuFile->AppendSeparator(); + m_menuFile->AppendSeparator(); m_menuItemNew = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("&New") ) + wxT('\t') + wxT("Ctrl+N"), wxEmptyString, wxITEM_NORMAL ); #ifdef __WXMSW__ @@ -57,8 +47,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_menuItemLoad = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("&Load configuration...") ) + wxT('\t') + wxT("Ctrl+O"), wxEmptyString, wxITEM_NORMAL ); m_menuFile->Append( m_menuItemLoad ); - wxMenuItem* m_separator3; - m_separator3 = m_menuFile->AppendSeparator(); + m_menuFile->AppendSeparator(); wxMenuItem* m_menuItem4; m_menuItem4 = new wxMenuItem( m_menuFile, wxID_EXIT, wxString( _("&Quit") ) + wxT('\t') + wxT("Ctrl+Q"), wxEmptyString, wxITEM_NORMAL ); @@ -70,10 +59,9 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_menuLanguages = new wxMenu(); m_menuAdvanced->Append( -1, _("&Language"), m_menuLanguages ); - wxMenuItem* m_separator4; - m_separator4 = m_menuAdvanced->AppendSeparator(); + m_menuAdvanced->AppendSeparator(); - m_menuItemGlobSett = new wxMenuItem( m_menuAdvanced, wxID_ANY, wxString( _("&Global settings...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuItemGlobSett = new wxMenuItem( m_menuAdvanced, wxID_PREFERENCES, wxString( _("&Global settings...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuAdvanced->Append( m_menuItemGlobSett ); m_menuItem7 = new wxMenuItem( m_menuAdvanced, wxID_ANY, wxString( _("&Create batch job...") ) , wxEmptyString, wxITEM_NORMAL ); @@ -86,15 +74,13 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_menubar1->Append( m_menuAdvanced, _("&Advanced") ); m_menuHelp = new wxMenu(); - wxMenuItem* m_menuItemReadme; - m_menuItemReadme = new wxMenuItem( m_menuHelp, wxID_ANY, wxString( _("&Content") ) + wxT('\t') + wxT("F1"), wxEmptyString, wxITEM_NORMAL ); - m_menuHelp->Append( m_menuItemReadme ); + m_menuItemManual = new wxMenuItem( m_menuHelp, wxID_HELP, wxString( _("&Content") ) + wxT('\t') + wxT("F1"), wxEmptyString, wxITEM_NORMAL ); + m_menuHelp->Append( m_menuItemManual ); m_menuItemCheckVer = new wxMenuItem( m_menuHelp, wxID_ANY, wxString( _("&Check for new version") ) , wxEmptyString, wxITEM_NORMAL ); m_menuHelp->Append( m_menuItemCheckVer ); - wxMenuItem* m_separator5; - m_separator5 = m_menuHelp->AppendSeparator(); + m_menuHelp->AppendSeparator(); m_menuItemAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( _("&About...") ) + wxT('\t') + wxT("Shift+F1"), wxEmptyString, wxITEM_NORMAL ); m_menuHelp->Append( m_menuItemAbout ); @@ -146,6 +132,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer30->Add( m_buttonAbort, 0, wxALIGN_CENTER_VERTICAL, 5 ); + fgSizer121->Add( bSizer30, 0, wxALIGN_CENTER_VERTICAL, 5 ); m_bpButtonCmpConfig = new wxBitmapButton( m_panelTopButtons, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,42 ), wxBU_AUTODRAW ); @@ -153,8 +140,10 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const fgSizer121->Add( m_bpButtonCmpConfig, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 3 ); + bSizer155->Add( fgSizer121, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 ); + bSizerTopButtons->Add( bSizer155, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -189,13 +178,16 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const fgSizer12->Add( m_buttonStartSync, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer1551->Add( fgSizer12, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 ); bSizer1551->Add( 15, 0, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizerTopButtons->Add( bSizer1551, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_panelTopButtons->SetSizer( bSizerTopButtons ); m_panelTopButtons->Layout(); bSizerTopButtons->Fit( m_panelTopButtons ); @@ -224,6 +216,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_staticTextFinalPathLeft->Wrap( -1 ); bSizer181->Add( m_staticTextFinalPathLeft, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 2 ); + bSizer180->Add( bSizer181, 0, 0, 5 ); wxBoxSizer* bSizer182; @@ -247,8 +240,10 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer182->Add( m_dirPickerLeft, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer180->Add( bSizer182, 0, wxEXPAND, 5 ); + m_panelTopLeft->SetSizer( bSizer180 ); m_panelTopLeft->Layout(); bSizer180->Fit( m_panelTopLeft ); @@ -284,8 +279,10 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer160->Add( 0, 0, 1, wxEXPAND, 5 ); + bSizer93->Add( bSizer160, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + m_panelTopMiddle->SetSizer( bSizer93 ); m_panelTopMiddle->Layout(); bSizer93->Fit( m_panelTopMiddle ); @@ -307,6 +304,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_staticTextFinalPathRight->Wrap( -1 ); bSizer184->Add( m_staticTextFinalPathRight, 0, wxTOP|wxBOTTOM|wxALIGN_CENTER_VERTICAL, 2 ); + bSizer183->Add( bSizer184, 0, 0, 5 ); wxBoxSizer* bSizer179; @@ -320,13 +318,16 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer179->Add( m_dirPickerRight, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer183->Add( bSizer179, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + m_panelTopRight->SetSizer( bSizer183 ); m_panelTopRight->Layout(); bSizer183->Fit( m_panelTopRight ); bSizer91->Add( m_panelTopRight, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, 5 ); + bSizer1601->Add( bSizer91, 0, wxEXPAND, 5 ); m_scrolledWindowFolderPairs = new wxScrolledWindow( m_panelDirectoryPairs, wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), wxHSCROLL|wxVSCROLL ); @@ -335,11 +336,13 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizerAddFolderPairs = new wxBoxSizer( wxVERTICAL ); + m_scrolledWindowFolderPairs->SetSizer( bSizerAddFolderPairs ); m_scrolledWindowFolderPairs->Layout(); bSizerAddFolderPairs->Fit( m_scrolledWindowFolderPairs ); bSizer1601->Add( m_scrolledWindowFolderPairs, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + m_panelDirectoryPairs->SetSizer( bSizer1601 ); m_panelDirectoryPairs->Layout(); bSizer1601->Fit( m_panelDirectoryPairs ); @@ -369,6 +372,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer151->Add( m_bpButtonLoad, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizerConfig->Add( bSizer151, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); m_listBoxHistory = new wxListBox( m_panelConfig, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED|wxLB_NEEDED_SB|wxLB_SORT ); @@ -377,6 +381,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizerConfig->Add( m_listBoxHistory, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + m_panelConfig->SetSizer( bSizerConfig ); m_panelConfig->Layout(); bSizerConfig->Fit( m_panelConfig ); @@ -394,6 +399,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer171->Add( m_checkBoxHideFilt, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_panelFilter->SetSizer( bSizer171 ); m_panelFilter->Layout(); bSizer171->Fit( m_panelFilter ); @@ -416,7 +422,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const fgSizer5->Add( m_bitmapCreate, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); m_textCtrlCreate = new wxTextCtrl( m_panelStatistics, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY|wxTE_RIGHT ); - m_textCtrlCreate->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_textCtrlCreate->SetBackgroundColour( wxColour( 224, 224, 224 ) ); m_textCtrlCreate->SetToolTip( _("Number of files and directories that will be created") ); fgSizer5->Add( m_textCtrlCreate, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -427,11 +433,12 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const fgSizer5->Add( m_bitmapUpdate, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); m_textCtrlUpdate = new wxTextCtrl( m_panelStatistics, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY|wxTE_RIGHT ); - m_textCtrlUpdate->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_textCtrlUpdate->SetBackgroundColour( wxColour( 224, 224, 224 ) ); m_textCtrlUpdate->SetToolTip( _("Number of files that will be overwritten") ); fgSizer5->Add( m_textCtrlUpdate, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizerStatistics->Add( fgSizer5, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 ); wxFlexGridSizer* fgSizer6; @@ -445,7 +452,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const fgSizer6->Add( m_bitmapDelete, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); m_textCtrlDelete = new wxTextCtrl( m_panelStatistics, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY|wxTE_RIGHT ); - m_textCtrlDelete->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_textCtrlDelete->SetBackgroundColour( wxColour( 224, 224, 224 ) ); m_textCtrlDelete->SetToolTip( _("Number of files and directories that will be deleted") ); fgSizer6->Add( m_textCtrlDelete, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -456,16 +463,18 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const fgSizer6->Add( m_bitmapData, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); m_textCtrlData = new wxTextCtrl( m_panelStatistics, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY|wxTE_RIGHT ); - m_textCtrlData->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_textCtrlData->SetBackgroundColour( wxColour( 224, 224, 224 ) ); m_textCtrlData->SetToolTip( _("Total amount of data that will be transferred") ); fgSizer6->Add( m_textCtrlData, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizerStatistics->Add( fgSizer6, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 ); bSizerStatistics->Add( 0, 0, 1, wxEXPAND, 5 ); + m_panelStatistics->SetSizer( bSizerStatistics ); m_panelStatistics->Layout(); bSizerStatistics->Fit( m_panelStatistics ); @@ -522,6 +531,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizerViewFilter->Add( 0, 0, 1, wxEXPAND, 5 ); + m_panelViewFilter->SetSizer( bSizerViewFilter ); m_panelViewFilter->Layout(); bSizerViewFilter->Fit( m_panelViewFilter ); @@ -550,6 +560,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_staticTextStatusLeftDirs->Wrap( -1 ); bSizerStatusLeftDirectories->Add( m_staticTextStatusLeftDirs, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer53->Add( bSizerStatusLeftDirectories, 0, wxALIGN_CENTER_VERTICAL, 5 ); bSizerStatusLeftFiles = new wxBoxSizer( wxHORIZONTAL ); @@ -574,11 +585,13 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_staticTextStatusLeftBytes->Wrap( -1 ); bSizerStatusLeftFiles->Add( m_staticTextStatusLeftBytes, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer53->Add( bSizerStatusLeftFiles, 0, wxALIGN_CENTER_VERTICAL, 5 ); bSizer53->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer451->Add( bSizer53, 1, wxALIGN_BOTTOM|wxEXPAND, 5 ); m_staticline9 = new wxStaticLine( m_panelStatusBar, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ); @@ -589,7 +602,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_staticTextStatusMiddle = new wxStaticText( m_panelStatusBar, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextStatusMiddle->Wrap( -1 ); - m_staticTextStatusMiddle->SetFont( wxFont( 8, 74, 90, 92, false, wxT("MS Shell Dlg 2") ) ); + m_staticTextStatusMiddle->SetFont( wxFont( 8, 70, 90, 92, false, wxEmptyString ) ); bSizer451->Add( m_staticTextStatusMiddle, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); @@ -617,6 +630,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_staticTextStatusRightDirs->Wrap( -1 ); bSizerStatusRightDirectories->Add( m_staticTextStatusRightDirs, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer52->Add( bSizerStatusRightDirectories, 0, wxALIGN_CENTER_VERTICAL, 5 ); bSizerStatusRightFiles = new wxBoxSizer( wxHORIZONTAL ); @@ -641,6 +655,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_staticTextStatusRightBytes->Wrap( -1 ); bSizerStatusRightFiles->Add( m_staticTextStatusRightBytes, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer52->Add( bSizerStatusRightFiles, 0, wxALIGN_CENTER_VERTICAL, 5 ); wxBoxSizer* bSizer50; @@ -652,15 +667,19 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_bitmapResizeCorner = new wxStaticBitmap( m_panelStatusBar, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 10,10 ), 0 ); bSizer50->Add( m_bitmapResizeCorner, 0, wxALIGN_BOTTOM, 5 ); + bSizer52->Add( bSizer50, 1, wxALIGN_BOTTOM, 5 ); + bSizer451->Add( bSizer52, 1, wxALIGN_BOTTOM|wxEXPAND, 5 ); + m_panelStatusBar->SetSizer( bSizer451 ); m_panelStatusBar->Layout(); bSizer451->Fit( m_panelStatusBar ); bSizerPanelHolder->Add( m_panelStatusBar, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + this->SetSizer( bSizerPanelHolder ); this->Layout(); @@ -675,7 +694,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const this->Connect( m_menuItemGlobSett->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuGlobalSettings ) ); this->Connect( m_menuItem7->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuBatchJob ) ); this->Connect( m_menuItem5->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuExportFileList ) ); - this->Connect( m_menuItemReadme->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnShowHelp ) ); + this->Connect( m_menuItemManual->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnShowHelp ) ); this->Connect( m_menuItemCheckVer->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuCheckVersion ) ); this->Connect( m_menuItemAbout->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuAbout ) ); m_buttonCompare->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnCompare ), NULL, this ); @@ -719,10 +738,10 @@ MainDialogGenerated::~MainDialogGenerated() this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnSaveConfig ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnLoadConfig ) ); this->Disconnect( wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuQuit ) ); - this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuGlobalSettings ) ); + this->Disconnect( wxID_PREFERENCES, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuGlobalSettings ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuBatchJob ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuExportFileList ) ); - this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnShowHelp ) ); + this->Disconnect( wxID_HELP, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnShowHelp ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuCheckVersion ) ); this->Disconnect( wxID_ABOUT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuAbout ) ); m_buttonCompare->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnCompare ), NULL, this ); @@ -781,6 +800,7 @@ FolderPairGenerated::FolderPairGenerated( wxWindow* parent, wxWindowID id, const bSizer134->Add( m_dirPickerLeft, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_panelLeft->SetSizer( bSizer134 ); m_panelLeft->Layout(); bSizer134->Fit( m_panelLeft ); @@ -805,6 +825,7 @@ FolderPairGenerated::FolderPairGenerated( wxWindow* parent, wxWindowID id, const bSizer95->Add( 0, 0, 1, wxEXPAND, 5 ); + m_panel20->SetSizer( bSizer95 ); m_panel20->Layout(); bSizer95->Fit( m_panel20 ); @@ -824,11 +845,13 @@ FolderPairGenerated::FolderPairGenerated( wxWindow* parent, wxWindowID id, const bSizer135->Add( m_dirPickerRight, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_panelRight->SetSizer( bSizer135 ); m_panelRight->Layout(); bSizer135->Fit( m_panelRight ); bSizer74->Add( m_panelRight, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, 5 ); + this->SetSizer( bSizer74 ); this->Layout(); bSizer74->Fit( this ); @@ -856,10 +879,11 @@ CompareStatusGenerated::CompareStatusGenerated( wxWindow* parent, wxWindowID id, bSizer48->Add( m_staticText30, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 ); m_textCtrlStatus = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY ); - m_textCtrlStatus->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_textCtrlStatus->SetBackgroundColour( wxColour( 224, 224, 224 ) ); bSizer48->Add( m_textCtrlStatus, 1, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer40->Add( bSizer48, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); m_gauge2 = new wxGauge( this, wxID_ANY, 100, wxDefaultPosition, wxSize( -1,14 ), wxGA_HORIZONTAL|wxGA_SMOOTH ); @@ -880,10 +904,11 @@ CompareStatusGenerated::CompareStatusGenerated( wxWindow* parent, wxWindowID id, m_staticTextScanned = new wxStaticText( this, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextScanned->Wrap( -1 ); - m_staticTextScanned->SetFont( wxFont( 9, 74, 90, 92, false, wxT("Arial") ) ); + m_staticTextScanned->SetFont( wxFont( 9, 70, 90, 92, false, wxEmptyString ) ); bSizerFilesFound->Add( m_staticTextScanned, 0, wxALIGN_BOTTOM|wxLEFT, 5 ); + bSizer157->Add( bSizerFilesFound, 0, 0, 5 ); bSizerFilesRemaining = new wxBoxSizer( wxHORIZONTAL ); @@ -899,32 +924,35 @@ CompareStatusGenerated::CompareStatusGenerated( wxWindow* parent, wxWindowID id, m_staticTextFilesRemaining = new wxStaticText( this, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextFilesRemaining->Wrap( -1 ); - m_staticTextFilesRemaining->SetFont( wxFont( 9, 74, 90, 92, false, wxT("Arial") ) ); + m_staticTextFilesRemaining->SetFont( wxFont( 9, 70, 90, 92, false, wxEmptyString ) ); bSizer154->Add( m_staticTextFilesRemaining, 0, wxALIGN_BOTTOM, 5 ); m_staticText117 = new wxStaticText( this, wxID_ANY, _("("), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText117->Wrap( -1 ); - m_staticText117->SetFont( wxFont( 9, 74, 90, 90, false, wxT("Arial") ) ); + m_staticText117->SetFont( wxFont( 9, 70, 90, 90, false, wxEmptyString ) ); bSizer154->Add( m_staticText117, 0, wxLEFT|wxALIGN_BOTTOM, 5 ); m_staticTextDataRemaining = new wxStaticText( this, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextDataRemaining->Wrap( -1 ); - m_staticTextDataRemaining->SetFont( wxFont( 9, 74, 90, 90, false, wxT("Arial") ) ); + m_staticTextDataRemaining->SetFont( wxFont( 9, 70, 90, 90, false, wxEmptyString ) ); bSizer154->Add( m_staticTextDataRemaining, 0, wxALIGN_BOTTOM, 5 ); m_staticText118 = new wxStaticText( this, wxID_ANY, _(")"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText118->Wrap( -1 ); - m_staticText118->SetFont( wxFont( 9, 74, 90, 90, false, wxT("Arial") ) ); + m_staticText118->SetFont( wxFont( 9, 70, 90, 90, false, wxEmptyString ) ); bSizer154->Add( m_staticText118, 0, wxALIGN_BOTTOM, 5 ); + bSizerFilesRemaining->Add( bSizer154, 0, wxALIGN_BOTTOM|wxLEFT, 5 ); + bSizer157->Add( bSizerFilesRemaining, 0, 0, 5 ); + bSizer42->Add( bSizer157, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -940,10 +968,11 @@ CompareStatusGenerated::CompareStatusGenerated( wxWindow* parent, wxWindowID id, m_staticTextSpeed = new wxStaticText( this, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextSpeed->Wrap( -1 ); - m_staticTextSpeed->SetFont( wxFont( 9, 74, 90, 92, false, wxT("Arial") ) ); + m_staticTextSpeed->SetFont( wxFont( 9, 70, 90, 92, false, wxEmptyString ) ); sSizerSpeed->Add( m_staticTextSpeed, 0, wxLEFT|wxALIGN_BOTTOM, 5 ); + bSizer42->Add( sSizerSpeed, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -951,7 +980,7 @@ CompareStatusGenerated::CompareStatusGenerated( wxWindow* parent, wxWindowID id, sSizerTimeRemaining = new wxBoxSizer( wxHORIZONTAL ); - m_staticTextTimeRemFixed = new wxStaticText( this, wxID_ANY, _("Time remaining:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextTimeRemFixed = new wxStaticText( this, wxID_ANY, _("Remaining time:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextTimeRemFixed->Wrap( -1 ); m_staticTextTimeRemFixed->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); @@ -959,10 +988,11 @@ CompareStatusGenerated::CompareStatusGenerated( wxWindow* parent, wxWindowID id, m_staticTextRemTime = new wxStaticText( this, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextRemTime->Wrap( -1 ); - m_staticTextRemTime->SetFont( wxFont( 9, 74, 90, 92, false, wxT("Arial") ) ); + m_staticTextRemTime->SetFont( wxFont( 9, 70, 90, 92, false, wxEmptyString ) ); sSizerTimeRemaining->Add( m_staticTextRemTime, 0, wxLEFT|wxALIGN_BOTTOM, 5 ); + bSizer42->Add( sSizerTimeRemaining, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -971,7 +1001,7 @@ CompareStatusGenerated::CompareStatusGenerated( wxWindow* parent, wxWindowID id, sSizerTimeElapsed = new wxBoxSizer( wxHORIZONTAL ); wxStaticText* m_staticText37; - m_staticText37 = new wxStaticText( this, wxID_ANY, _("Time elapsed:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText37 = new wxStaticText( this, wxID_ANY, _("Elapsed time:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText37->Wrap( -1 ); m_staticText37->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); @@ -979,17 +1009,20 @@ CompareStatusGenerated::CompareStatusGenerated( wxWindow* parent, wxWindowID id, m_staticTextTimeElapsed = new wxStaticText( this, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextTimeElapsed->Wrap( -1 ); - m_staticTextTimeElapsed->SetFont( wxFont( 9, 74, 90, 92, false, wxT("Arial") ) ); + m_staticTextTimeElapsed->SetFont( wxFont( 9, 70, 90, 92, false, wxEmptyString ) ); sSizerTimeElapsed->Add( m_staticTextTimeElapsed, 0, wxLEFT|wxALIGN_BOTTOM, 5 ); + bSizer42->Add( sSizerTimeElapsed, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer40->Add( bSizer42, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); bSizer40->Add( 0, 0, 1, wxEXPAND, 5 ); + this->SetSizer( bSizer40 ); this->Layout(); bSizer40->Fit( this ); @@ -1001,7 +1034,7 @@ CompareStatusGenerated::~CompareStatusGenerated() BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) { - this->SetSizeHints( wxSize( 560,320 ), wxDefaultSize ); + this->SetSizeHints( wxSize( 560,300 ), wxDefaultSize ); wxBoxSizer* bSizer54; bSizer54 = new wxBoxSizer( wxVERTICAL ); @@ -1010,7 +1043,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer87 = new wxBoxSizer( wxHORIZONTAL ); m_bitmap27 = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), 0 ); - bSizer87->Add( m_bitmap27, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + bSizer87->Add( m_bitmap27, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); m_panel8 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER|wxTAB_TRAVERSAL ); m_panel8->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT ) ); @@ -1020,36 +1053,30 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS m_staticText56 = new wxStaticText( m_panel8, wxID_ANY, _("Batch job"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText56->Wrap( -1 ); - m_staticText56->SetFont( wxFont( 16, 70, 90, 92, false, wxEmptyString ) ); + m_staticText56->SetFont( wxFont( 14, 70, 90, 92, false, wxEmptyString ) ); bSizer72->Add( m_staticText56, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); + m_panel8->SetSizer( bSizer72 ); m_panel8->Layout(); bSizer72->Fit( m_panel8 ); - bSizer87->Add( m_panel8, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - - bSizer87->Add( 5, 0, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - wxBoxSizer* bSizer70; - bSizer70 = new wxBoxSizer( wxHORIZONTAL ); + bSizer87->Add( m_panel8, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - m_staticText44 = new wxStaticText( this, wxID_ANY, _("Create a batch file for automated synchronization. To start in batch mode simply double-click the file or execute via command line: FreeFileSync.exe <ffs_batch file>. This can also be scheduled in your operating system's task planner."), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText44->Wrap( 460 ); - bSizer70->Add( m_staticText44, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + m_staticText44 = new wxStaticText( this, wxID_ANY, _("Create a batch file and automate synchronization. To start in batch mode simply double-click this file or run command: FreeFileSync.exe SyncJob.ffs_batch. This can also be scheduled in your system's task planner."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText44->Wrap( 480 ); + bSizer87->Add( m_staticText44, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); m_bpButtonHelp = new wxBitmapButton( this, wxID_HELP, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); m_bpButtonHelp->SetToolTip( _("Help") ); - bSizer70->Add( m_bpButtonHelp, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + bSizer87->Add( m_bpButtonHelp, 0, wxALIGN_CENTER_VERTICAL, 5 ); - bSizer87->Add( bSizer70, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); - bSizer54->Add( bSizer87, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 5 ); + bSizer54->Add( bSizer87, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP|wxRIGHT|wxLEFT, 5 ); - m_listbook1 = new wxListbook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLB_DEFAULT ); - m_panelOverview = new wxPanel( m_listbook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_notebook1 = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + m_panelOverview = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bSizer67; bSizer67 = new wxBoxSizer( wxHORIZONTAL ); @@ -1080,8 +1107,10 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS sbSizer241->Add( m_staticTextCmpVariant, 1, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer1701->Add( sbSizer241, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer175->Add( bSizer1701, 1, wxALIGN_CENTER_VERTICAL, 5 ); wxStaticBoxSizer* sbSizer26; @@ -1090,6 +1119,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS m_bpButtonFilter = new wxBitmapButton( m_panelOverview, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW|wxFULL_REPAINT_ON_RESIZE ); sbSizer26->Add( m_bpButtonFilter, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 15 ); + bSizer175->Add( sbSizer26, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); wxBoxSizer* bSizer171; @@ -1113,10 +1143,13 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS sbSizer252->Add( m_bpButtonSyncConfig, 0, wxALIGN_CENTER_VERTICAL, 3 ); + bSizer171->Add( sbSizer252, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 ); + bSizer175->Add( bSizer171, 1, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer120->Add( bSizer175, 0, wxEXPAND, 5 ); @@ -1146,6 +1179,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer1361->Add( m_bpButtonRemovePair, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer147->Add( bSizer1361, 0, wxALIGN_CENTER_VERTICAL, 5 ); wxBoxSizer* bSizer143; @@ -1160,6 +1194,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer145->Add( m_staticText532, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer143->Add( bSizer145, 1, 0, 5 ); wxBoxSizer* bSizer146; @@ -1171,10 +1206,13 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer146->Add( m_staticText5411, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer143->Add( bSizer146, 1, 0, 5 ); + bSizer147->Add( bSizer143, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT|wxEXPAND, 5 ); + m_panelMainPair->SetSizer( bSizer147 ); m_panelMainPair->Layout(); bSizer147->Fit( m_panelMainPair ); @@ -1195,6 +1233,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer1141->Add( m_dirPickerLeft, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_panelLeft->SetSizer( bSizer1141 ); m_panelLeft->Layout(); bSizer1141->Fit( m_panelLeft ); @@ -1212,11 +1251,13 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer115->Add( m_dirPickerRight, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_panelRight->SetSizer( bSizer115 ); m_panelRight->Layout(); bSizer115->Fit( m_panelRight ); bSizer158->Add( m_panelRight, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + sbSizerMainPair->Add( bSizer158, 1, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 ); wxBoxSizer* bSizer177; @@ -1231,14 +1272,18 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS m_bpButtonAltSyncCfg = new wxBitmapButton( m_scrolledWindow6, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); bSizer177->Add( m_bpButtonAltSyncCfg, 0, wxALIGN_CENTER_VERTICAL, 5 ); + sbSizerMainPair->Add( bSizer177, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + bSizer141->Add( sbSizerMainPair, 0, wxEXPAND, 5 ); bSizerAddFolderPairs = new wxBoxSizer( wxVERTICAL ); + bSizer141->Add( bSizerAddFolderPairs, 1, wxEXPAND, 5 ); + m_scrolledWindow6->SetSizer( bSizer141 ); m_scrolledWindow6->Layout(); bSizer141->Fit( m_scrolledWindow6 ); @@ -1247,13 +1292,15 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer120->Add( 0, 5, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer67->Add( bSizer120, 1, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 10 ); + m_panelOverview->SetSizer( bSizer67 ); m_panelOverview->Layout(); bSizer67->Fit( m_panelOverview ); - m_listbook1->AddPage( m_panelOverview, _("Overview"), true ); - m_panelBatchSettings = new wxPanel( m_listbook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_notebook1->AddPage( m_panelOverview, _("Synchronization settings"), true ); + m_panelBatchSettings = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bSizer117; bSizer117 = new wxBoxSizer( wxVERTICAL ); @@ -1269,6 +1316,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS m_checkBoxShowProgress = new wxCheckBox( m_panelBatchSettings, wxID_ANY, _("Show progress dialog"), wxDefaultPosition, wxDefaultSize, 0 ); sbSizer24->Add( m_checkBoxShowProgress, 0, wxALL|wxEXPAND, 5 ); + bSizer1722->Add( sbSizer24, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); @@ -1282,8 +1330,10 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS m_choiceHandleError->SetSelection( 0 ); sbSizer25->Add( m_choiceHandleError, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer1722->Add( sbSizer25, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + bSizer172->Add( bSizer1722, 0, wxEXPAND, 5 ); @@ -1304,6 +1354,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS m_spinCtrlLogCountMax = new wxSpinCtrl( m_panelBatchSettings, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 2000000000, 0 ); bSizer152->Add( m_spinCtrlLogCountMax, 0, wxALIGN_CENTER_VERTICAL, 5 ); + sbSizerLogfileDir->Add( bSizer152, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); m_panelLogfile = new wxPanel( m_panelBatchSettings, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); @@ -1325,29 +1376,28 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer170->Add( m_dirPickerLogfileDir, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer1721->Add( bSizer170, 0, wxEXPAND, 5 ); + m_panelLogfile->SetSizer( bSizer1721 ); m_panelLogfile->Layout(); bSizer1721->Fit( m_panelLogfile ); sbSizerLogfileDir->Add( m_panelLogfile, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + bSizer172->Add( sbSizerLogfileDir, 0, wxEXPAND, 5 ); + bSizer117->Add( bSizer172, 1, wxEXPAND|wxALL, 10 ); + m_panelBatchSettings->SetSizer( bSizer117 ); m_panelBatchSettings->Layout(); bSizer117->Fit( m_panelBatchSettings ); - m_listbook1->AddPage( m_panelBatchSettings, _("Batch settings"), false ); -#ifndef __WXGTK__ // Small icon style not supported in GTK - wxListView* m_listbook1ListView = m_listbook1->GetListView(); - long m_listbook1Flags = m_listbook1ListView->GetWindowStyleFlag(); - m_listbook1Flags = ( m_listbook1Flags & ~wxLC_ICON ) | wxLC_SMALL_ICON; - m_listbook1ListView->SetWindowStyleFlag( m_listbook1Flags ); -#endif + m_notebook1->AddPage( m_panelBatchSettings, _("Batch settings"), false ); - bSizer54->Add( m_listbook1, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + bSizer54->Add( m_notebook1, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); wxBoxSizer* bSizer68; bSizer68 = new wxBoxSizer( wxHORIZONTAL ); @@ -1368,7 +1418,9 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer68->Add( m_button6, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - bSizer54->Add( bSizer68, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 5 ); + + bSizer54->Add( bSizer68, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + this->SetSizer( bSizer54 ); this->Layout(); @@ -1429,6 +1481,7 @@ BatchFolderPairGenerated::BatchFolderPairGenerated( wxWindow* parent, wxWindowID bSizer136->Add( m_bpButtonRemovePair, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer147->Add( bSizer136, 0, wxALIGN_CENTER_VERTICAL, 5 ); wxBoxSizer* bSizer143; @@ -1443,6 +1496,7 @@ BatchFolderPairGenerated::BatchFolderPairGenerated( wxWindow* parent, wxWindowID bSizer145->Add( m_staticText53, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer143->Add( bSizer145, 1, 0, 5 ); wxBoxSizer* bSizer146; @@ -1454,10 +1508,13 @@ BatchFolderPairGenerated::BatchFolderPairGenerated( wxWindow* parent, wxWindowID bSizer146->Add( m_staticText541, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer143->Add( bSizer146, 1, 0, 5 ); + bSizer147->Add( bSizer143, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxRIGHT|wxLEFT, 5 ); + m_panel32->SetSizer( bSizer147 ); m_panel32->Layout(); bSizer147->Fit( m_panel32 ); @@ -1478,6 +1535,7 @@ BatchFolderPairGenerated::BatchFolderPairGenerated( wxWindow* parent, wxWindowID bSizer114->Add( m_dirPickerLeft, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_panelLeft->SetSizer( bSizer114 ); m_panelLeft->Layout(); bSizer114->Fit( m_panelLeft ); @@ -1495,11 +1553,13 @@ BatchFolderPairGenerated::BatchFolderPairGenerated( wxWindow* parent, wxWindowID bSizer115->Add( m_dirPickerRight, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_panelRight->SetSizer( bSizer115 ); m_panelRight->Layout(); bSizer115->Fit( m_panelRight ); bSizer144->Add( m_panelRight, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer140->Add( bSizer144, 1, wxALIGN_CENTER_VERTICAL, 5 ); wxBoxSizer* bSizer176; @@ -1514,13 +1574,16 @@ BatchFolderPairGenerated::BatchFolderPairGenerated( wxWindow* parent, wxWindowID m_bpButtonAltSyncCfg = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); bSizer176->Add( m_bpButtonAltSyncCfg, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer140->Add( bSizer176, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + bSizer142->Add( bSizer140, 0, wxEXPAND, 5 ); bSizer142->Add( 0, 5, 0, 0, 5 ); + this->SetSizer( bSizer142 ); this->Layout(); bSizer142->Fit( this ); @@ -1608,8 +1671,10 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const m_staticText9->Wrap( 410 ); fgSizer1->Add( m_staticText9, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + sbSizer7->Add( fgSizer1, 0, 0, 5 ); + bSizer29->Add( sbSizer7, 0, wxEXPAND, 5 ); @@ -1632,11 +1697,13 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const m_dirPickerCustomDelFolder = new zen::DirPickerCtrl( m_panelCustomDeletionDir, wxID_ANY, wxEmptyString, _("Select a folder"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer1151->Add( m_dirPickerCustomDelFolder, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_panelCustomDeletionDir->SetSizer( bSizer1151 ); m_panelCustomDeletionDir->Layout(); bSizer1151->Fit( m_panelCustomDeletionDir ); sbSizerCustDelDir->Add( m_panelCustomDeletionDir, 1, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer29->Add( sbSizerCustDelDir, 0, wxEXPAND, 5 ); bSizer201 = new wxBoxSizer( wxHORIZONTAL ); @@ -1648,6 +1715,7 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const m_choiceHandleError->SetSelection( 0 ); sbSizerErrorHandling->Add( m_choiceHandleError, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer201->Add( sbSizerErrorHandling, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 10 ); sbSizerExecFinished = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("On completion:") ), wxHORIZONTAL ); @@ -1655,10 +1723,13 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const m_comboBoxExecFinished = new ExecFinishedBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); sbSizerExecFinished->Add( m_comboBoxExecFinished, 1, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer201->Add( sbSizerExecFinished, 1, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer29->Add( bSizer201, 0, wxEXPAND|wxTOP, 5 ); + bSizer181->Add( bSizer29, 0, wxEXPAND, 5 ); @@ -1690,6 +1761,7 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const gSizer3->Add( m_staticText31, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + sbSizerSyncDirections->Add( gSizer3, 0, wxBOTTOM|wxEXPAND, 5 ); wxBoxSizer* bSizer121; @@ -1708,6 +1780,7 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const m_bpButtonLeftOnly = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); bSizerLeftOnly->Add( m_bpButtonLeftOnly, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer121->Add( bSizerLeftOnly, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); bSizerRightOnly = new wxBoxSizer( wxHORIZONTAL ); @@ -1723,6 +1796,7 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const m_bpButtonRightOnly = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); bSizerRightOnly->Add( m_bpButtonRightOnly, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer121->Add( bSizerRightOnly, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); bSizerLeftNewer = new wxBoxSizer( wxHORIZONTAL ); @@ -1738,6 +1812,7 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const m_bpButtonLeftNewer = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); bSizerLeftNewer->Add( m_bpButtonLeftNewer, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer121->Add( bSizerLeftNewer, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); bSizerRightNewer = new wxBoxSizer( wxHORIZONTAL ); @@ -1753,6 +1828,7 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const m_bpButtonRightNewer = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); bSizerRightNewer->Add( m_bpButtonRightNewer, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer121->Add( bSizerRightNewer, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); bSizerDifferent = new wxBoxSizer( wxHORIZONTAL ); @@ -1768,6 +1844,7 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const m_bpButtonDifferent = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); bSizerDifferent->Add( m_bpButtonDifferent, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer121->Add( bSizerDifferent, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); bSizerConflict = new wxBoxSizer( wxHORIZONTAL ); @@ -1783,17 +1860,22 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const m_bpButtonConflict = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); bSizerConflict->Add( m_bpButtonConflict, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer121->Add( bSizerConflict, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + sbSizerSyncDirections->Add( bSizer121, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + sbSizer2453245->Add( sbSizerSyncDirections, 0, wxEXPAND, 5 ); sbSizer2453245->Add( 0, 0, 1, wxEXPAND, 5 ); + bSizer181->Add( sbSizer2453245, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer7->Add( bSizer181, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); wxBoxSizer* bSizer291; @@ -1810,8 +1892,10 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const bSizer291->Add( m_button16, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer7->Add( bSizer291, 0, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM, 5 ); + this->SetSizer( bSizer7 ); this->Layout(); bSizer7->Fit( this ); @@ -1924,8 +2008,10 @@ CmpCfgDlgGenerated::CmpCfgDlgGenerated( wxWindow* parent, wxWindowID id, const w fgSizer16->Add( m_buttonContent, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + sbSizer6->Add( fgSizer16, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + bSizer55->Add( sbSizer6, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 2 ); @@ -1942,6 +2028,7 @@ CmpCfgDlgGenerated::CmpCfgDlgGenerated( wxWindow* parent, wxWindowID id, const w m_choiceHandleSymlinks->SetSelection( -1 ); sbSizer25->Add( m_choiceHandleSymlinks, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer177->Add( sbSizer25, 1, wxALIGN_CENTER_VERTICAL, 5 ); m_bpButtonHelp = new wxBitmapButton( this, wxID_HELP, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); @@ -1949,6 +2036,7 @@ CmpCfgDlgGenerated::CmpCfgDlgGenerated( wxWindow* parent, wxWindowID id, const w bSizer177->Add( m_bpButtonHelp, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + bSizer55->Add( bSizer177, 0, wxEXPAND, 5 ); wxBoxSizer* bSizer22; @@ -1965,10 +2053,13 @@ CmpCfgDlgGenerated::CmpCfgDlgGenerated( wxWindow* parent, wxWindowID id, const w bSizer22->Add( m_button6, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer55->Add( bSizer22, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer136->Add( bSizer55, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + this->SetSizer( bSizer136 ); this->Layout(); bSizer136->Fit( this ); @@ -2006,7 +2097,7 @@ CmpCfgDlgGenerated::~CmpCfgDlgGenerated() SyncStatusDlgGenerated::SyncStatusDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style ) { - this->SetSizeHints( wxSize( 470,200 ), wxDefaultSize ); + this->SetSizeHints( wxSize( 470,260 ), wxDefaultSize ); wxBoxSizer* bSizer172; bSizer172 = new wxBoxSizer( wxVERTICAL ); @@ -2018,37 +2109,42 @@ SyncStatusDlgGenerated::SyncStatusDlgGenerated( wxWindow* parent, wxWindowID id, bSizer42 = new wxBoxSizer( wxHORIZONTAL ); m_bitmapStatus = new wxStaticBitmap( m_panelBackground, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 28,28 ), 0 ); - bSizer42->Add( m_bitmapStatus, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 5 ); + bSizer42->Add( m_bitmapStatus, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); m_staticTextStatus = new wxStaticText( m_panelBackground, wxID_ANY, _("Synchronizing..."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextStatus->Wrap( -1 ); m_staticTextStatus->SetFont( wxFont( 14, 70, 90, 92, false, wxEmptyString ) ); - bSizer42->Add( m_staticTextStatus, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + bSizer42->Add( m_staticTextStatus, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 5 ); m_animationControl1 = new wxAnimationCtrl( m_panelBackground, wxID_ANY, wxNullAnimation, wxDefaultPosition, wxDefaultSize, wxAC_DEFAULT_STYLE ); m_animationControl1->SetMinSize( wxSize( 45,45 ) ); bSizer42->Add( m_animationControl1, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - bSizerTop->Add( bSizer42, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + + bSizerTop->Add( bSizer42, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 5 ); bSizerCurrentOperation = new wxBoxSizer( wxHORIZONTAL ); m_staticText2511 = new wxStaticText( m_panelBackground, wxID_ANY, _("Operation:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText2511->Wrap( -1 ); - m_staticText2511->SetFont( wxFont( 10, 74, 90, 92, false, wxT("Tahoma") ) ); + m_staticText2511->SetFont( wxFont( 10, 70, 90, 92, false, wxEmptyString ) ); bSizerCurrentOperation->Add( m_staticText2511, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 ); m_textCtrlInfo = new wxTextCtrl( m_panelBackground, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY ); - m_textCtrlInfo->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_textCtrlInfo->SetBackgroundColour( wxColour( 224, 224, 224 ) ); bSizerCurrentOperation->Add( m_textCtrlInfo, 1, wxALIGN_CENTER_VERTICAL, 5 ); - bSizerTop->Add( bSizerCurrentOperation, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT|wxEXPAND, 5 ); + + bSizerTop->Add( bSizerCurrentOperation, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); m_panelProgress = new wxPanel( m_panelBackground, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer173; + bSizer173 = new wxBoxSizer( wxVERTICAL ); + bSizer171 = new wxBoxSizer( wxHORIZONTAL ); bSizerProgressStat = new wxStaticBoxSizer( new wxStaticBox( m_panelProgress, wxID_ANY, wxEmptyString ), wxHORIZONTAL ); @@ -2058,112 +2154,116 @@ SyncStatusDlgGenerated::SyncStatusDlgGenerated( wxWindow* parent, wxWindowID id, fgSizer10->SetFlexibleDirection( wxBOTH ); fgSizer10->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - m_staticTextItemsRem = new wxStaticText( m_panelProgress, wxID_ANY, _("Items remaining:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextItemsRem->Wrap( -1 ); - m_staticTextItemsRem->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); - - fgSizer10->Add( m_staticTextItemsRem, 0, wxALIGN_BOTTOM, 5 ); - - bSizerItemsRem = new wxBoxSizer( wxHORIZONTAL ); - - m_staticTextRemainingObj = new wxStaticText( m_panelProgress, wxID_ANY, _("dummy"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_staticTextRemainingObj->Wrap( -1 ); - m_staticTextRemainingObj->SetFont( wxFont( 9, 74, 90, 92, false, wxT("Arial") ) ); - - bSizerItemsRem->Add( m_staticTextRemainingObj, 0, wxALIGN_BOTTOM, 5 ); - - m_staticText96 = new wxStaticText( m_panelProgress, wxID_ANY, _("("), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText96->Wrap( -1 ); - m_staticText96->SetFont( wxFont( 9, 74, 90, 90, false, wxT("Arial") ) ); - - bSizerItemsRem->Add( m_staticText96, 0, wxLEFT|wxALIGN_BOTTOM, 5 ); - - m_staticTextDataRemaining = new wxStaticText( m_panelProgress, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextDataRemaining->Wrap( -1 ); - m_staticTextDataRemaining->SetFont( wxFont( 9, 74, 90, 90, false, wxT("Arial") ) ); - - bSizerItemsRem->Add( m_staticTextDataRemaining, 0, wxALIGN_BOTTOM, 5 ); - - m_staticText97 = new wxStaticText( m_panelProgress, wxID_ANY, _(")"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText97->Wrap( -1 ); - m_staticText97->SetFont( wxFont( 9, 74, 90, 90, false, wxT("Arial") ) ); - - bSizerItemsRem->Add( m_staticText97, 0, wxALIGN_BOTTOM, 5 ); - - fgSizer10->Add( bSizerItemsRem, 0, wxALIGN_BOTTOM, 5 ); - - m_staticTextItemsProc = new wxStaticText( m_panelProgress, wxID_ANY, _("Items processed:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextItemsProc->Wrap( -1 ); - m_staticTextItemsProc->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); + m_staticTextLabelItemsProc = new wxStaticText( m_panelProgress, wxID_ANY, _("Items processed:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextLabelItemsProc->Wrap( -1 ); + m_staticTextLabelItemsProc->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); - fgSizer10->Add( m_staticTextItemsProc, 0, wxALIGN_BOTTOM, 5 ); + fgSizer10->Add( m_staticTextLabelItemsProc, 0, wxALIGN_BOTTOM, 5 ); bSizerItemsProc = new wxBoxSizer( wxHORIZONTAL ); m_staticTextProcessedObj = new wxStaticText( m_panelProgress, wxID_ANY, _("dummy"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); m_staticTextProcessedObj->Wrap( -1 ); - m_staticTextProcessedObj->SetFont( wxFont( 9, 74, 90, 92, false, wxT("Arial") ) ); + m_staticTextProcessedObj->SetFont( wxFont( 9, 70, 90, 92, false, wxEmptyString ) ); bSizerItemsProc->Add( m_staticTextProcessedObj, 0, wxALIGN_BOTTOM, 5 ); m_staticText98 = new wxStaticText( m_panelProgress, wxID_ANY, _("("), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText98->Wrap( -1 ); - m_staticText98->SetFont( wxFont( 9, 74, 90, 90, false, wxT("Arial") ) ); + m_staticText98->SetFont( wxFont( 9, 70, 90, 90, false, wxEmptyString ) ); bSizerItemsProc->Add( m_staticText98, 0, wxLEFT|wxALIGN_BOTTOM, 5 ); m_staticTextDataProcessed = new wxStaticText( m_panelProgress, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextDataProcessed->Wrap( -1 ); - m_staticTextDataProcessed->SetFont( wxFont( 9, 74, 90, 90, false, wxT("Arial") ) ); + m_staticTextDataProcessed->SetFont( wxFont( 9, 70, 90, 90, false, wxEmptyString ) ); bSizerItemsProc->Add( m_staticTextDataProcessed, 0, wxALIGN_BOTTOM, 5 ); m_staticText99 = new wxStaticText( m_panelProgress, wxID_ANY, _(")"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText99->Wrap( -1 ); - m_staticText99->SetFont( wxFont( 9, 74, 90, 90, false, wxT("Arial") ) ); + m_staticText99->SetFont( wxFont( 9, 70, 90, 90, false, wxEmptyString ) ); bSizerItemsProc->Add( m_staticText99, 0, wxALIGN_BOTTOM, 5 ); + fgSizer10->Add( bSizerItemsProc, 0, wxALIGN_BOTTOM, 5 ); - m_staticTextSpeedDescr = new wxStaticText( m_panelProgress, wxID_ANY, _("Speed:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextSpeedDescr->Wrap( -1 ); - m_staticTextSpeedDescr->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); + m_staticTextLabelItemsRem = new wxStaticText( m_panelProgress, wxID_ANY, _("Items remaining:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextLabelItemsRem->Wrap( -1 ); + m_staticTextLabelItemsRem->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); - fgSizer10->Add( m_staticTextSpeedDescr, 0, wxALIGN_BOTTOM, 5 ); + fgSizer10->Add( m_staticTextLabelItemsRem, 0, wxALIGN_BOTTOM, 5 ); - m_staticTextSpeed = new wxStaticText( m_panelProgress, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextSpeed->Wrap( -1 ); - m_staticTextSpeed->SetFont( wxFont( 9, 74, 90, 92, false, wxT("Arial") ) ); + bSizerItemsRem = new wxBoxSizer( wxHORIZONTAL ); + + m_staticTextRemainingObj = new wxStaticText( m_panelProgress, wxID_ANY, _("dummy"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_staticTextRemainingObj->Wrap( -1 ); + m_staticTextRemainingObj->SetFont( wxFont( 9, 70, 90, 92, false, wxEmptyString ) ); + + bSizerItemsRem->Add( m_staticTextRemainingObj, 0, wxALIGN_BOTTOM, 5 ); + + m_staticText96 = new wxStaticText( m_panelProgress, wxID_ANY, _("("), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText96->Wrap( -1 ); + m_staticText96->SetFont( wxFont( 9, 70, 90, 90, false, wxEmptyString ) ); + + bSizerItemsRem->Add( m_staticText96, 0, wxLEFT|wxALIGN_BOTTOM, 5 ); + + m_staticTextDataRemaining = new wxStaticText( m_panelProgress, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextDataRemaining->Wrap( -1 ); + m_staticTextDataRemaining->SetFont( wxFont( 9, 70, 90, 90, false, wxEmptyString ) ); + + bSizerItemsRem->Add( m_staticTextDataRemaining, 0, wxALIGN_BOTTOM, 5 ); + + m_staticText97 = new wxStaticText( m_panelProgress, wxID_ANY, _(")"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText97->Wrap( -1 ); + m_staticText97->SetFont( wxFont( 9, 70, 90, 90, false, wxEmptyString ) ); + + bSizerItemsRem->Add( m_staticText97, 0, wxALIGN_BOTTOM, 5 ); - fgSizer10->Add( m_staticTextSpeed, 0, wxALIGN_BOTTOM, 5 ); - m_staticText55 = new wxStaticText( m_panelProgress, wxID_ANY, _("Time elapsed:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText55->Wrap( -1 ); - m_staticText55->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); + fgSizer10->Add( bSizerItemsRem, 0, wxALIGN_BOTTOM, 5 ); + + m_staticTextLabelElapsedTime = new wxStaticText( m_panelProgress, wxID_ANY, _("Elapsed time:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextLabelElapsedTime->Wrap( -1 ); + m_staticTextLabelElapsedTime->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); - fgSizer10->Add( m_staticText55, 0, wxALIGN_BOTTOM, 5 ); + fgSizer10->Add( m_staticTextLabelElapsedTime, 0, wxALIGN_BOTTOM, 5 ); m_staticTextTimeElapsed = new wxStaticText( m_panelProgress, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextTimeElapsed->Wrap( -1 ); - m_staticTextTimeElapsed->SetFont( wxFont( 9, 74, 90, 92, false, wxT("Arial") ) ); + m_staticTextTimeElapsed->SetFont( wxFont( 9, 70, 90, 92, false, wxEmptyString ) ); fgSizer10->Add( m_staticTextTimeElapsed, 0, wxALIGN_BOTTOM, 5 ); - m_staticTextRemTimeDescr = new wxStaticText( m_panelProgress, wxID_ANY, _("Time remaining:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextRemTimeDescr->Wrap( -1 ); - m_staticTextRemTimeDescr->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); + m_staticTextLabelRemTime = new wxStaticText( m_panelProgress, wxID_ANY, _("Remaining time:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextLabelRemTime->Wrap( -1 ); + m_staticTextLabelRemTime->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); - fgSizer10->Add( m_staticTextRemTimeDescr, 0, wxALIGN_BOTTOM, 5 ); + fgSizer10->Add( m_staticTextLabelRemTime, 0, wxALIGN_BOTTOM, 5 ); m_staticTextRemTime = new wxStaticText( m_panelProgress, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextRemTime->Wrap( -1 ); - m_staticTextRemTime->SetFont( wxFont( 9, 74, 90, 92, false, wxT("Arial") ) ); + m_staticTextRemTime->SetFont( wxFont( 9, 70, 90, 92, false, wxEmptyString ) ); fgSizer10->Add( m_staticTextRemTime, 0, wxALIGN_BOTTOM, 5 ); + m_staticText84 = new wxStaticText( m_panelProgress, wxID_ANY, _("Speed:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText84->Wrap( -1 ); + m_staticText84->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); + + fgSizer10->Add( m_staticText84, 0, wxALIGN_BOTTOM, 5 ); + + m_staticTextSpeed = new wxStaticText( m_panelProgress, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextSpeed->Wrap( -1 ); + m_staticTextSpeed->SetFont( wxFont( 9, 70, 90, 92, false, wxEmptyString ) ); + + fgSizer10->Add( m_staticTextSpeed, 0, wxALIGN_BOTTOM, 5 ); + + bSizerProgressStat->Add( fgSizer10, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + bSizer171->Add( bSizerProgressStat, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -2174,9 +2274,16 @@ SyncStatusDlgGenerated::SyncStatusDlgGenerated( wxWindow* parent, wxWindowID id, bSizer171->Add( m_panelGraph, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - m_panelProgress->SetSizer( bSizer171 ); + + bSizer173->Add( bSizer171, 1, wxEXPAND, 5 ); + + m_gauge1 = new wxGauge( m_panelProgress, wxID_ANY, 100, wxDefaultPosition, wxSize( -1,14 ), wxGA_HORIZONTAL ); + bSizer173->Add( m_gauge1, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + + + m_panelProgress->SetSizer( bSizer173 ); m_panelProgress->Layout(); - bSizer171->Fit( m_panelProgress ); + bSizer173->Fit( m_panelProgress ); bSizerTop->Add( m_panelProgress, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); bSizerFinalStat = new wxBoxSizer( wxVERTICAL ); @@ -2191,22 +2298,21 @@ SyncStatusDlgGenerated::SyncStatusDlgGenerated( wxWindow* parent, wxWindowID id, bSizerFinalStat->Add( m_listbookResult, 1, wxEXPAND, 5 ); - bSizerTop->Add( bSizerFinalStat, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 ); - m_gauge1 = new wxGauge( m_panelBackground, wxID_ANY, 100, wxDefaultPosition, wxSize( -1,14 ), wxGA_HORIZONTAL ); - bSizerTop->Add( m_gauge1, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + bSizerTop->Add( bSizerFinalStat, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); bSizerExecFinished = new wxBoxSizer( wxHORIZONTAL ); m_staticText87 = new wxStaticText( m_panelBackground, wxID_ANY, _("On completion:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText87->Wrap( -1 ); - m_staticText87->SetFont( wxFont( 8, 74, 90, 90, false, wxT("MS Shell Dlg 2") ) ); + m_staticText87->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); bSizerExecFinished->Add( m_staticText87, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); m_comboBoxExecFinished = new ExecFinishedBox( m_panelBackground, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); bSizerExecFinished->Add( m_comboBoxExecFinished, 1, wxALIGN_CENTER_VERTICAL, 5 ); + bSizerTop->Add( bSizerExecFinished, 0, wxTOP|wxRIGHT|wxLEFT|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); bSizer28 = new wxBoxSizer( wxHORIZONTAL ); @@ -2233,13 +2339,16 @@ SyncStatusDlgGenerated::SyncStatusDlgGenerated( wxWindow* parent, wxWindowID id, bSizer28->Add( 0, 0, 1, wxEXPAND, 5 ); + bSizerTop->Add( bSizer28, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + m_panelBackground->SetSizer( bSizerTop ); m_panelBackground->Layout(); bSizerTop->Fit( m_panelBackground ); bSizer172->Add( m_panelBackground, 1, wxEXPAND, 5 ); + this->SetSizer( bSizer172 ); this->Layout(); @@ -2281,13 +2390,15 @@ LogControlGenerated::LogControlGenerated( wxWindow* parent, wxWindowID id, const m_bpButtonInfo = new ToggleButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 48,48 ), wxBU_AUTODRAW ); bSizer154->Add( m_bpButtonInfo, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer153->Add( bSizer154, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); m_textCtrlInfo = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_DONTWRAP|wxTE_MULTILINE|wxTE_READONLY ); - m_textCtrlInfo->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_textCtrlInfo->SetBackgroundColour( wxColour( 224, 224, 224 ) ); bSizer153->Add( m_textCtrlInfo, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + this->SetSizer( bSizer153 ); this->Layout(); bSizer153->Fit( this ); @@ -2326,6 +2437,7 @@ AboutDlgGenerated::AboutDlgGenerated( wxWindow* parent, wxWindowID id, const wxS m_bitmap11 = new wxStaticBitmap( m_panel5, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 404,55 ), 0 ); bSizer36->Add( m_bitmap11, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_panel5->SetSizer( bSizer36 ); m_panel5->Layout(); bSizer36->Fit( m_panel5 ); @@ -2342,7 +2454,7 @@ AboutDlgGenerated::AboutDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer53 = new wxBoxSizer( wxVERTICAL ); m_panel33 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDOUBLE_BORDER|wxTAB_TRAVERSAL ); - m_panel33->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_panel33->SetBackgroundColour( wxColour( 224, 224, 224 ) ); bSizerCodeInfo = new wxBoxSizer( wxVERTICAL ); @@ -2359,76 +2471,80 @@ AboutDlgGenerated::AboutDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer171 = new wxBoxSizer( wxHORIZONTAL ); m_hyperlink9 = new wxHyperlinkCtrl( m_panel33, wxID_ANY, _("MinGW"), wxT("http://www.mingw.org"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink9->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_hyperlink9->SetBackgroundColour( wxColour( 224, 224, 224 ) ); bSizer171->Add( m_hyperlink9, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); m_hyperlink11 = new wxHyperlinkCtrl( m_panel33, wxID_ANY, _("MS Visual C++"), wxT("http://msdn.microsoft.com/library/60k1461a.aspx"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink11->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_hyperlink11->SetBackgroundColour( wxColour( 224, 224, 224 ) ); bSizer171->Add( m_hyperlink11, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); m_hyperlink10 = new wxHyperlinkCtrl( m_panel33, wxID_ANY, _("Code::Blocks"), wxT("http://www.codeblocks.org"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink10->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_hyperlink10->SetBackgroundColour( wxColour( 224, 224, 224 ) ); bSizer171->Add( m_hyperlink10, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); m_hyperlink13 = new wxHyperlinkCtrl( m_panel33, wxID_ANY, _("Boost"), wxT("http://www.boost.org"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink13->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_hyperlink13->SetBackgroundColour( wxColour( 224, 224, 224 ) ); bSizer171->Add( m_hyperlink13, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); m_hyperlink7 = new wxHyperlinkCtrl( m_panel33, wxID_ANY, _("wxWidgets"), wxT("http://www.wxwidgets.org"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink7->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_hyperlink7->SetBackgroundColour( wxColour( 224, 224, 224 ) ); bSizer171->Add( m_hyperlink7, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); m_hyperlink16 = new wxHyperlinkCtrl( m_panel33, wxID_ANY, _("Artistic Style"), wxT("http://astyle.sourceforge.net"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink16->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_hyperlink16->SetBackgroundColour( wxColour( 224, 224, 224 ) ); bSizer171->Add( m_hyperlink16, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + bSizer167->Add( bSizer171, 0, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM, 5 ); wxBoxSizer* bSizer172; bSizer172 = new wxBoxSizer( wxHORIZONTAL ); m_hyperlink8 = new wxHyperlinkCtrl( m_panel33, wxID_ANY, _("Loki"), wxT("http://loki-lib.sourceforge.net/"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink8->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_hyperlink8->SetBackgroundColour( wxColour( 224, 224, 224 ) ); bSizer172->Add( m_hyperlink8, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); m_hyperlink15 = new wxHyperlinkCtrl( m_panel33, wxID_ANY, _("zenXML"), wxT("http://zenxml.sourceforge.net/"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink15->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_hyperlink15->SetBackgroundColour( wxColour( 224, 224, 224 ) ); bSizer172->Add( m_hyperlink15, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); m_hyperlink12 = new wxHyperlinkCtrl( m_panel33, wxID_ANY, _("Google Test"), wxT("http://code.google.com/p/googletest"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink12->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_hyperlink12->SetBackgroundColour( wxColour( 224, 224, 224 ) ); bSizer172->Add( m_hyperlink12, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); m_hyperlink18 = new wxHyperlinkCtrl( m_panel33, wxID_ANY, _("Unicode NSIS"), wxT("http://www.scratchpaper.com"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink18->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_hyperlink18->SetBackgroundColour( wxColour( 224, 224, 224 ) ); bSizer172->Add( m_hyperlink18, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); m_hyperlink14 = new wxHyperlinkCtrl( m_panel33, wxID_ANY, _("wxFormBuilder"), wxT("http://wxformbuilder.org"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink14->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_hyperlink14->SetBackgroundColour( wxColour( 224, 224, 224 ) ); bSizer172->Add( m_hyperlink14, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + bSizer167->Add( bSizer172, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizerCodeInfo->Add( bSizer167, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); m_hyperlink21 = new wxHyperlinkCtrl( m_panel33, wxID_ANY, _("- ZenJu -"), wxT("mailto:zhnmju123@gmx.de"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); m_hyperlink21->SetFont( wxFont( 10, 74, 93, 92, false, wxT("Segoe Print") ) ); - m_hyperlink21->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_hyperlink21->SetBackgroundColour( wxColour( 224, 224, 224 ) ); m_hyperlink21->SetToolTip( _("zhnmju123@gmx.de") ); bSizerCodeInfo->Add( m_hyperlink21, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + m_panel33->SetSizer( bSizerCodeInfo ); m_panel33->Layout(); bSizerCodeInfo->Fit( m_panel33 ); @@ -2457,6 +2573,7 @@ AboutDlgGenerated::AboutDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer170->Add( 0, 0, 1, wxEXPAND, 5 ); + sbSizer29->Add( bSizer170, 1, wxALIGN_CENTER_VERTICAL, 5 ); wxBoxSizer* bSizer1711; @@ -2479,20 +2596,22 @@ AboutDlgGenerated::AboutDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer1711->Add( 0, 0, 1, wxEXPAND, 5 ); + sbSizer29->Add( bSizer1711, 1, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer53->Add( sbSizer29, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxBOTTOM, 5 ); m_scrolledWindowTranslators = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), wxDOUBLE_BORDER|wxHSCROLL|wxVSCROLL ); m_scrolledWindowTranslators->SetScrollRate( 5, 5 ); - m_scrolledWindowTranslators->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_scrolledWindowTranslators->SetBackgroundColour( wxColour( 224, 224, 224 ) ); m_scrolledWindowTranslators->SetMinSize( wxSize( -1,180 ) ); bSizerTranslators = new wxBoxSizer( wxVERTICAL ); m_staticText54 = new wxStaticText( m_scrolledWindowTranslators, wxID_ANY, _("Big thanks for localizing FreeFileSync goes out to:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText54->Wrap( -1 ); - m_staticText54->SetFont( wxFont( 8, 70, 90, 92, false, wxEmptyString ) ); + m_staticText54->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) ); bSizerTranslators->Add( m_staticText54, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP|wxBOTTOM, 5 ); @@ -2503,8 +2622,10 @@ AboutDlgGenerated::AboutDlgGenerated( wxWindow* parent, wxWindowID id, const wxS fgSizerTranslators->SetFlexibleDirection( wxBOTH ); fgSizerTranslators->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + bSizerTranslators->Add( fgSizerTranslators, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + m_scrolledWindowTranslators->SetSizer( bSizerTranslators ); m_scrolledWindowTranslators->Layout(); bSizerTranslators->Fit( m_scrolledWindowTranslators ); @@ -2517,7 +2638,7 @@ AboutDlgGenerated::AboutDlgGenerated( wxWindow* parent, wxWindowID id, const wxS sbSizer28->Add( 0, 0, 1, wxEXPAND, 5 ); m_hyperlink3 = new wxHyperlinkCtrl( this, wxID_ANY, _("Donate with PayPal"), wxT("https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=zhnmju123@gmx.de&lc=US¤cy_code=EUR"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink3->SetFont( wxFont( 10, 74, 90, 92, true, wxT("MS Shell Dlg 2") ) ); + m_hyperlink3->SetFont( wxFont( 10, 70, 90, 92, true, wxEmptyString ) ); m_hyperlink3->SetToolTip( _("https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=zhnmju123@gmx.de&lc=US¤cy_code=EUR") ); sbSizer28->Add( m_hyperlink3, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); @@ -2530,8 +2651,10 @@ AboutDlgGenerated::AboutDlgGenerated( wxWindow* parent, wxWindowID id, const wxS sbSizer28->Add( 0, 0, 1, wxEXPAND, 5 ); + bSizer53->Add( sbSizer28, 0, wxBOTTOM|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + bSizer31->Add( bSizer53, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxRIGHT|wxLEFT, 25 ); wxStaticBoxSizer* sbSizer14; @@ -2549,6 +2672,7 @@ AboutDlgGenerated::AboutDlgGenerated( wxWindow* parent, wxWindowID id, const wxS sbSizer14->Add( 0, 0, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer31->Add( sbSizer14, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxRIGHT|wxLEFT, 5 ); m_buttonOkay = new wxButton( this, wxID_OK, _("&OK"), wxDefaultPosition, wxSize( 100,30 ), 0 ); @@ -2557,6 +2681,7 @@ AboutDlgGenerated::AboutDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer31->Add( m_buttonOkay, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); + this->SetSizer( bSizer31 ); this->Layout(); bSizer31->Fit( this ); @@ -2578,7 +2703,7 @@ AboutDlgGenerated::~AboutDlgGenerated() ErrorDlgGenerated::ErrorDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) { - this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetSizeHints( wxSize( 300,160 ), wxDefaultSize ); wxBoxSizer* bSizer24; bSizer24 = new wxBoxSizer( wxVERTICAL ); @@ -2593,13 +2718,14 @@ ErrorDlgGenerated::ErrorDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer26->Add( m_bitmap10, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); m_textCtrl8 = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), wxTE_MULTILINE|wxTE_READONLY ); - m_textCtrl8->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_textCtrl8->SetBackgroundColour( wxColour( 224, 224, 224 ) ); bSizer26->Add( m_textCtrl8, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxRIGHT|wxLEFT, 5 ); + bSizer24->Add( bSizer26, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); - m_checkBoxIgnoreErrors = new wxCheckBox( this, wxID_ANY, _("Ignore subsequent errors"), wxDefaultPosition, wxDefaultSize, 0 ); + m_checkBoxIgnoreErrors = new wxCheckBox( this, wxID_ANY, _("Ignore further errors"), wxDefaultPosition, wxDefaultSize, 0 ); m_checkBoxIgnoreErrors->SetToolTip( _("Hide further error messages during the current process") ); bSizer24->Add( m_checkBoxIgnoreErrors, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP, 5 ); @@ -2611,23 +2737,22 @@ ErrorDlgGenerated::ErrorDlgGenerated( wxWindow* parent, wxWindowID id, const wxS m_buttonIgnore->SetDefault(); m_buttonIgnore->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); - bSizer25->Add( m_buttonIgnore, 0, wxTOP|wxBOTTOM|wxLEFT, 5 ); + bSizer25->Add( m_buttonIgnore, 0, wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); m_buttonRetry = new wxButton( this, wxID_RETRY, _("&Retry"), wxDefaultPosition, wxSize( -1,30 ), 0 ); m_buttonRetry->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); - bSizer25->Add( m_buttonRetry, 0, wxTOP|wxBOTTOM|wxLEFT, 5 ); + bSizer25->Add( m_buttonRetry, 0, wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); m_buttonAbort = new wxButton( this, wxID_CANCEL, _("&Abort"), wxDefaultPosition, wxSize( -1,30 ), 0 ); m_buttonAbort->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); - bSizer25->Add( m_buttonAbort, 0, wxTOP|wxBOTTOM|wxLEFT, 5 ); - + bSizer25->Add( m_buttonAbort, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); - bSizer25->Add( 5, 0, 0, wxALIGN_CENTER_VERTICAL, 5 ); bSizer24->Add( bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + this->SetSizer( bSizer24 ); this->Layout(); @@ -2650,7 +2775,7 @@ ErrorDlgGenerated::~ErrorDlgGenerated() WarningDlgGenerated::WarningDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) { - this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetSizeHints( wxSize( 300,160 ), wxDefaultSize ); wxBoxSizer* bSizer24; bSizer24 = new wxBoxSizer( wxVERTICAL ); @@ -2665,10 +2790,11 @@ WarningDlgGenerated::WarningDlgGenerated( wxWindow* parent, wxWindowID id, const bSizer26->Add( m_bitmap10, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); m_textCtrl8 = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), wxTE_MULTILINE|wxTE_READONLY ); - m_textCtrl8->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_textCtrl8->SetBackgroundColour( wxColour( 224, 224, 224 ) ); bSizer26->Add( m_textCtrl8, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxRIGHT|wxLEFT, 5 ); + bSizer24->Add( bSizer26, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); m_checkBoxDontShowAgain = new wxCheckBox( this, wxID_ANY, _("Do not show this dialog again"), wxDefaultPosition, wxDefaultSize, 0 ); @@ -2694,10 +2820,9 @@ WarningDlgGenerated::WarningDlgGenerated( wxWindow* parent, wxWindowID id, const bSizer25->Add( m_buttonAbort, 0, wxTOP|wxBOTTOM|wxLEFT, 5 ); - bSizer25->Add( 5, 0, 0, wxALIGN_CENTER_VERTICAL, 5 ); - bSizer24->Add( bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + this->SetSizer( bSizer24 ); this->Layout(); @@ -2720,7 +2845,7 @@ WarningDlgGenerated::~WarningDlgGenerated() QuestionDlgGenerated::QuestionDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) { - this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetSizeHints( wxSize( 300,160 ), wxDefaultSize ); wxBoxSizer* bSizer24; bSizer24 = new wxBoxSizer( wxVERTICAL ); @@ -2735,14 +2860,15 @@ QuestionDlgGenerated::QuestionDlgGenerated( wxWindow* parent, wxWindowID id, con bSizer26->Add( m_bitmap10, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); m_textCtrl8 = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), wxTE_MULTILINE|wxTE_READONLY ); - m_textCtrl8->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_textCtrl8->SetBackgroundColour( wxColour( 224, 224, 224 ) ); bSizer26->Add( m_textCtrl8, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxRIGHT|wxLEFT, 5 ); + bSizer24->Add( bSizer26, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); - m_checkBoxDontAskAgain = new wxCheckBox( this, wxID_ANY, _("Do not show this dialog again"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer24->Add( m_checkBoxDontAskAgain, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP, 5 ); + m_checkBox = new wxCheckBox( this, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer24->Add( m_checkBox, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP, 5 ); wxBoxSizer* bSizer25; bSizer25 = new wxBoxSizer( wxHORIZONTAL ); @@ -2751,29 +2877,27 @@ QuestionDlgGenerated::QuestionDlgGenerated( wxWindow* parent, wxWindowID id, con m_buttonYes->SetDefault(); m_buttonYes->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); - bSizer25->Add( m_buttonYes, 0, wxTOP|wxBOTTOM|wxLEFT, 5 ); + bSizer25->Add( m_buttonYes, 0, wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); m_buttonNo = new wxButton( this, wxID_NO, _("&No"), wxDefaultPosition, wxSize( -1,30 ), 0 ); m_buttonNo->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); - bSizer25->Add( m_buttonNo, 0, wxTOP|wxBOTTOM|wxLEFT, 5 ); + bSizer25->Add( m_buttonNo, 0, wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxSize( -1,30 ), 0 ); m_buttonCancel->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); - bSizer25->Add( m_buttonCancel, 0, wxTOP|wxBOTTOM|wxLEFT, 5 ); + bSizer25->Add( m_buttonCancel, 0, wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); - bSizer25->Add( 5, 0, 0, wxALIGN_CENTER_VERTICAL, 5 ); - bSizer24->Add( bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + this->SetSizer( bSizer24 ); this->Layout(); // Connect Events this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( QuestionDlgGenerated::OnClose ) ); - m_checkBoxDontAskAgain->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( QuestionDlgGenerated::OnCheckBoxDontShowAgain ), NULL, this ); m_buttonYes->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( QuestionDlgGenerated::OnYes ), NULL, this ); m_buttonNo->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( QuestionDlgGenerated::OnNo ), NULL, this ); m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( QuestionDlgGenerated::OnCancel ), NULL, this ); @@ -2783,7 +2907,6 @@ QuestionDlgGenerated::~QuestionDlgGenerated() { // Disconnect Events this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( QuestionDlgGenerated::OnClose ) ); - m_checkBoxDontAskAgain->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( QuestionDlgGenerated::OnCheckBoxDontShowAgain ), NULL, this ); m_buttonYes->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( QuestionDlgGenerated::OnYes ), NULL, this ); m_buttonNo->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( QuestionDlgGenerated::OnNo ), NULL, this ); m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( QuestionDlgGenerated::OnCancel ), NULL, this ); @@ -2792,49 +2915,50 @@ QuestionDlgGenerated::~QuestionDlgGenerated() DeleteDlgGenerated::DeleteDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) { - this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetSizeHints( wxSize( 400,220 ), wxDefaultSize ); wxBoxSizer* bSizer24; bSizer24 = new wxBoxSizer( wxVERTICAL ); - - bSizer24->Add( 0, 10, 0, wxEXPAND, 5 ); - wxBoxSizer* bSizer41; bSizer41 = new wxBoxSizer( wxHORIZONTAL ); m_bitmap12 = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), 0 ); - bSizer41->Add( m_bitmap12, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer41->Add( m_bitmap12, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); m_staticTextHeader = new wxStaticText( this, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextHeader->Wrap( -1 ); m_staticTextHeader->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); - bSizer41->Add( m_staticTextHeader, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + bSizer41->Add( m_staticTextHeader, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); - bSizer24->Add( bSizer41, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + + bSizer24->Add( bSizer41, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP|wxRIGHT|wxLEFT, 5 ); m_textCtrlMessage = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), wxTE_DONTWRAP|wxTE_MULTILINE|wxTE_READONLY ); - m_textCtrlMessage->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_textCtrlMessage->SetBackgroundColour( wxColour( 224, 224, 224 ) ); bSizer24->Add( m_textCtrlMessage, 1, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT|wxEXPAND, 5 ); + wxBoxSizer* bSizer179; + bSizer179 = new wxBoxSizer( wxHORIZONTAL ); + wxBoxSizer* bSizer99; - bSizer99 = new wxBoxSizer( wxHORIZONTAL ); + bSizer99 = new wxBoxSizer( wxVERTICAL ); + + m_checkBoxUseRecycler = new wxCheckBox( this, wxID_ANY, _("Use Recycle Bin"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer99->Add( m_checkBoxUseRecycler, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 ); m_checkBoxDeleteBothSides = new wxCheckBox( this, wxID_ANY, _("Delete on both sides"), wxDefaultPosition, wxDefaultSize, 0 ); m_checkBoxDeleteBothSides->SetToolTip( _("Delete on both sides even if the file is selected on one side only") ); - bSizer99->Add( m_checkBoxDeleteBothSides, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + bSizer99->Add( m_checkBoxDeleteBothSides, 0, wxALIGN_CENTER_VERTICAL, 5 ); - bSizer99->Add( 0, 0, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer179->Add( bSizer99, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - m_checkBoxUseRecycler = new wxCheckBox( this, wxID_ANY, _("Use Recycle Bin"), wxDefaultPosition, wxDefaultSize, 0 ); - m_checkBoxUseRecycler->SetValue(true); - bSizer99->Add( m_checkBoxUseRecycler, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - bSizer24->Add( bSizer99, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxTOP|wxRIGHT|wxLEFT, 5 ); + bSizer179->Add( 0, 0, 1, wxEXPAND, 5 ); wxBoxSizer* bSizer25; bSizer25 = new wxBoxSizer( wxHORIZONTAL ); @@ -2850,15 +2974,20 @@ DeleteDlgGenerated::DeleteDlgGenerated( wxWindow* parent, wxWindowID id, const w bSizer25->Add( m_buttonCancel, 0, wxALL, 5 ); - bSizer24->Add( bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + + bSizer179->Add( bSizer25, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer24->Add( bSizer179, 0, wxEXPAND, 5 ); + this->SetSizer( bSizer24 ); this->Layout(); // Connect Events this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DeleteDlgGenerated::OnClose ) ); - m_checkBoxDeleteBothSides->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DeleteDlgGenerated::OnDelOnBothSides ), NULL, this ); m_checkBoxUseRecycler->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DeleteDlgGenerated::OnUseRecycler ), NULL, this ); + m_checkBoxDeleteBothSides->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DeleteDlgGenerated::OnDelOnBothSides ), NULL, this ); m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DeleteDlgGenerated::OnOK ), NULL, this ); m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DeleteDlgGenerated::OnCancel ), NULL, this ); } @@ -2867,8 +2996,8 @@ DeleteDlgGenerated::~DeleteDlgGenerated() { // Disconnect Events this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DeleteDlgGenerated::OnClose ) ); - m_checkBoxDeleteBothSides->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DeleteDlgGenerated::OnDelOnBothSides ), NULL, this ); m_checkBoxUseRecycler->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DeleteDlgGenerated::OnUseRecycler ), NULL, this ); + m_checkBoxDeleteBothSides->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DeleteDlgGenerated::OnDelOnBothSides ), NULL, this ); m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DeleteDlgGenerated::OnOK ), NULL, this ); m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DeleteDlgGenerated::OnCancel ), NULL, this ); @@ -2876,16 +3005,20 @@ DeleteDlgGenerated::~DeleteDlgGenerated() FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) { - this->SetSizeHints( wxSize( 370,380 ), wxDefaultSize ); + this->SetSizeHints( wxSize( 500,380 ), wxDefaultSize ); wxBoxSizer* bSizer21; bSizer21 = new wxBoxSizer( wxVERTICAL ); - wxBoxSizer* bSizer86; - bSizer86 = new wxBoxSizer( wxHORIZONTAL ); + wxBoxSizer* bSizer70; + bSizer70 = new wxBoxSizer( wxHORIZONTAL ); + + bSizer70->SetMinSize( wxSize( 550,-1 ) ); + + bSizer70->Add( 0, 0, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); m_bitmap26 = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), 0 ); - bSizer86->Add( m_bitmap26, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + bSizer70->Add( m_bitmap26, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); m_panel8 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER|wxTAB_TRAVERSAL ); m_panel8->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT ) ); @@ -2895,50 +3028,37 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w m_staticTexHeader = new wxStaticText( m_panel8, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTexHeader->Wrap( -1 ); - m_staticTexHeader->SetFont( wxFont( 16, 70, 90, 92, false, wxEmptyString ) ); + m_staticTexHeader->SetFont( wxFont( 14, 70, 90, 92, false, wxEmptyString ) ); bSizer72->Add( m_staticTexHeader, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); + m_panel8->SetSizer( bSizer72 ); m_panel8->Layout(); bSizer72->Fit( m_panel8 ); - bSizer86->Add( m_panel8, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - - bSizer86->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL, 5 ); - - bSizer21->Add( bSizer86, 0, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM, 5 ); - - wxBoxSizer* bSizer70; - bSizer70 = new wxBoxSizer( wxHORIZONTAL ); + bSizer70->Add( m_panel8, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - bSizer70->SetMinSize( wxSize( 550,-1 ) ); - - bSizer70->Add( 0, 0, 1, wxEXPAND, 5 ); - - m_staticText44 = new wxStaticText( this, wxID_ANY, _("Only files/directories that match all filter settings will be selected for synchronization.\nNote: The name filter must be specified relative(!) to main synchronization directories."), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_staticText44->Wrap( 550 ); + m_staticText44 = new wxStaticText( this, wxID_ANY, _("Only files that match all filter settings will be synchronized.\nNote: File names must be relative to base directories!"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_staticText44->Wrap( -1 ); bSizer70->Add( m_staticText44, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); - - bSizer70->Add( 0, 0, 1, wxEXPAND, 5 ); - m_bpButtonHelp = new wxBitmapButton( this, wxID_HELP, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); m_bpButtonHelp->SetToolTip( _("Help") ); bSizer70->Add( m_bpButtonHelp, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - bSizer21->Add( bSizer70, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT|wxEXPAND, 10 ); + + bSizer70->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - bSizer21->Add( 0, 5, 0, 0, 5 ); + bSizer21->Add( bSizer70, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP|wxRIGHT|wxLEFT|wxEXPAND, 5 ); m_panel13 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bSizer69; bSizer69 = new wxBoxSizer( wxVERTICAL ); m_staticline10 = new wxStaticLine( m_panel13, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - bSizer69->Add( m_staticline10, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 ); + bSizer69->Add( m_staticline10, 0, wxEXPAND, 5 ); wxBoxSizer* bSizer52; bSizer52 = new wxBoxSizer( wxVERTICAL ); @@ -2961,35 +3081,30 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w m_staticText85->Wrap( -1 ); bSizer52->Add( m_staticText85, 0, 0, 5 ); - bSizer69->Add( bSizer52, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 10 ); - wxStaticBoxSizer* sbSizer21; - sbSizer21 = new wxStaticBoxSizer( new wxStaticBox( m_panel13, wxID_ANY, _("Example") ), wxVERTICAL ); + bSizer69->Add( bSizer52, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP, 5 ); - wxBoxSizer* bSizer66; - bSizer66 = new wxBoxSizer( wxHORIZONTAL ); + wxStaticBoxSizer* sbSizer21; + sbSizer21 = new wxStaticBoxSizer( new wxStaticBox( m_panel13, wxID_ANY, _("Example") ), wxHORIZONTAL ); m_staticText181 = new wxStaticText( m_panel13, wxID_ANY, _("Include: *.doc;*.zip;*.exe\nExclude: \\stuff\\temp\\*"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText181->Wrap( -1 ); - bSizer66->Add( m_staticText181, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 ); + sbSizer21->Add( m_staticText181, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); m_staticText1811 = new wxStaticText( m_panel13, wxID_ANY, _("Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\"."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText1811->Wrap( 250 ); m_staticText1811->SetFont( wxFont( 8, 70, 93, 90, false, wxEmptyString ) ); - bSizer66->Add( m_staticText1811, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + sbSizer21->Add( m_staticText1811, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + - sbSizer21->Add( bSizer66, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 5 ); + bSizer69->Add( sbSizer21, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP, 5 ); - bSizer69->Add( sbSizer21, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP|wxRIGHT|wxLEFT, 5 ); m_panel13->SetSizer( bSizer69 ); m_panel13->Layout(); bSizer69->Fit( m_panel13 ); - bSizer21->Add( m_panel13, 0, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxEXPAND, 5 ); - - - bSizer21->Add( 0, 0, 0, 0, 5 ); + bSizer21->Add( m_panel13, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); wxBoxSizer* bSizer159; bSizer159 = new wxBoxSizer( wxHORIZONTAL ); @@ -3006,6 +3121,7 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w m_textCtrlInclude = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), wxTE_MULTILINE ); sbSizer8->Add( m_textCtrlInclude, 1, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + bSizer166->Add( sbSizer8, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); wxStaticBoxSizer* sbSizer26; @@ -3017,8 +3133,10 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w m_textCtrlExclude = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), wxTE_MULTILINE ); sbSizer26->Add( m_textCtrlExclude, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer166->Add( sbSizer26, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + bSizer159->Add( bSizer166, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); @@ -3028,7 +3146,7 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w bSizer160 = new wxBoxSizer( wxVERTICAL ); wxStaticBoxSizer* sbSizer25; - sbSizer25 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Date") ), wxHORIZONTAL ); + sbSizer25 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Time span") ), wxHORIZONTAL ); wxBoxSizer* bSizer169; bSizer169 = new wxBoxSizer( wxHORIZONTAL ); @@ -3039,33 +3157,31 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w wxBoxSizer* bSizer165; bSizer165 = new wxBoxSizer( wxVERTICAL ); - m_staticText103 = new wxStaticText( this, wxID_ANY, _("Select time span"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText103->Wrap( -1 ); - bSizer165->Add( m_staticText103, 0, 0, 5 ); - wxBoxSizer* bSizer164; bSizer164 = new wxBoxSizer( wxVERTICAL ); + m_spinCtrlTimespan = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 2000000000, 0 ); + bSizer164->Add( m_spinCtrlTimespan, 0, wxALIGN_CENTER_VERTICAL, 5 ); + wxArrayString m_choiceUnitTimespanChoices; m_choiceUnitTimespan = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceUnitTimespanChoices, 0 ); m_choiceUnitTimespan->SetSelection( 0 ); bSizer164->Add( m_choiceUnitTimespan, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_spinCtrlTimespan = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 2000000000, 0 ); - m_spinCtrlTimespan->Hide(); - - bSizer164->Add( m_spinCtrlTimespan, 0, wxALIGN_CENTER_VERTICAL, 5 ); bSizer165->Add( bSizer164, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer169->Add( bSizer165, 0, wxALIGN_CENTER_VERTICAL, 5 ); + sbSizer25->Add( bSizer169, 0, 0, 5 ); + bSizer160->Add( sbSizer25, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); wxStaticBoxSizer* sbSizer81; - sbSizer81 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Size") ), wxHORIZONTAL ); + sbSizer81 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("File size") ), wxHORIZONTAL ); wxBoxSizer* bSizer170; bSizer170 = new wxBoxSizer( wxHORIZONTAL ); @@ -3076,13 +3192,13 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w wxBoxSizer* bSizer158; bSizer158 = new wxBoxSizer( wxVERTICAL ); - m_staticText101 = new wxStaticText( this, wxID_ANY, _("Minimum file size"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText101->Wrap( -1 ); - bSizer158->Add( m_staticText101, 0, 0, 5 ); - wxBoxSizer* bSizer162; bSizer162 = new wxBoxSizer( wxVERTICAL ); + m_staticText101 = new wxStaticText( this, wxID_ANY, _("Minimum"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText101->Wrap( -1 ); + bSizer162->Add( m_staticText101, 0, wxBOTTOM, 2 ); + m_spinCtrlMinSize = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 2000000000, 0 ); bSizer162->Add( m_spinCtrlMinSize, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -3091,15 +3207,16 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w m_choiceUnitMinSize->SetSelection( 0 ); bSizer162->Add( m_choiceUnitMinSize, 0, wxALIGN_CENTER_VERTICAL, 5 ); - bSizer158->Add( bSizer162, 0, wxBOTTOM, 5 ); - m_staticText102 = new wxStaticText( this, wxID_ANY, _("Maximum file size"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText102->Wrap( -1 ); - bSizer158->Add( m_staticText102, 0, 0, 5 ); + bSizer158->Add( bSizer162, 0, wxBOTTOM, 5 ); wxBoxSizer* bSizer163; bSizer163 = new wxBoxSizer( wxVERTICAL ); + m_staticText102 = new wxStaticText( this, wxID_ANY, _("Maximum"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText102->Wrap( -1 ); + bSizer163->Add( m_staticText102, 0, wxBOTTOM, 2 ); + m_spinCtrlMaxSize = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 2000000000, 0 ); bSizer163->Add( m_spinCtrlMaxSize, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -3108,17 +3225,23 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w m_choiceUnitMaxSize->SetSelection( 0 ); bSizer163->Add( m_choiceUnitMaxSize, 0, wxALIGN_CENTER_VERTICAL, 5 ); - bSizer158->Add( bSizer163, 0, wxTOP, 5 ); + + bSizer158->Add( bSizer163, 0, 0, 5 ); + bSizer170->Add( bSizer158, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + sbSizer81->Add( bSizer170, 0, 0, 5 ); + bSizer160->Add( sbSizer81, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + bSizer159->Add( bSizer160, 0, wxEXPAND, 5 ); - bSizer21->Add( bSizer159, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + bSizer21->Add( bSizer159, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); wxBoxSizer* bSizer22; bSizer22 = new wxBoxSizer( wxHORIZONTAL ); @@ -3142,8 +3265,10 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w bSizer22->Add( m_button17, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + bSizer21->Add( bSizer22, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP|wxBOTTOM|wxEXPAND, 5 ); + this->SetSizer( bSizer21 ); this->Layout(); bSizer21->Fit( this ); @@ -3179,86 +3304,6 @@ FilterDlgGenerated::~FilterDlgGenerated() } -CustomizeColsDlgGenerated::CustomizeColsDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) -{ - this->SetSizeHints( wxDefaultSize, wxDefaultSize ); - - wxBoxSizer* bSizer96; - bSizer96 = new wxBoxSizer( wxVERTICAL ); - - wxBoxSizer* bSizer99; - bSizer99 = new wxBoxSizer( wxHORIZONTAL ); - - wxArrayString m_checkListColumnsChoices; - m_checkListColumns = new wxCheckListBox( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_checkListColumnsChoices, 0 ); - bSizer99->Add( m_checkListColumns, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - wxBoxSizer* bSizer98; - bSizer98 = new wxBoxSizer( wxVERTICAL ); - - m_bpButton29 = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); - m_bpButton29->SetToolTip( _("Move column up") ); - - bSizer98->Add( m_bpButton29, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - - m_bpButton30 = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), wxBU_AUTODRAW ); - m_bpButton30->SetToolTip( _("Move column down") ); - - bSizer98->Add( m_bpButton30, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); - - bSizer99->Add( bSizer98, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - bSizer96->Add( bSizer99, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); - - wxBoxSizer* bSizer97; - bSizer97 = new wxBoxSizer( wxHORIZONTAL ); - - m_button9 = new wxButton( this, wxID_DEFAULT, _("&Default"), wxDefaultPosition, wxSize( -1,30 ), 0 ); - m_button9->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); - - bSizer97->Add( m_button9, 0, wxALL, 5 ); - - - bSizer97->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL, 5 ); - - m_button28 = new wxButton( this, wxID_OK, _("&OK"), wxDefaultPosition, wxSize( -1,30 ), 0 ); - m_button28->SetDefault(); - m_button28->SetFont( wxFont( 10, 70, 90, 92, false, wxEmptyString ) ); - - bSizer97->Add( m_button28, 0, wxTOP|wxBOTTOM|wxLEFT, 5 ); - - m_button29 = new wxButton( this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxSize( -1,30 ), 0 ); - m_button29->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); - - bSizer97->Add( m_button29, 0, wxALL, 5 ); - - bSizer96->Add( bSizer97, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 ); - - this->SetSizer( bSizer96 ); - this->Layout(); - bSizer96->Fit( this ); - - // Connect Events - this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CustomizeColsDlgGenerated::OnClose ) ); - m_bpButton29->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnMoveUp ), NULL, this ); - m_bpButton30->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnMoveDown ), NULL, this ); - m_button9->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnDefault ), NULL, this ); - m_button28->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnOkay ), NULL, this ); - m_button29->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnCancel ), NULL, this ); -} - -CustomizeColsDlgGenerated::~CustomizeColsDlgGenerated() -{ - // Disconnect Events - this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CustomizeColsDlgGenerated::OnClose ) ); - m_bpButton29->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnMoveUp ), NULL, this ); - m_bpButton30->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnMoveDown ), NULL, this ); - m_button9->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnDefault ), NULL, this ); - m_button28->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnOkay ), NULL, this ); - m_button29->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CustomizeColsDlgGenerated::OnCancel ), NULL, this ); - -} - GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) { this->SetSizeHints( wxSize( 280,230 ), wxDefaultSize ); @@ -3270,10 +3315,7 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind bSizer86 = new wxBoxSizer( wxHORIZONTAL ); m_bitmapSettings = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), 0 ); - bSizer86->Add( m_bitmapSettings, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - - bSizer86->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer86->Add( m_bitmapSettings, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); m_panel8 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER|wxTAB_TRAVERSAL ); m_panel8->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT ) ); @@ -3283,19 +3325,18 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind m_staticText56 = new wxStaticText( m_panel8, wxID_ANY, _("Global settings"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText56->Wrap( -1 ); - m_staticText56->SetFont( wxFont( 16, 70, 90, 92, false, wxEmptyString ) ); + m_staticText56->SetFont( wxFont( 14, 70, 90, 92, false, wxEmptyString ) ); bSizer72->Add( m_staticText56, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); + m_panel8->SetSizer( bSizer72 ); m_panel8->Layout(); bSizer72->Fit( m_panel8 ); - bSizer86->Add( m_panel8, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - bSizer95->Add( bSizer86, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer86->Add( m_panel8, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); - bSizer95->Add( 0, 5, 0, 0, 5 ); + bSizer95->Add( bSizer86, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP|wxRIGHT|wxLEFT, 5 ); wxStaticBoxSizer* sbSizer23; sbSizer23 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxEmptyString ), wxVERTICAL ); @@ -3327,30 +3368,13 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind sbSizer23->Add( m_staticText8211, 0, wxLEFT|wxEXPAND, 20 ); - bSizer95->Add( sbSizer23, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT|wxEXPAND, 5 ); - wxStaticBoxSizer* sbSizer261; - sbSizer261 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxEmptyString ), wxVERTICAL ); + bSizer95->Add( sbSizer23, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxRIGHT|wxLEFT, 5 ); - wxBoxSizer* bSizer101; - bSizer101 = new wxBoxSizer( wxHORIZONTAL ); - - m_staticText100 = new wxStaticText( this, wxID_ANY, _("Hidden dialogs:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText100->Wrap( -1 ); - bSizer101->Add( m_staticText100, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - - bSizer101->Add( 0, 0, 1, wxEXPAND, 5 ); - - m_buttonResetDialogs = new zen::BitmapButton( this, wxID_ANY, _("Reset"), wxDefaultPosition, wxSize( 80,-1 ), 0 ); + m_buttonResetDialogs = new zen::BitmapButton( this, wxID_ANY, _("Restore hidden dialogs"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); m_buttonResetDialogs->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); - m_buttonResetDialogs->SetToolTip( _("Show hidden dialogs") ); - - bSizer101->Add( m_buttonResetDialogs, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - - sbSizer261->Add( bSizer101, 0, wxEXPAND, 5 ); - bSizer95->Add( sbSizer261, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); + bSizer95->Add( m_buttonResetDialogs, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxTOP|wxRIGHT|wxLEFT, 5 ); wxStaticBoxSizer* sbSizer26; sbSizer26 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("External applications") ), wxHORIZONTAL ); @@ -3379,8 +3403,8 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind // Rows m_gridCustomCommand->EnableDragRowSize( false ); - m_gridCustomCommand->SetRowLabelSize( 0 ); - m_gridCustomCommand->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + m_gridCustomCommand->SetRowLabelSize( 1 ); + m_gridCustomCommand->SetRowLabelAlignment( wxALIGN_LEFT, wxALIGN_CENTRE ); // Label Appearance @@ -3397,12 +3421,14 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind m_bpButtonRemoveRow = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 19,21 ), wxBU_AUTODRAW ); bSizer157->Add( m_bpButtonRemoveRow, 0, 0, 5 ); + sbSizer26->Add( bSizer157, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); sbSizer26->Add( 5, 0, 0, 0, 5 ); - bSizer95->Add( sbSizer26, 1, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT|wxEXPAND, 5 ); + + bSizer95->Add( sbSizer26, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); wxBoxSizer* bSizer97; bSizer97 = new wxBoxSizer( wxHORIZONTAL ); @@ -3410,7 +3436,7 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind m_button9 = new wxButton( this, wxID_DEFAULT, _("&Default"), wxDefaultPosition, wxSize( -1,30 ), 0 ); m_button9->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); - bSizer97->Add( m_button9, 0, wxALL, 5 ); + bSizer97->Add( m_button9, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); bSizer97->Add( 0, 0, 1, 0, 5 ); @@ -3419,15 +3445,17 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind m_buttonOkay->SetDefault(); m_buttonOkay->SetFont( wxFont( 10, 70, 90, 92, false, wxEmptyString ) ); - bSizer97->Add( m_buttonOkay, 0, wxTOP|wxBOTTOM|wxLEFT, 5 ); + bSizer97->Add( m_buttonOkay, 0, wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); m_button29 = new wxButton( this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxSize( -1,30 ), 0 ); m_button29->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); - bSizer97->Add( m_button29, 0, wxALL, 5 ); + bSizer97->Add( m_button29, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer95->Add( bSizer97, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + this->SetSizer( bSizer95 ); this->Layout(); bSizer95->Fit( this ); @@ -3467,10 +3495,10 @@ SyncPreviewDlgGenerated::SyncPreviewDlgGenerated( wxWindow* parent, wxWindowID i m_buttonStartSync = new zen::BitmapButton( this, wxID_ANY, _("Start"), wxDefaultPosition, wxSize( -1,40 ), 0 ); m_buttonStartSync->SetDefault(); - m_buttonStartSync->SetFont( wxFont( 14, 70, 90, 92, false, wxT("Arial Black") ) ); + m_buttonStartSync->SetFont( wxFont( 14, 70, 90, 92, false, wxEmptyString ) ); m_buttonStartSync->SetToolTip( _("Start synchronization") ); - bSizer158->Add( m_buttonStartSync, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer158->Add( m_buttonStartSync, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); m_staticline16 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ); bSizer158->Add( m_staticline16, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); @@ -3480,12 +3508,14 @@ SyncPreviewDlgGenerated::SyncPreviewDlgGenerated( wxWindow* parent, wxWindowID i m_staticTextVariant = new wxStaticText( this, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextVariant->Wrap( -1 ); - m_staticTextVariant->SetFont( wxFont( 10, 70, 90, 92, false, wxT("Arial Black") ) ); + m_staticTextVariant->SetFont( wxFont( 10, 70, 90, 92, false, wxEmptyString ) ); sbSizer28->Add( m_staticTextVariant, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer158->Add( sbSizer28, 1, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + bSizer134->Add( bSizer158, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); m_staticline14 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); @@ -3520,7 +3550,7 @@ SyncPreviewDlgGenerated::SyncPreviewDlgGenerated( wxWindow* parent, wxWindowID i fgSizer5->Add( m_bitmapCreate, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); m_textCtrlCreateL = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY|wxTE_RIGHT ); - m_textCtrlCreateL->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_textCtrlCreateL->SetBackgroundColour( wxColour( 224, 224, 224 ) ); m_textCtrlCreateL->SetToolTip( _("Number of files and directories that will be created") ); fgSizer5->Add( m_textCtrlCreateL, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -3531,7 +3561,7 @@ SyncPreviewDlgGenerated::SyncPreviewDlgGenerated( wxWindow* parent, wxWindowID i fgSizer5->Add( m_bitmapUpdate, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); m_textCtrlUpdateL = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY|wxTE_RIGHT ); - m_textCtrlUpdateL->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_textCtrlUpdateL->SetBackgroundColour( wxColour( 224, 224, 224 ) ); m_textCtrlUpdateL->SetToolTip( _("Number of files that will be overwritten") ); fgSizer5->Add( m_textCtrlUpdateL, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -3542,11 +3572,12 @@ SyncPreviewDlgGenerated::SyncPreviewDlgGenerated( wxWindow* parent, wxWindowID i fgSizer5->Add( m_bitmapDelete, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); m_textCtrlDeleteL = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY|wxTE_RIGHT ); - m_textCtrlDeleteL->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_textCtrlDeleteL->SetBackgroundColour( wxColour( 224, 224, 224 ) ); m_textCtrlDeleteL->SetToolTip( _("Number of files and directories that will be deleted") ); fgSizer5->Add( m_textCtrlDeleteL, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer157->Add( fgSizer5, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); wxFlexGridSizer* fgSizer51; @@ -3561,25 +3592,27 @@ SyncPreviewDlgGenerated::SyncPreviewDlgGenerated( wxWindow* parent, wxWindowID i fgSizer51->Add( m_staticText95, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); m_textCtrlCreateR = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY|wxTE_RIGHT ); - m_textCtrlCreateR->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_textCtrlCreateR->SetBackgroundColour( wxColour( 224, 224, 224 ) ); m_textCtrlCreateR->SetToolTip( _("Number of files and directories that will be created") ); fgSizer51->Add( m_textCtrlCreateR, 0, wxALIGN_CENTER_VERTICAL, 5 ); m_textCtrlUpdateR = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY|wxTE_RIGHT ); - m_textCtrlUpdateR->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_textCtrlUpdateR->SetBackgroundColour( wxColour( 224, 224, 224 ) ); m_textCtrlUpdateR->SetToolTip( _("Number of files that will be overwritten") ); fgSizer51->Add( m_textCtrlUpdateR, 0, wxALIGN_CENTER_VERTICAL, 5 ); m_textCtrlDeleteR = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_READONLY|wxTE_RIGHT ); - m_textCtrlDeleteR->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_textCtrlDeleteR->SetBackgroundColour( wxColour( 224, 224, 224 ) ); m_textCtrlDeleteR->SetToolTip( _("Number of files and directories that will be deleted") ); fgSizer51->Add( m_textCtrlDeleteR, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer157->Add( fgSizer51, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); + sbSizer161->Add( bSizer157, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); @@ -3597,7 +3630,7 @@ SyncPreviewDlgGenerated::SyncPreviewDlgGenerated( wxWindow* parent, wxWindowID i bSizer156->Add( 0, 0, 1, wxEXPAND, 5 ); m_textCtrlData = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80,-1 ), wxTE_CENTRE|wxTE_READONLY ); - m_textCtrlData->SetBackgroundColour( wxColour( 208, 208, 208 ) ); + m_textCtrlData->SetBackgroundColour( wxColour( 224, 224, 224 ) ); m_textCtrlData->SetToolTip( _("Total amount of data that will be transferred") ); bSizer156->Add( m_textCtrlData, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -3605,20 +3638,23 @@ SyncPreviewDlgGenerated::SyncPreviewDlgGenerated( wxWindow* parent, wxWindowID i bSizer156->Add( 0, 0, 1, wxEXPAND, 5 ); + sbSizer161->Add( bSizer156, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT|wxEXPAND, 5 ); + bSizer141->Add( sbSizer161, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); + bSizer134->Add( bSizer141, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); m_staticline12 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - bSizer134->Add( m_staticline12, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 ); + bSizer134->Add( m_staticline12, 0, wxEXPAND|wxTOP, 5 ); wxBoxSizer* bSizer142; bSizer142 = new wxBoxSizer( wxHORIZONTAL ); m_checkBoxDontShowAgain = new wxCheckBox( this, wxID_ANY, _("Do not show this dialog again"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer142->Add( m_checkBoxDontShowAgain, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer142->Add( m_checkBoxDontShowAgain, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxALIGN_CENTER_VERTICAL, 5 ); bSizer142->Add( 10, 0, 1, 0, 5 ); @@ -3626,10 +3662,12 @@ SyncPreviewDlgGenerated::SyncPreviewDlgGenerated( wxWindow* parent, wxWindowID i m_button16 = new wxButton( this, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxSize( -1,30 ), 0 ); m_button16->SetFont( wxFont( 10, 70, 90, 90, false, wxEmptyString ) ); - bSizer142->Add( m_button16, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer142->Add( m_button16, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); + bSizer134->Add( bSizer142, 0, wxEXPAND, 5 ); + this->SetSizer( bSizer134 ); this->Layout(); bSizer134->Fit( this ); @@ -3663,6 +3701,7 @@ PopupFrameGenerated1::PopupFrameGenerated1( wxWindow* parent, wxWindowID id, con m_staticTextMain->Wrap( 600 ); bSizer158->Add( m_staticTextMain, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + this->SetSizer( bSizer158 ); this->Layout(); bSizer158->Fit( this ); @@ -3692,6 +3731,7 @@ SearchDialogGenerated::SearchDialogGenerated( wxWindow* parent, wxWindowID id, c m_textCtrlSearchTxt = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 220,-1 ), 0 ); bSizer162->Add( m_textCtrlSearchTxt, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + bSizer166->Add( bSizer162, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); @@ -3700,6 +3740,7 @@ SearchDialogGenerated::SearchDialogGenerated( wxWindow* parent, wxWindowID id, c m_checkBoxMatchCase = new wxCheckBox( this, wxID_ANY, _("Match case"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer166->Add( m_checkBoxMatchCase, 0, wxALL, 5 ); + bSizer161->Add( bSizer166, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); wxBoxSizer* bSizer97; @@ -3716,8 +3757,10 @@ SearchDialogGenerated::SearchDialogGenerated( wxWindow* parent, wxWindowID id, c bSizer97->Add( m_button29, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5 ); + bSizer161->Add( bSizer97, 0, wxALIGN_CENTER_VERTICAL, 5 ); + this->SetSizer( bSizer161 ); this->Layout(); bSizer161->Fit( this ); @@ -3755,6 +3798,7 @@ SelectTimespanDlgGenerated::SelectTimespanDlgGenerated( wxWindow* parent, wxWind m_calendarTo = new wxCalendarCtrl( this, wxID_ANY, wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxCAL_SHOW_HOLIDAYS ); bSizer98->Add( m_calendarTo, 0, wxALL, 5 ); + bSizer96->Add( bSizer98, 0, wxALIGN_CENTER_VERTICAL, 5 ); wxBoxSizer* bSizer97; @@ -3777,8 +3821,10 @@ SelectTimespanDlgGenerated::SelectTimespanDlgGenerated( wxWindow* parent, wxWind bSizer97->Add( 0, 0, 1, wxEXPAND, 5 ); + bSizer96->Add( bSizer97, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + this->SetSizer( bSizer96 ); this->Layout(); bSizer96->Fit( this ); diff --git a/ui/gui_generated.h b/ui/gui_generated.h index 4cc32873..8176dbf9 100644 --- a/ui/gui_generated.h +++ b/ui/gui_generated.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Dec 2 2011) +// C++ code generated with wxFormBuilder (version Mar 17 2012) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -11,15 +11,14 @@ #include <wx/artprov.h> #include <wx/xrc/xmlres.h> #include <wx/intl.h> -class ExecFinishedBox; -class FolderHistoryBox; -class ToggleButton; -class wxStaticText; -namespace zen { class BitmapButton; } -namespace zen { class DirPickerCtrl; } -namespace zen { class Graph2D; } -namespace zen { class Grid; } - +#include "wx_form_build_hide_warnings.h" +#include "../wx+/button.h" +#include "folder_history_box.h" +#include "../wx+/dir_picker.h" +#include "../wx+/grid.h" +#include "../wx+/toggle_button.h" +#include "exec_finished_box.h" +#include "../wx+/graph.h" #include <wx/string.h> #include <wx/bitmap.h> #include <wx/image.h> @@ -47,14 +46,14 @@ namespace zen { class Grid; } #include <wx/statbox.h> #include <wx/choice.h> #include <wx/spinctrl.h> -#include <wx/listbook.h> -#include <wx/listctrl.h> +#include <wx/notebook.h> #include <wx/dialog.h> #include <wx/radiobut.h> #include <wx/animate.h> +#include <wx/listbook.h> +#include <wx/listctrl.h> #include <wx/imaglist.h> #include <wx/hyperlink.h> -#include <wx/checklst.h> #include <wx/grid.h> #include <wx/calctrl.h> @@ -83,6 +82,7 @@ protected: wxMenuItem* m_menuItemGlobSett; wxMenuItem* m_menuItem7; wxMenu* m_menuHelp; + wxMenuItem* m_menuItemManual; wxMenuItem* m_menuItemCheckVer; wxMenuItem* m_menuItemAbout; wxBoxSizer* bSizerPanelHolder; @@ -294,7 +294,7 @@ protected: wxStaticText* m_staticText56; wxStaticText* m_staticText44; wxBitmapButton* m_bpButtonHelp; - wxListbook* m_listbook1; + wxNotebook* m_notebook1; wxPanel* m_panelOverview; wxBitmapButton* m_bpButtonCmpConfig; wxStaticText* m_staticTextCmpVariant; @@ -349,7 +349,7 @@ public: wxBitmapButton* m_bpButtonAltSyncCfg; FolderHistoryBox* m_comboBoxLogfileDir; - BatchDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Create a batch job"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + BatchDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Create a batch job"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER ); ~BatchDlgGenerated(); }; @@ -524,24 +524,24 @@ protected: wxPanel* m_panelProgress; wxBoxSizer* bSizer171; wxStaticBoxSizer* bSizerProgressStat; - wxStaticText* m_staticTextItemsRem; - wxBoxSizer* bSizerItemsRem; - wxStaticText* m_staticTextRemainingObj; - wxStaticText* m_staticText96; - wxStaticText* m_staticTextDataRemaining; - wxStaticText* m_staticText97; - wxStaticText* m_staticTextItemsProc; + wxStaticText* m_staticTextLabelItemsProc; wxBoxSizer* bSizerItemsProc; wxStaticText* m_staticTextProcessedObj; wxStaticText* m_staticText98; wxStaticText* m_staticTextDataProcessed; wxStaticText* m_staticText99; - wxStaticText* m_staticTextSpeedDescr; - wxStaticText* m_staticTextSpeed; - wxStaticText* m_staticText55; + wxStaticText* m_staticTextLabelItemsRem; + wxBoxSizer* bSizerItemsRem; + wxStaticText* m_staticTextRemainingObj; + wxStaticText* m_staticText96; + wxStaticText* m_staticTextDataRemaining; + wxStaticText* m_staticText97; + wxStaticText* m_staticTextLabelElapsedTime; wxStaticText* m_staticTextTimeElapsed; - wxStaticText* m_staticTextRemTimeDescr; + wxStaticText* m_staticTextLabelRemTime; wxStaticText* m_staticTextRemTime; + wxStaticText* m_staticText84; + wxStaticText* m_staticTextSpeed; zen::Graph2D* m_panelGraph; wxBoxSizer* bSizerFinalStat; wxListbook* m_listbookResult; @@ -716,14 +716,13 @@ private: protected: wxStaticBitmap* m_bitmap10; wxTextCtrl* m_textCtrl8; - wxCheckBox* m_checkBoxDontAskAgain; + wxCheckBox* m_checkBox; wxButton* m_buttonYes; wxButton* m_buttonNo; wxButton* m_buttonCancel; // Virtual event handlers, overide them in your derived class virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } - virtual void OnCheckBoxDontShowAgain( wxCommandEvent& event ) { event.Skip(); } virtual void OnYes( wxCommandEvent& event ) { event.Skip(); } virtual void OnNo( wxCommandEvent& event ) { event.Skip(); } virtual void OnCancel( wxCommandEvent& event ) { event.Skip(); } @@ -747,22 +746,22 @@ protected: wxStaticBitmap* m_bitmap12; wxStaticText* m_staticTextHeader; wxTextCtrl* m_textCtrlMessage; - wxCheckBox* m_checkBoxDeleteBothSides; wxCheckBox* m_checkBoxUseRecycler; + wxCheckBox* m_checkBoxDeleteBothSides; wxButton* m_buttonOK; wxButton* m_buttonCancel; // Virtual event handlers, overide them in your derived class virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } - virtual void OnDelOnBothSides( wxCommandEvent& event ) { event.Skip(); } virtual void OnUseRecycler( wxCommandEvent& event ) { event.Skip(); } + virtual void OnDelOnBothSides( wxCommandEvent& event ) { event.Skip(); } virtual void OnOK( wxCommandEvent& event ) { event.Skip(); } virtual void OnCancel( wxCommandEvent& event ) { event.Skip(); } public: - DeleteDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Confirm"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 553,336 ), long style = wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER ); + DeleteDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Confirm"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 560,336 ), long style = wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER ); ~DeleteDlgGenerated(); }; @@ -793,9 +792,8 @@ protected: wxStaticBitmap* m_bitmapExclude; wxTextCtrl* m_textCtrlExclude; wxStaticBitmap* m_bitmapFilterDate; - wxStaticText* m_staticText103; - wxChoice* m_choiceUnitTimespan; wxSpinCtrl* m_spinCtrlTimespan; + wxChoice* m_choiceUnitTimespan; wxStaticBitmap* m_bitmapFilterSize; wxStaticText* m_staticText101; wxSpinCtrl* m_spinCtrlMinSize; @@ -825,37 +823,6 @@ public: }; /////////////////////////////////////////////////////////////////////////////// -/// Class CustomizeColsDlgGenerated -/////////////////////////////////////////////////////////////////////////////// -class CustomizeColsDlgGenerated : public wxDialog -{ -private: - -protected: - wxCheckListBox* m_checkListColumns; - wxBitmapButton* m_bpButton29; - wxBitmapButton* m_bpButton30; - wxButton* m_button9; - wxButton* m_button28; - wxButton* m_button29; - - // Virtual event handlers, overide them in your derived class - virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } - virtual void OnMoveUp( wxCommandEvent& event ) { event.Skip(); } - virtual void OnMoveDown( wxCommandEvent& event ) { event.Skip(); } - virtual void OnDefault( wxCommandEvent& event ) { event.Skip(); } - virtual void OnOkay( wxCommandEvent& event ) { event.Skip(); } - virtual void OnCancel( wxCommandEvent& event ) { event.Skip(); } - - -public: - - CustomizeColsDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Customize columns"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); - ~CustomizeColsDlgGenerated(); - -}; - -/////////////////////////////////////////////////////////////////////////////// /// Class GlobalSettingsDlgGenerated /////////////////////////////////////////////////////////////////////////////// class GlobalSettingsDlgGenerated : public wxDialog @@ -872,7 +839,6 @@ protected: wxStaticText* m_staticTextCopyLocked; wxCheckBox* m_checkBoxCopyPermissions; wxStaticText* m_staticText8211; - wxStaticText* m_staticText100; zen::BitmapButton* m_buttonResetDialogs; wxGrid* m_gridCustomCommand; wxBitmapButton* m_bpButtonAddRow; diff --git a/ui/gui_status_handler.cpp b/ui/gui_status_handler.cpp index 42c50671..6e3c08a0 100644 --- a/ui/gui_status_handler.cpp +++ b/ui/gui_status_handler.cpp @@ -31,11 +31,12 @@ CompareStatusHandler::CompareStatusHandler(MainDialog& dlg) : //display status panel during compare mainDlg.auiMgr.GetPane(mainDlg.compareStatus->getAsWindow()).Show(); mainDlg.auiMgr.Update(); + mainDlg.compareStatus->updateStatusPanelNow(); //clear gui flicker: window must be visible to make this work! //register abort button - mainDlg.m_buttonAbort->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CompareStatusHandler::OnAbortCompare), NULL, this); + mainDlg.m_buttonAbort->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CompareStatusHandler::OnAbortCompare), nullptr, this); //register key event - mainDlg.Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(CompareStatusHandler::OnKeyPressed), NULL, this); + mainDlg.Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(CompareStatusHandler::OnKeyPressed), nullptr, this); } @@ -54,8 +55,8 @@ CompareStatusHandler::~CompareStatusHandler() mainDlg.pushStatusInformation(_("Operation aborted!")); //de-register keys - mainDlg.Disconnect(wxEVT_CHAR_HOOK, wxKeyEventHandler(CompareStatusHandler::OnKeyPressed), NULL, this); - mainDlg.m_buttonAbort->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CompareStatusHandler::OnAbortCompare), NULL, this); + mainDlg.Disconnect(wxEVT_CHAR_HOOK, wxKeyEventHandler(CompareStatusHandler::OnKeyPressed), nullptr, this); + mainDlg.m_buttonAbort->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CompareStatusHandler::OnAbortCompare), nullptr, this); } @@ -169,7 +170,7 @@ void CompareStatusHandler::reportFatalError(const std::wstring& errorMessage) forceUiRefresh(); showErrorDlg(ReturnErrorDlg::BUTTON_ABORT, - errorMessage, NULL); + errorMessage, nullptr); } @@ -233,7 +234,7 @@ SyncStatusHandler::SyncStatusHandler(MainDialog* parentDlg, SyncStatusHandler::~SyncStatusHandler() { - const int totalErrors = errorLog.typeCount(TYPE_ERROR | TYPE_FATAL_ERROR); //evaluate before finalizing log + const int totalErrors = errorLog.getItemCount(TYPE_ERROR | TYPE_FATAL_ERROR); //evaluate before finalizing log //finalize error log if (abortIsRequested()) diff --git a/ui/gui_status_handler.h b/ui/gui_status_handler.h index 1977e265..4e289648 100644 --- a/ui/gui_status_handler.h +++ b/ui/gui_status_handler.h @@ -7,10 +7,10 @@ #ifndef GUISTATUSHANDLER_H_INCLUDED #define GUISTATUSHANDLER_H_INCLUDED -#include "../lib/status_handler.h" #include <wx/event.h> -#include "../lib/error_log.h" +#include <zen/error_log.h> #include "progress_indicator.h" +#include "../lib/status_handler.h" #include "../lib/process_xml.h" #include "main_dlg.h" @@ -76,7 +76,7 @@ private: MainDialog* parentDlg_; SyncStatus syncStatusFrame; //the window managed by SyncStatus has longer lifetime than this handler! xmlAccess::OnGuiError handleError_; - zen::ErrorLogging errorLog; + zen::ErrorLog errorLog; }; diff --git a/ui/main_dlg.cpp b/ui/main_dlg.cpp index 24f1b06e..85f9a580 100644 --- a/ui/main_dlg.cpp +++ b/ui/main_dlg.cpp @@ -56,7 +56,6 @@ #include <wx+/no_flicker.h> #include <wx+/grid.h> - using namespace zen; using namespace std::rel_ops; @@ -69,8 +68,24 @@ struct wxClientDataString : public wxClientData //we need a wxClientData derived wxString name_; }; + +IconBuffer::IconSize convert(xmlAccess::FileIconSize isize) +{ + using namespace xmlAccess; + switch (isize) + { + case ICON_SIZE_SMALL: + return IconBuffer::SIZE_SMALL; + case ICON_SIZE_MEDIUM: + return IconBuffer::SIZE_MEDIUM; + case ICON_SIZE_LARGE: + return IconBuffer::SIZE_LARGE; + } + return IconBuffer::SIZE_SMALL; +} } + class DirectoryNameMainImpl : public DirectoryName<FolderHistoryBox> { public: @@ -159,20 +174,9 @@ private: return &mainDlg; } - virtual MainConfiguration getMainConfig() const - { - return mainDlg.getConfig().mainCfg; - } - - virtual void OnAltCompCfgChange() - { - mainDlg.applyCompareConfig(false); //false: do not change preview status - } - - virtual void OnAltSyncCfgChange() - { - mainDlg.applySyncConfig(); - } + virtual MainConfiguration getMainConfig() const { return mainDlg.getConfig().mainCfg; } + virtual void OnAltCompCfgChange() { mainDlg.applyCompareConfig(false); } //false: do not change preview status + virtual void OnAltSyncCfgChange() { mainDlg.applySyncConfig(); } virtual void removeAltCompCfg() { @@ -181,16 +185,12 @@ private: } virtual void removeAltSyncCfg() - { FolderPairPanelBasic<GuiPanel>::removeAltSyncCfg(); mainDlg.applySyncConfig(); } - virtual void OnLocalFilterCfgChange() - { - mainDlg.applyFilterConfig(); //re-apply filter - } + virtual void OnLocalFilterCfgChange() { mainDlg.applyFilterConfig(); } //re-apply filter virtual void removeLocalFilterCfg() { @@ -350,7 +350,7 @@ private: //################################################################################################################################## MainDialog::MainDialog(const std::vector<wxString>& cfgFileNames, xmlAccess::XmlGlobalSettings& settings) : - MainDialogGenerated(NULL) + MainDialogGenerated(nullptr) { xmlAccess::XmlGuiConfig guiCfg; //structure to receive gui settings, already defaulted!! @@ -376,7 +376,7 @@ MainDialog::MainDialog(const std::vector<wxString>& cfgFileNames, xmlAccess::Xml //------------------------------------------------------------------------------------------ //check if one of the files is not existing (this shall not be an error!) - const bool allFilesExist = std::find_if(fileEx.begin(), fileEx.end(), [](boost::unique_future<bool>& ft) { return !ft.is_ready() || !ft.get(); }) == fileEx.end(); + const bool allFilesExist = std::all_of(fileEx.begin(), fileEx.end(), [](boost::unique_future<bool>& ft) { return ft.is_ready() && ft.get(); }); if (!allFilesExist) filenames.clear(); @@ -417,7 +417,7 @@ MainDialog::MainDialog(const std::vector<wxString>& referenceFiles, const xmlAccess::XmlGuiConfig& guiCfg, xmlAccess::XmlGlobalSettings& settings, bool startComparison) : - MainDialogGenerated(NULL) + MainDialogGenerated(nullptr) { init(guiCfg, settings, @@ -429,6 +429,8 @@ MainDialog::MainDialog(const std::vector<wxString>& referenceFiles, MainDialog::~MainDialog() { + wxWindowUpdateLocker dummy(this); + writeGlobalSettings(); //set before saving last used config since "activeConfigFiles" will be replaced //save "LastRun.ffs_gui" configuration @@ -442,8 +444,8 @@ MainDialog::~MainDialog() catch (const xmlAccess::FfsXmlError&) {} //important! event source wxTheApp is NOT dependent on this instance -> disconnect! - wxTheApp->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainDialog::OnGlobalKeyEvent), NULL, this); - wxTheApp->Disconnect(wxEVT_CHAR_HOOK, wxKeyEventHandler(MainDialog::OnGlobalKeyEvent), NULL, this); + wxTheApp->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainDialog::OnGlobalKeyEvent), nullptr, this); + wxTheApp->Disconnect(wxEVT_CHAR_HOOK, wxKeyEventHandler(MainDialog::OnGlobalKeyEvent), nullptr, this); //no need for wxEventHandler::Disconnect() here; event sources are components of this window and are destroyed, too @@ -509,7 +511,7 @@ void MainDialog::init(const xmlAccess::XmlGuiConfig& guiCfg, wxAuiPaneInfo().Name(wxT("Panel3")).CenterPane().PaneBorder(false)); auiMgr.AddPane(m_gridNavi, - wxAuiPaneInfo().Name(L"Panel10").Left().Layer(3).Caption(_("Compressed view")).MinSize(350, m_gridNavi->GetSize().GetHeight())); //MinSize(): just default size, see comment below + wxAuiPaneInfo().Name(L"Panel10").Left().Layer(3).Caption(_("Overview")).MinSize(350, m_gridNavi->GetSize().GetHeight())); //MinSize(): just default size, see comment below auiMgr.AddPane(m_panelConfig, wxAuiPaneInfo().Name(wxT("Panel4")).Layer(4).Bottom().Row(1).Position(0).Caption(_("Configuration")).MinSize(m_listBoxHistory->GetSize().GetWidth(), m_panelConfig->GetSize().GetHeight())); @@ -534,31 +536,30 @@ void MainDialog::init(const xmlAccess::XmlGuiConfig& guiCfg, defaultPerspective = auiMgr.SavePerspective(); //---------------------------------------------------------------------------------- //register view layout context menu - m_panelTopButtons->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSetLayout), NULL, this); - m_panelConfig ->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSetLayout), NULL, this); - m_panelFilter ->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSetLayout), NULL, this); - m_panelViewFilter->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSetLayout), NULL, this); - m_panelStatistics->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSetLayout), NULL, this); - m_panelStatusBar ->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSetLayout), NULL, this); + m_panelTopButtons->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSetLayout), nullptr, this); + m_panelConfig ->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSetLayout), nullptr, this); + m_panelFilter ->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSetLayout), nullptr, this); + m_panelViewFilter->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSetLayout), nullptr, this); + m_panelStatistics->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSetLayout), nullptr, this); + m_panelStatusBar ->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSetLayout), nullptr, this); //---------------------------------------------------------------------------------- //register context: quick variant selection - m_bpButtonCmpConfig ->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnCompSettingsContext), NULL, this); - m_bpButtonSyncConfig->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnSyncSettingsContext), NULL, this); - m_bpButtonFilter ->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(MainDialog::OnGlobalFilterContext), NULL, this); + m_bpButtonCmpConfig ->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnCompSettingsContext), nullptr, this); + m_bpButtonSyncConfig->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnSyncSettingsContext), nullptr, this); + m_bpButtonFilter ->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(MainDialog::OnGlobalFilterContext), nullptr, this); //sort grids - m_gridMain->Connect(EVENT_GRID_COL_LABEL_MOUSE_LEFT, GridClickEventHandler(MainDialog::onGridLabelLeftClick ), NULL, this ); - m_gridMain->Connect(EVENT_GRID_COL_LABEL_MOUSE_RIGHT, GridClickEventHandler(MainDialog::onGridLabelContext), NULL, this ); + m_gridMain->Connect(EVENT_GRID_COL_LABEL_MOUSE_LEFT, GridClickEventHandler(MainDialog::onGridLabelLeftClick ), nullptr, this ); + m_gridMain->Connect(EVENT_GRID_COL_LABEL_MOUSE_RIGHT, GridClickEventHandler(MainDialog::onGridLabelContext), nullptr, this ); //grid context menu - m_gridMain->Connect(EVENT_GRID_MOUSE_RIGHT_UP, GridClickEventHandler(MainDialog::onMainGridContext), NULL, this); - m_gridNavi->Connect(EVENT_GRID_MOUSE_RIGHT_UP, GridClickEventHandler(MainDialog::onNaviGridContext), NULL, this); - - m_gridMain->Connect(EVENT_GRID_MOUSE_LEFT_DOUBLE, GridClickEventHandler(MainDialog::onGridDoubleClick), NULL, this ); + m_gridMain->Connect(EVENT_GRID_MOUSE_RIGHT_UP, GridClickEventHandler(MainDialog::onMainGridContext), nullptr, this); + m_gridNavi->Connect(EVENT_GRID_MOUSE_RIGHT_UP, GridClickEventHandler(MainDialog::onNaviGridContext), nullptr, this); - m_gridNavi->Connect(EVENT_GRID_SELECT_RANGE, GridRangeSelectEventHandler(MainDialog::onNaviSelection), NULL, this); + m_gridMain->Connect(EVENT_GRID_MOUSE_LEFT_DOUBLE, GridClickEventHandler(MainDialog::onGridDoubleClick), nullptr, this ); + m_gridNavi->Connect(EVENT_GRID_SELECT_RANGE, GridRangeSelectEventHandler(MainDialog::onNaviSelection), nullptr, this); globalSettings = &settings; gridDataView.reset(new zen::GridView); @@ -619,20 +620,20 @@ void MainDialog::init(const xmlAccess::XmlGuiConfig& guiCfg, MenuItemUpdater updateMenuFile(*m_menuFile); updateMenuFile.markForUpdate(m_menuItem10, GlobalResources::getImage(wxT("compareSmall"))); updateMenuFile.markForUpdate(m_menuItem11, GlobalResources::getImage(wxT("syncSmall"))); - updateMenuFile.markForUpdate(m_menuItemNew, GlobalResources::getImage(wxT("newSmall"))); + //updateMenuFile.markForUpdate(m_menuItemNew, GlobalResources::getImage(wxT("newSmall"))); updateMenuFile.markForUpdate(m_menuItemSave, GlobalResources::getImage(wxT("saveSmall"))); updateMenuFile.markForUpdate(m_menuItemLoad, GlobalResources::getImage(wxT("loadSmall"))); MenuItemUpdater updateMenuAdv(*m_menuAdvanced); - updateMenuAdv.markForUpdate(m_menuItemGlobSett, GlobalResources::getImage(wxT("settingsSmall"))); - updateMenuAdv.markForUpdate(m_menuItem7, GlobalResources::getImage(wxT("batchSmall"))); + updateMenuAdv.markForUpdate(m_menuItemGlobSett, GlobalResources::getImage(L"settingsSmall")); + updateMenuAdv.markForUpdate(m_menuItem7, GlobalResources::getImage(L"batchSmall")); MenuItemUpdater updateMenuHelp(*m_menuHelp); - updateMenuHelp.markForUpdate(m_menuItemAbout, GlobalResources::getImage(wxT("aboutSmall"))); + updateMenuHelp.markForUpdate(m_menuItemManual, GlobalResources::getImage(L"helpSmall")); + updateMenuHelp.markForUpdate(m_menuItemAbout, GlobalResources::getImage(L"aboutSmall")); #ifdef FFS_LINUX - if (!zen::isPortableVersion()) //disable update check for Linux installer-based version -> handled by .deb - m_menuItemCheckVer->Enable(false); + m_menuItemCheckVer->Enable(zen::isPortableVersion()); //disable update check for Linux installer-based version -> handled by .deb #endif //create language selection menu @@ -651,46 +652,46 @@ void MainDialog::init(const xmlAccess::XmlGuiConfig& guiCfg, }); //support for CTRL + C and DEL on grids - m_gridMain->getMainWin().Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainDialog::onGridButtonEvent), NULL, this); - m_gridNavi->getMainWin().Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainDialog::onTreeButtonEvent), NULL, this); + m_gridMain->getMainWin().Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainDialog::onGridButtonEvent), nullptr, this); + m_gridNavi->getMainWin().Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainDialog::onTreeButtonEvent), nullptr, this); //register global hotkeys (without explicit menu entry) - wxTheApp->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainDialog::OnGlobalKeyEvent), NULL, this); - wxTheApp->Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(MainDialog::OnGlobalKeyEvent), NULL, this); //capture direction keys + wxTheApp->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainDialog::OnGlobalKeyEvent), nullptr, this); + wxTheApp->Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(MainDialog::OnGlobalKeyEvent), nullptr, this); //capture direction keys //drag & drop on navi panel setupFileDrop(*m_gridNavi); - m_gridNavi->Connect(EVENT_DROP_FILE, FileDropEventHandler(MainDialog::onNaviPanelFilesDropped), NULL, this); + m_gridNavi->Connect(EVENT_DROP_FILE, FileDropEventHandler(MainDialog::onNaviPanelFilesDropped), nullptr, this); - Connect(wxEVT_IDLE, wxEventHandler(MainDialog::OnIdleEvent), NULL, this); + Connect(wxEVT_IDLE, wxEventHandler(MainDialog::OnIdleEvent), nullptr, this); - Connect(wxEVT_SIZE, wxSizeEventHandler(MainDialog::OnResize), NULL, this); - Connect(wxEVT_MOVE, wxSizeEventHandler(MainDialog::OnResize), NULL, this); + //Connect(wxEVT_SIZE, wxSizeEventHandler(MainDialog::OnResize), nullptr, this); + //Connect(wxEVT_MOVE, wxSizeEventHandler(MainDialog::OnResize), nullptr, this); //calculate witdh of folder pair manually (if scrollbars are visible) - m_panelTopLeft->Connect(wxEVT_SIZE, wxEventHandler(MainDialog::OnResizeFolderPairs), NULL, this); + m_panelTopLeft->Connect(wxEVT_SIZE, wxEventHandler(MainDialog::OnResizeFolderPairs), nullptr, this); //dynamically change sizer direction depending on size - m_panelConfig ->Connect(wxEVT_SIZE, wxEventHandler(MainDialog::OnResizeConfigPanel), NULL, this); - m_panelViewFilter->Connect(wxEVT_SIZE, wxEventHandler(MainDialog::OnResizeViewPanel), NULL, this); - m_panelStatistics->Connect(wxEVT_SIZE, wxEventHandler(MainDialog::OnResizeStatisticsPanel), NULL, this); + m_panelConfig ->Connect(wxEVT_SIZE, wxEventHandler(MainDialog::OnResizeConfigPanel), nullptr, this); + m_panelViewFilter->Connect(wxEVT_SIZE, wxEventHandler(MainDialog::OnResizeViewPanel), nullptr, this); + m_panelStatistics->Connect(wxEVT_SIZE, wxEventHandler(MainDialog::OnResizeStatisticsPanel), nullptr, this); wxSizeEvent dummy3; OnResizeConfigPanel (dummy3); //call once on window creation OnResizeViewPanel (dummy3); // OnResizeStatisticsPanel(dummy3); // //event handler for manual (un-)checking of rows and setting of sync direction - m_gridMain->Connect(EVENT_GRID_CHECK_ROWS, CheckRowsEventHandler (MainDialog::onCheckRows), NULL, this); - m_gridMain->Connect(EVENT_GRID_SYNC_DIRECTION, SyncDirectionEventHandler(MainDialog::onSetSyncDirection), NULL, this); + m_gridMain->Connect(EVENT_GRID_CHECK_ROWS, CheckRowsEventHandler (MainDialog::onCheckRows), nullptr, this); + m_gridMain->Connect(EVENT_GRID_SYNC_DIRECTION, SyncDirectionEventHandler(MainDialog::onSetSyncDirection), nullptr, this); //mainly to update row label sizes... updateGui(); //register regular check for update on next idle event - Connect(wxEVT_IDLE, wxIdleEventHandler(MainDialog::OnRegularUpdateCheck), NULL, this); + Connect(wxEVT_IDLE, wxIdleEventHandler(MainDialog::OnRegularUpdateCheck), nullptr, this); //asynchronous call to wxWindow::Layout(): fix superfluous frame on right and bottom when FFS is started in fullscreen mode - Connect(wxEVT_IDLE, wxIdleEventHandler(MainDialog::OnLayoutWindowAsync), NULL, this); + Connect(wxEVT_IDLE, wxIdleEventHandler(MainDialog::OnLayoutWindowAsync), nullptr, this); wxCommandEvent evtDummy; //call once before OnLayoutWindowAsync() OnResizeFolderPairs(evtDummy); // @@ -723,8 +724,7 @@ void MainDialog::init(const xmlAccess::XmlGuiConfig& guiCfg, wait_for_all_timed(dirEx.begin(), dirEx.end(), boost::posix_time::milliseconds(500)); //------------------------------------------------------------------------------------------ - const bool allFoldersExist = std::find_if(dirEx.begin(), dirEx.end(), [](boost::unique_future<bool>& ft) { return !ft.is_ready() || !ft.get(); }) == dirEx.end(); - + const bool allFoldersExist = std::all_of(dirEx.begin(), dirEx.end(), [](boost::unique_future<bool>& ft) { return ft.is_ready() && ft.get(); }); if (allFoldersExist) { wxCommandEvent dummy2(wxEVT_COMMAND_BUTTON_CLICKED); @@ -738,13 +738,13 @@ void MainDialog::init(const xmlAccess::XmlGuiConfig& guiCfg, void MainDialog::readGlobalSettings() { - //apply window size and position at program startup ONLY - //apply window size and position - if (globalSettings->gui.dlgSize.GetWidth () != wxDefaultCoord && - globalSettings->gui.dlgSize.GetHeight() != wxDefaultCoord && - globalSettings->gui.dlgPos.x != wxDefaultCoord && - globalSettings->gui.dlgPos.y != wxDefaultCoord && - wxDisplay::GetFromPoint(globalSettings->gui.dlgPos) != wxNOT_FOUND) //make sure upper left corner is in visible view + //set dialog size and position: test ALL parameters at once, since width/height are invalid if the window is minimized (eg x,y == -32000; height = 28, width = 160) + //note: negative values for x and y are possible when using multiple monitors! + if (globalSettings->gui.dlgSize.GetWidth () > 0 && + globalSettings->gui.dlgSize.GetHeight() > 0 && + globalSettings->gui.dlgPos.x >= -3360 && + globalSettings->gui.dlgPos.y >= -200) + //wxDisplay::GetFromPoint(globalSettings->gui.dlgPos) != wxNOT_FOUND) //make sure upper left corner is in visible view -> not required SetSize(wxRect(globalSettings->gui.dlgPos, globalSettings->gui.dlgSize)); else Centre(); @@ -770,20 +770,7 @@ void MainDialog::readGlobalSettings() *folderHistoryRight = FolderHistory(globalSettings->gui.folderHistoryRight, globalSettings->gui.folderHistMax); //show/hide file icons - const IconBuffer::IconSize sz = [&]() -> IconBuffer::IconSize - { - switch (globalSettings->gui.iconSize) - { - case xmlAccess::ICON_SIZE_SMALL: - return IconBuffer::SIZE_SMALL; - case xmlAccess::ICON_SIZE_MEDIUM: - return IconBuffer::SIZE_MEDIUM; - case xmlAccess::ICON_SIZE_LARGE: - return IconBuffer::SIZE_LARGE; - } - return IconBuffer::SIZE_SMALL; - }(); - gridview::setIconSize(*m_gridMain, sz); + gridview::setupIcons(*m_gridMain, globalSettings->gui.showIcons, convert(globalSettings->gui.iconSize)); //------------------------------------------------------------------------------------------------ //wxAuiManager erroneously loads panel captions, we don't want that @@ -805,7 +792,16 @@ void MainDialog::readGlobalSettings() void MainDialog::writeGlobalSettings() { //write global settings to (global) variable stored in application instance - globalSettings->gui.isMaximized = IsMaximized(); + if (IsIconized()) //we need to (reliably) retrieve non-iconized, non-maximized size and position + Iconize(false); + + globalSettings->gui.isMaximized = IsMaximized(); //evaluate AFTER uniconizing! + + if (IsMaximized()) + Maximize(false); + + globalSettings->gui.dlgSize = GetSize(); + globalSettings->gui.dlgPos = GetPosition(); //retrieve column attributes globalSettings->gui.columnAttribLeft = gridview::convertConfig(m_gridMain->getColumnConfig(gridview::COMP_LEFT)); @@ -909,9 +905,9 @@ void MainDialog::copySelectionToClipboard() vector_remove_if(colAttr, [](const Grid::ColumnAttribute& ca) { return !ca.visible_; }); if (!colAttr.empty()) { - const std::vector<int> selection = m_gridMain->getSelectedRows(compPos); + const std::vector<size_t> selection = m_gridMain->getSelectedRows(compPos); std::for_each(selection.begin(), selection.end(), - [&](int row) + [&](size_t row) { std::for_each(colAttr.begin(), colAttr.end() - 1, [&](const Grid::ColumnAttribute& ca) @@ -945,7 +941,7 @@ std::vector<FileSystemObject*> MainDialog::getGridSelection(bool fromLeft, bool auto addSelection = [&](size_t compPos) { - const std::vector<int>& sel = m_gridMain->getSelectedRows(compPos); + const std::vector<size_t>& sel = m_gridMain->getSelectedRows(compPos); selectedRows.insert(sel.begin(), sel.end()); }; @@ -963,11 +959,11 @@ std::vector<FileSystemObject*> MainDialog::getGridSelection(bool fromLeft, bool std::vector<FileSystemObject*> MainDialog::getTreeSelection() const { - const std::vector<int>& sel = m_gridNavi->getSelectedRows(); + const std::vector<size_t>& sel = m_gridNavi->getSelectedRows(); std::vector<FileSystemObject*> output; std::for_each(sel.begin(), sel.end(), - [&](int row) + [&](size_t row) { if (std::unique_ptr<TreeView::Node> node = treeDataView->getLine(row)) { @@ -1004,15 +1000,15 @@ public: mainDlg->clearStatusBar(); //register abort button - mainDlg->m_buttonAbort->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ManualDeletionHandler::OnAbortDeletion), NULL, this ); - mainDlg->Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(ManualDeletionHandler::OnKeyPressed), NULL, this); + mainDlg->m_buttonAbort->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ManualDeletionHandler::OnAbortDeletion), nullptr, this ); + mainDlg->Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(ManualDeletionHandler::OnKeyPressed), nullptr, this); } ~ManualDeletionHandler() { //de-register abort button - mainDlg->Disconnect(wxEVT_CHAR_HOOK, wxKeyEventHandler(ManualDeletionHandler::OnKeyPressed), NULL, this); - mainDlg->m_buttonAbort->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ManualDeletionHandler::OnAbortDeletion ), NULL, this ); + mainDlg->Disconnect(wxEVT_CHAR_HOOK, wxKeyEventHandler(ManualDeletionHandler::OnKeyPressed), nullptr, this); + mainDlg->m_buttonAbort->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ManualDeletionHandler::OnAbortDeletion ), nullptr, this ); mainDlg->enableAllElements(); } @@ -1096,7 +1092,7 @@ void MainDialog::deleteSelectedFiles(const std::vector<FileSystemObject*>& selec if (!selectionLeft.empty() || !selectionRight.empty()) { wxWindow* oldFocus = wxWindow::FindFocus(); - ZEN_ON_BLOCK_EXIT( if (oldFocus) oldFocus->SetFocus(); ) + ZEN_ON_SCOPE_EXIT( if (oldFocus) oldFocus->SetFocus(); ) if (zen::showDeleteDialog(selectionLeft, selectionRight, @@ -1307,27 +1303,6 @@ void MainDialog::enableAllElements() } -void MainDialog::OnResize(wxSizeEvent& event) -{ - if (!IsMaximized()) - { - wxSize sz = GetSize(); - wxPoint ps = GetPosition(); - - //test ALL parameters at once, since width/height are invalid if the window is minimized (eg x,y == -32000; height = 28, width = 160) - //note: negative values for x and y are possible when using multiple monitors! - if (sz.GetWidth() > 0 && sz.GetHeight() > 0 && ps.x >= -3360 && ps.y >= -200 && - wxDisplay::GetFromPoint(ps) != wxNOT_FOUND) //make sure upper left corner is in visible view - { - globalSettings->gui.dlgSize = sz; - globalSettings->gui.dlgPos = ps; - } - } - - event.Skip(); -} - - namespace { void updateSizerOrientation(wxBoxSizer& sizer, wxWindow& window) @@ -1515,7 +1490,7 @@ void MainDialog::onGridButtonEvent(wxKeyEvent& event) { const wxString commandline = globalSettings->gui.externelApplications[0].second; //open with first external application auto cursorPos = m_gridMain->getGridCursor(); - const int row = cursorPos.first; + const size_t row = cursorPos.first; const size_t compPos = cursorPos.second; openExternalApplication(gridDataView->getObject(row), compPos == gridview::COMP_LEFT, commandline); } @@ -1528,8 +1503,8 @@ void MainDialog::onGridButtonEvent(wxKeyEvent& event) bool isPartOf(const wxWindow* child, const wxWindow* top) { - for (const wxWindow* i = child; i != NULL; i = i->GetParent()) - if (i == top) + for (const wxWindow* wnd = child; wnd != nullptr; wnd = wnd->GetParent()) + if (wnd == top) return true; return false; } @@ -1550,7 +1525,7 @@ void MainDialog::OnGlobalKeyEvent(wxKeyEvent& event) //process key events withou } processingGlobalKeyEvent = true; - ZEN_ON_BLOCK_EXIT(processingGlobalKeyEvent = false;) + ZEN_ON_SCOPE_EXIT(processingGlobalKeyEvent = false;) //---------------------------------------------------- const int keyCode = event.GetKeyCode(); @@ -1571,6 +1546,10 @@ void MainDialog::OnGlobalKeyEvent(wxKeyEvent& event) //process key events withou zen::findNext(*this, *m_gridMain, gridview::COMP_LEFT, gridview::COMP_RIGHT, globalSettings->gui.textSearchRespectCase); return; //-> swallow event! + case WXK_F8: //F8 + enablePreview(!syncPreviewEnabled); + return; //-> swallow event! + //redirect certain (unhandled) keys directly to grid! case WXK_UP: case WXK_DOWN: @@ -1636,9 +1615,9 @@ void MainDialog::onNaviSelection(GridRangeSelectEvent& event) std::vector<const HierarchyObject*> markedFiles; //mark files/symlinks directly within a container std::vector<const HierarchyObject*> markedContainer; //mark full container including child-objects - const std::vector<int>& selection = m_gridNavi->getSelectedRows(); + const std::vector<size_t>& selection = m_gridNavi->getSelectedRows(); std::for_each(selection.begin(), selection.end(), - [&](int row) + [&](size_t row) { if (std::unique_ptr<TreeView::Node> node = treeDataView->getLine(row)) { @@ -1665,12 +1644,12 @@ void MainDialog::onNaviGridContext(GridClickEvent& event) //---------------------------------------------------------------------------------------------------- if (syncPreviewEnabled && !selection.empty()) - //std::find_if(selection.begin(), selection.end(), [](const FileSystemObject* fsObj){ return fsObj->getSyncOperation() != SO_EQUAL; }) != selection.end()) -> doesn't consider directories + //std::any_of(selection.begin(), selection.end(), [](const FileSystemObject* fsObj){ return fsObj->getSyncOperation() != SO_EQUAL; })) -> doesn't consider directories { auto getImage = [&](SyncDirection dir, SyncOperation soDefault) { return mirrorIfRtl(getSyncOpImage(selection[0]->getSyncOperation() != SO_EQUAL ? - selection[0]->testSyncOperation(dir, true) : soDefault)); + selection[0]->testSyncOperation(dir) : soDefault)); }; const wxBitmap opRight = getImage(SYNC_DIR_RIGHT, SO_OVERWRITE_RIGHT); const wxBitmap opNone = getImage(SYNC_DIR_NONE, SO_DO_NOTHING ); @@ -1697,23 +1676,23 @@ void MainDialog::onNaviGridContext(GridClickEvent& event) menu.addItem(_("Include temporarily") + L"\tSpace", [this, &selection] { setManualFilter(selection, true); }, &GlobalResources::getImage(L"checkboxTrue")); } else - menu.addItem(_("Exclude temporarily") + L"\tSpace", [] {}, NULL, false); + menu.addItem(_("Exclude temporarily") + L"\tSpace", [] {}, nullptr, false); //---------------------------------------------------------------------------------------------------- //CONTEXT_EXCLUDE_OBJ if (selection.size() == 1) menu.addItem(_("Exclude via filter:") + L" " + afterLast(selection[0]->getObjRelativeName(), FILE_NAME_SEPARATOR), [this, &selection] { excludeItems(selection); }, - &GlobalResources::getImage(L"filterSmall")); + &GlobalResources::getImage(L"filterOnSmall")); else if (selection.size() > 1) menu.addItem(_("Exclude via filter:") + L" " + _("<multiple selection>"), [this, &selection] { excludeItems(selection); }, - &GlobalResources::getImage(L"filterSmall")); + &GlobalResources::getImage(L"filterOnSmall")); //---------------------------------------------------------------------------------------------------- //CONTEXT_DELETE_FILES menu.addSeparator(); - menu.addItem(_("Delete") + L"\tDel", [&] { deleteSelectedFiles(selection, selection); }, NULL, !selection.empty()); + menu.addItem(_("Delete") + L"\tDel", [&] { deleteSelectedFiles(selection, selection); }, nullptr, !selection.empty()); menu.popup(*this); } @@ -1734,7 +1713,7 @@ void MainDialog::onMainGridContext(GridClickEvent& event) auto getImage = [&](SyncDirection dir, SyncOperation soDefault) { return mirrorIfRtl(getSyncOpImage(selection[0]->getSyncOperation() != SO_EQUAL ? - selection[0]->testSyncOperation(dir, true) : soDefault)); + selection[0]->testSyncOperation(dir) : soDefault)); }; const wxBitmap opRight = getImage(SYNC_DIR_RIGHT, SO_OVERWRITE_RIGHT); const wxBitmap opNone = getImage(SYNC_DIR_NONE, SO_DO_NOTHING ); @@ -1761,12 +1740,12 @@ void MainDialog::onMainGridContext(GridClickEvent& event) menu.addItem(_("Include temporarily") + L"\tSpace", [this, &selection] { setManualFilter(selection, true); }, &GlobalResources::getImage(L"checkboxTrue")); } else - menu.addItem(_("Exclude temporarily") + L"\tSpace", [] {}, NULL, false); + menu.addItem(_("Exclude temporarily") + L"\tSpace", [] {}, nullptr, false); //---------------------------------------------------------------------------------------------------- //CONTEXT_EXCLUDE_EXT if (!selection.empty() && - dynamic_cast<const DirMapping*>(selection[0]) == NULL) //non empty && no directory + dynamic_cast<const DirMapping*>(selection[0]) == nullptr) //non empty && no directory { const Zstring filename = afterLast(selection[0]->getObjRelativeName(), FILE_NAME_SEPARATOR); if (filename.find(Zchar('.')) != Zstring::npos) //be careful: AfterLast would return the whole string if '.' were not found! @@ -1775,7 +1754,7 @@ void MainDialog::onMainGridContext(GridClickEvent& event) menu.addItem(_("Exclude via filter:") + L" *." + extension, [this, extension] { excludeExtension(extension); }, - &GlobalResources::getImage(L"filterSmall")); + &GlobalResources::getImage(L"filterOnSmall")); } } //---------------------------------------------------------------------------------------------------- @@ -1783,11 +1762,11 @@ void MainDialog::onMainGridContext(GridClickEvent& event) if (selection.size() == 1) menu.addItem(_("Exclude via filter:") + L" " + afterLast(selection[0]->getObjRelativeName(), FILE_NAME_SEPARATOR), [this, &selection] { excludeItems(selection); }, - &GlobalResources::getImage(L"filterSmall")); + &GlobalResources::getImage(L"filterOnSmall")); else if (selection.size() > 1) menu.addItem(_("Exclude via filter:") + L" " + _("<multiple selection>"), [this, &selection] { excludeItems(selection); }, - &GlobalResources::getImage(L"filterSmall")); + &GlobalResources::getImage(L"filterOnSmall")); //---------------------------------------------------------------------------------------------------- //CONTEXT_EXTERNAL_APP @@ -1806,12 +1785,12 @@ void MainDialog::onMainGridContext(GridClickEvent& event) const wxString command = iter->second; - auto openApp = [this, &selection, command, event] { openExternalApplication(selection.empty() ? NULL : selection[0], event.compPos_ == gridview::COMP_LEFT, command); }; + auto openApp = [this, &selection, command, event] { openExternalApplication(selection.empty() ? nullptr : selection[0], event.compPos_ == gridview::COMP_LEFT, command); }; if (iter == globalSettings->gui.externelApplications.begin()) menu.addItem(description + L"\tEnter", openApp); else - menu.addItem(description, openApp, NULL, !selection.empty()); + menu.addItem(description, openApp, nullptr, !selection.empty()); } } //---------------------------------------------------------------------------------------------------- @@ -1823,7 +1802,7 @@ void MainDialog::onMainGridContext(GridClickEvent& event) deleteSelectedFiles( getGridSelection(true, false), getGridSelection(false, true)); - }, NULL, !selection.empty()); + }, nullptr, !selection.empty()); } else if (event.compPos_ == gridview::COMP_MIDDLE) @@ -1832,13 +1811,13 @@ void MainDialog::onMainGridContext(GridClickEvent& event) { zen::setActiveStatus(true, folderCmp); updateGui(); - }, NULL, gridDataView->rowsTotal() > 0); + }, nullptr, gridDataView->rowsTotal() > 0); menu.addItem(_("Exclude all"), [&] { zen::setActiveStatus(false, folderCmp); updateGuiAfterFilterChange(400); //call this instead of updateGuiGrid() to add some delay if hideFiltered == true - }, NULL, gridDataView->rowsTotal() > 0); + }, nullptr, gridDataView->rowsTotal() > 0); } menu.popup(*this); } @@ -1873,12 +1852,14 @@ void MainDialog::excludeItems(const std::vector<FileSystemObject*>& selection) for (auto iter = selection.begin(); iter != selection.end(); ++iter) { FileSystemObject* fsObj = *iter; - const bool isDir = dynamic_cast<const DirMapping*>(fsObj) != NULL; if (iter != selection.begin()) newExclude += Zstr("\n"); + //#pragma warning(suppress: 6011) -> fsObj cannot be NULL here! newExclude += FILE_NAME_SEPARATOR + fsObj->getObjRelativeName(); + + const bool isDir = dynamic_cast<const DirMapping*>(fsObj) != nullptr; if (isDir) newExclude += FILE_NAME_SEPARATOR; } @@ -1944,22 +1925,27 @@ void MainDialog::onGridLabelContext(GridClickEvent& event) }; menu.addItem(_("&Default"), setDefault); //'&' -> reuse text from "default" buttons elsewhere //---------------------------------------------------------------------------------------------- - auto setIconSize = [&](xmlAccess::FileIconSize sz, IconBuffer::IconSize szAlias) + menu.addSeparator(); + menu.addCheckBox(_("Show icons:"), [&] + { + globalSettings->gui.showIcons = !globalSettings->gui.showIcons; + gridview::setupIcons(*m_gridMain, globalSettings->gui.showIcons, convert(globalSettings->gui.iconSize)); + + }, globalSettings->gui.showIcons); + + auto setIconSize = [&](xmlAccess::FileIconSize sz) { globalSettings->gui.iconSize = sz; - gridview::setIconSize(*m_gridMain, szAlias); + gridview::setupIcons(*m_gridMain, globalSettings->gui.showIcons, convert(sz)); }; - menu.addSeparator(); - menu.addItem(_("Icon size:"), [] {}, NULL, false); - - auto addSizeEntry = [&](const wxString& label, xmlAccess::FileIconSize sz, IconBuffer::IconSize szAlias) + auto addSizeEntry = [&](const wxString& label, xmlAccess::FileIconSize sz) { auto setIconSize2 = setIconSize; //bring into scope - menu.addRadio(label, [sz, szAlias, setIconSize2] { setIconSize2(sz, szAlias); }, globalSettings->gui.iconSize == sz); + menu.addRadio(label, [sz, setIconSize2] { setIconSize2(sz); }, globalSettings->gui.iconSize == sz, globalSettings->gui.showIcons); }; - addSizeEntry(_("Small" ), xmlAccess::ICON_SIZE_SMALL , IconBuffer::SIZE_SMALL); - addSizeEntry(_("Medium"), xmlAccess::ICON_SIZE_MEDIUM, IconBuffer::SIZE_MEDIUM); - addSizeEntry(_("Large" ), xmlAccess::ICON_SIZE_LARGE , IconBuffer::SIZE_LARGE); + addSizeEntry(L" " + _("Small" ), xmlAccess::ICON_SIZE_SMALL ); + addSizeEntry(L" " + _("Medium"), xmlAccess::ICON_SIZE_MEDIUM); + addSizeEntry(L" " + _("Large" ), xmlAccess::ICON_SIZE_LARGE ); //---------------------------------------------------------------------------------------------- if (static_cast<ColumnTypeRim>(event.colType_) == COL_TYPE_DATE) { @@ -1979,8 +1965,8 @@ void MainDialog::onGridLabelContext(GridClickEvent& event) else if (event.compPos_ == gridview::COMP_MIDDLE) { - menu.addItem(_("Synchronization Preview"), [&] { enablePreview(true ); }, syncPreviewEnabled ? &GlobalResources::getImage(L"syncViewSmall") : NULL); - menu.addItem(_("Comparison Result"), [&] { enablePreview(false); }, syncPreviewEnabled ? NULL : &GlobalResources::getImage(L"cmpViewSmall")); + menu.addItem(_("Synchronization Preview") + L"\tF8", [&] { enablePreview(true ); }, syncPreviewEnabled ? &GlobalResources::getImage(L"syncSmall") : nullptr); + menu.addItem(_("Comparison Result"), [&] { enablePreview(false); }, syncPreviewEnabled ? nullptr : &GlobalResources::getImage(L"compareSmall")); } menu.popup(*this); } @@ -2182,7 +2168,7 @@ void MainDialog::addFileToCfgHistory(const std::vector<wxString>& filenames) void MainDialog::OnSaveConfig(wxCommandEvent& event) { - trySaveConfig(NULL); + trySaveConfig(nullptr); } @@ -2297,20 +2283,22 @@ bool MainDialog::saveOldConfig() //return false on user abort { const wxString filename = activeConfigFiles[0]; - bool dontShowAgain = !globalSettings->optDialogs.popupOnConfigChange; + bool neverSave = !globalSettings->optDialogs.popupOnConfigChange; + CheckBox cb(_("Never save changes"), neverSave); switch (showQuestionDlg(ReturnQuestionDlg::BUTTON_YES | ReturnQuestionDlg::BUTTON_NO | ReturnQuestionDlg::BUTTON_CANCEL, - _("Save changes to current configuration?"), - &dontShowAgain)) + _("Save changes to current configuration?"), &cb)) { case ReturnQuestionDlg::BUTTON_YES: - return trySaveConfig(endsWith(filename, L".ffs_gui") ? &filename : NULL); //don't overwrite .ffs_batch! + return trySaveConfig(endsWith(filename, L".ffs_gui") ? &filename : nullptr); //don't overwrite .ffs_batch! + case ReturnQuestionDlg::BUTTON_NO: - globalSettings->optDialogs.popupOnConfigChange = !dontShowAgain; + globalSettings->optDialogs.popupOnConfigChange = !neverSave; //by choosing "no" user actively discards current config selection //this ensures next app start will load <last session> instead of the original non-modified config selection setLastUsedConfig(std::vector<wxString>(), getConfig()); break; + case ReturnQuestionDlg::BUTTON_CANCEL: return false; } @@ -2623,7 +2611,7 @@ void MainDialog::OnGlobalFilterContext(wxCommandEvent& event) updateFilterButtons(); //refresh global filter icon applyFilterConfig(); //re-apply filter }; - menu.addItem( _("Clear filter settings"), clearFilter, NULL, !isNullFilter(currentCfg.mainCfg.globalFilter)); + menu.addItem( _("Clear filter settings"), clearFilter, nullptr, !isNullFilter(currentCfg.mainCfg.globalFilter)); menu.popup(*this); } @@ -2875,8 +2863,11 @@ void MainDialog::OnCompare(wxCommandEvent& event) wxBusyCursor dummy; //show hourglass cursor - clearGrid(false); //-> don't resize grid to keep scroll position! - //prevent temporary memory peak by clearing old result list + int scrollPosX = 0; + int scrollPosY = 0; + m_gridMain->GetViewStart(&scrollPosX, &scrollPosY); //preserve current scroll position + + clearGrid(false); //avoid memory peak by clearing old data try { @@ -2916,8 +2907,9 @@ void MainDialog::OnCompare(wxCommandEvent& event) } gridDataView->setData(folderCmp); //update view on data - treeDataView->setData(folderCmp); // + treeDataView->setData(folderCmp); // updateGui(); + m_gridMain->Scroll(scrollPosX, scrollPosY); //restore updateSyncEnabledStatus(); //enable the sync button if (m_buttonStartSync->IsShownOnScreen()) @@ -2976,12 +2968,6 @@ void MainDialog::updateStatistics() } -//void MainDialog::OnSwitchView(wxCommandEvent& event) -//{ -// enablePreview(!syncPreviewEnabled); -//} - - void MainDialog::OnSyncSettings(wxCommandEvent& event) { ExecWhenFinishedCfg ewfCfg = { ¤tCfg.mainCfg.onCompletion, @@ -3502,8 +3488,8 @@ void MainDialog::updateGuiForFolderPair() //adapt local filter and sync cfg for first folder pair if (additionalFolderPairs.empty() && - firstFolderPair->getAltCompConfig().get() == NULL && - firstFolderPair->getAltSyncConfig().get() == NULL && + firstFolderPair->getAltCompConfig().get() == nullptr && + firstFolderPair->getAltSyncConfig().get() == nullptr && isNullFilter(firstFolderPair->getAltFilterConfig())) { m_bpButtonAltCompCfg ->Hide(); @@ -3592,7 +3578,7 @@ void MainDialog::addFolderPair(const std::vector<FolderPairEnh>& newPairs, bool newEntries.push_back(newPair); //register events - newPair->m_bpButtonRemovePair->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainDialog::OnRemoveFolderPair), NULL, this); + newPair->m_bpButtonRemovePair->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainDialog::OnRemoveFolderPair), nullptr, this); }); //wxComboBox screws up miserably if width/height is smaller than the magic number 4! Problem occurs when trying to set tooltip @@ -3819,12 +3805,11 @@ void MainDialog::OnMenuBatchJob(wxCommandEvent& event) const xmlAccess::XmlBatchConfig batchCfg = convertGuiToBatch(currCfg, referenceFile); - if (showSyncBatchDlg(referenceFile, batchCfg, - folderHistoryLeft, - folderHistoryRight, - globalSettings->gui.onCompletionHistory, - globalSettings->gui.onCompletionHistoryMax) == ReturnBatchConfig::BATCH_FILE_SAVED) - pushStatusInformation(_("Batch file created successfully!")); + showSyncBatchDlg(referenceFile, batchCfg, + folderHistoryLeft, + folderHistoryRight, + globalSettings->gui.onCompletionHistory, + globalSettings->gui.onCompletionHistoryMax); } @@ -3837,7 +3822,7 @@ void MainDialog::OnMenuCheckVersion(wxCommandEvent& event) void MainDialog::OnRegularUpdateCheck(wxIdleEvent& event) { //execute just once per startup! - Disconnect(wxEVT_IDLE, wxIdleEventHandler(MainDialog::OnRegularUpdateCheck), NULL, this); + Disconnect(wxEVT_IDLE, wxIdleEventHandler(MainDialog::OnRegularUpdateCheck), nullptr, this); zen::checkForUpdatePeriodically(globalSettings->gui.lastUpdateCheck); } @@ -3846,7 +3831,7 @@ void MainDialog::OnRegularUpdateCheck(wxIdleEvent& event) void MainDialog::OnLayoutWindowAsync(wxIdleEvent& event) { //execute just once per startup! - Disconnect(wxEVT_IDLE, wxIdleEventHandler(MainDialog::OnLayoutWindowAsync), NULL, this); + Disconnect(wxEVT_IDLE, wxIdleEventHandler(MainDialog::OnLayoutWindowAsync), nullptr, this); wxWindowUpdateLocker dummy(this); //avoid display distortion diff --git a/ui/main_dlg.h b/ui/main_dlg.h index c13887ed..228cef4a 100644 --- a/ui/main_dlg.h +++ b/ui/main_dlg.h @@ -168,7 +168,6 @@ private: void OnRegularUpdateCheck( wxIdleEvent& event); void OnLayoutWindowAsync( wxIdleEvent& event); - void OnResize( wxSizeEvent& event); void OnResizeFolderPairs( wxEvent& event); void OnResizeConfigPanel( wxEvent& event); void OnResizeViewPanel( wxEvent& event); diff --git a/ui/msg_popup.cpp b/ui/msg_popup.cpp index e86b6cf2..1ed892f8 100644 --- a/ui/msg_popup.cpp +++ b/ui/msg_popup.cpp @@ -98,7 +98,7 @@ void ErrorDlg::OnAbort(wxCommandEvent& event) ReturnErrorDlg::ButtonPressed zen::showErrorDlg(int activeButtons, const wxString& messageText, bool* ignoreNextErrors) { - ErrorDlg errorDlg(NULL, activeButtons, messageText, ignoreNextErrors); + ErrorDlg errorDlg(nullptr, activeButtons, messageText, ignoreNextErrors); errorDlg.Raise(); return static_cast<ReturnErrorDlg::ButtonPressed>(errorDlg.ShowModal()); } @@ -180,7 +180,7 @@ void WarningDlg::OnAbort(wxCommandEvent& event) ReturnWarningDlg::ButtonPressed zen::showWarningDlg(int activeButtons, const wxString& messageText, bool& dontShowAgain) { - WarningDlg warningDlg(NULL, activeButtons, messageText, dontShowAgain); + WarningDlg warningDlg(nullptr, activeButtons, messageText, dontShowAgain); warningDlg.Raise(); return static_cast<ReturnWarningDlg::ButtonPressed>(warningDlg.ShowModal()); } @@ -190,42 +190,42 @@ ReturnWarningDlg::ButtonPressed zen::showWarningDlg(int activeButtons, const wxS class QuestionDlg : public QuestionDlgGenerated { public: - QuestionDlg(wxWindow* parentWindow, int activeButtons, const wxString& messageText, bool* dontShowAgain = NULL); + QuestionDlg(wxWindow* parentWindow, int activeButtons, const wxString& messageText, CheckBox* checkbox); private: - void OnClose(wxCloseEvent& event); - void OnCancel(wxCommandEvent& event); + void OnClose (wxCloseEvent& event) { EndModal(ReturnQuestionDlg::BUTTON_CANCEL); } + void OnCancel(wxCommandEvent& event) { EndModal(ReturnQuestionDlg::BUTTON_CANCEL); } void OnYes(wxCommandEvent& event); - void OnNo(wxCommandEvent& event); - void OnCheckBoxDontShowAgain(wxCommandEvent& event); + void OnNo (wxCommandEvent& event); - bool* dontShowAgain; //optional + CheckBox* checkbox_; //optional }; -QuestionDlg::QuestionDlg(wxWindow* parentWindow, int activeButtons, const wxString& messageText, bool* dontShowDlgAgain) : +QuestionDlg::QuestionDlg(wxWindow* parentWindow, int activeButtons, const wxString& messageText, CheckBox* checkbox) : QuestionDlgGenerated(parentWindow), - dontShowAgain(dontShowDlgAgain) + checkbox_(checkbox) { #ifdef FFS_WIN new zen::MouseMoveWindow(*this); //allow moving main dialog by clicking (nearly) anywhere...; ownership passed to "this" #endif - m_bitmap10->SetBitmap(GlobalResources::getImage(wxT("question"))); + m_bitmap10->SetBitmap(GlobalResources::getImage(L"question")); m_textCtrl8->SetValue(messageText); - if (dontShowAgain) - m_checkBoxDontAskAgain->SetValue(*dontShowAgain); + + if (checkbox_) + { + m_checkBox->SetValue(checkbox_->value_); + m_checkBox->SetLabel(checkbox_->label_); + } else - m_checkBoxDontAskAgain->Hide(); + m_checkBox->Hide(); if (~activeButtons & ReturnQuestionDlg::BUTTON_YES) m_buttonYes->Hide(); if (~activeButtons & ReturnQuestionDlg::BUTTON_NO) - { m_buttonNo->Hide(); - m_checkBoxDontAskAgain->Hide(); - } if (~activeButtons & ReturnQuestionDlg::BUTTON_CANCEL) m_buttonCancel->Hide(); @@ -239,42 +239,23 @@ QuestionDlg::QuestionDlg(wxWindow* parentWindow, int activeButtons, const wxStri m_buttonNo->SetFocus(); } - -void QuestionDlg::OnClose(wxCloseEvent& event) -{ - EndModal(ReturnQuestionDlg::BUTTON_CANCEL); -} - - -void QuestionDlg::OnCancel(wxCommandEvent& event) -{ - EndModal(ReturnQuestionDlg::BUTTON_CANCEL); -} - - void QuestionDlg::OnYes(wxCommandEvent& event) { - if (dontShowAgain) - *dontShowAgain = m_checkBoxDontAskAgain->GetValue(); + if (checkbox_) + checkbox_->value_ = m_checkBox->GetValue(); EndModal(ReturnQuestionDlg::BUTTON_YES); } void QuestionDlg::OnNo(wxCommandEvent& event) { - if (dontShowAgain) - *dontShowAgain = m_checkBoxDontAskAgain->GetValue(); + if (checkbox_) + checkbox_->value_ = m_checkBox->GetValue(); EndModal(ReturnQuestionDlg::BUTTON_NO); } -void QuestionDlg::OnCheckBoxDontShowAgain(wxCommandEvent& event) -{ - event.Skip(); -} - - -ReturnQuestionDlg::ButtonPressed zen::showQuestionDlg(int activeButtons, const wxString& messageText, bool* dontShowAgain) +ReturnQuestionDlg::ButtonPressed zen::showQuestionDlg(int activeButtons, const wxString& messageText, CheckBox* checkbox) { - QuestionDlg qtnDlg(NULL, activeButtons, messageText, dontShowAgain); + QuestionDlg qtnDlg(nullptr, activeButtons, messageText, checkbox); qtnDlg.Raise(); return static_cast<ReturnQuestionDlg::ButtonPressed>(qtnDlg.ShowModal()); } diff --git a/ui/msg_popup.h b/ui/msg_popup.h index 29606a41..ccdf09e4 100644 --- a/ui/msg_popup.h +++ b/ui/msg_popup.h @@ -20,7 +20,7 @@ struct ReturnErrorDlg BUTTON_ABORT = 4 }; }; -ReturnErrorDlg::ButtonPressed showErrorDlg(int activeButtons, const wxString& messageText, bool* ignoreNextErrors); //ignoreNextErrors may be NULL +ReturnErrorDlg::ButtonPressed showErrorDlg(int activeButtons, const wxString& messageText, bool* ignoreNextErrors); //ignoreNextErrors may be nullptr struct ReturnWarningDlg @@ -44,7 +44,16 @@ struct ReturnQuestionDlg BUTTON_CANCEL = 4 }; }; -ReturnQuestionDlg::ButtonPressed showQuestionDlg(int activeButtons, const wxString& messageText, bool* dontShowAgain = NULL); + +struct CheckBox +{ + CheckBox(const wxString& label, bool& value) : label_(label), value_(value) {} + + wxString label_; //in + bool& value_; //in/out +}; + +ReturnQuestionDlg::ButtonPressed showQuestionDlg(int activeButtons, const wxString& messageText, CheckBox* checkbox = nullptr); } diff --git a/ui/progress_indicator.cpp b/ui/progress_indicator.cpp index ee24b28b..1e4be39a 100644 --- a/ui/progress_indicator.cpp +++ b/ui/progress_indicator.cpp @@ -19,7 +19,6 @@ #include <wx+/no_flicker.h> #include "gui_generated.h" #include "../lib/resources.h" -#include "../lib/error_log.h" #include "../lib/statistics.h" #include "tray_icon.h" #include "taskbar.h" @@ -394,11 +393,11 @@ wxBitmap buttonReleased(const std::string& name) class LogControl : public LogControlGenerated { public: - LogControl(wxWindow* parent, const ErrorLogging& log) : LogControlGenerated(parent), log_(log) + LogControl(wxWindow* parent, const ErrorLog& log) : LogControlGenerated(parent), log_(log) { - const int errorCount = log_.typeCount(TYPE_ERROR | TYPE_FATAL_ERROR); - const int warningCount = log_.typeCount(TYPE_WARNING); - const int infoCount = log_.typeCount(TYPE_INFO); + const int errorCount = log_.getItemCount(TYPE_ERROR | TYPE_FATAL_ERROR); + const int warningCount = log_.getItemCount(TYPE_WARNING); + const int infoCount = log_.getItemCount(TYPE_INFO); m_bpButtonErrors->init(buttonPressed ("error"), wxString(_("Error")) + wxString::Format(wxT(" (%d)"), errorCount), buttonReleased("error"), wxString(_("Error")) + wxString::Format(wxT(" (%d)"), errorCount)); @@ -419,7 +418,7 @@ public: updateLogText(); - m_textCtrlInfo->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(LogControl::onKeyEvent), NULL, this); + m_textCtrlInfo->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(LogControl::onKeyEvent), nullptr, this); } virtual void OnErrors(wxCommandEvent& event) @@ -467,32 +466,28 @@ private: if (m_bpButtonInfo->isActive()) includedTypes |= TYPE_INFO; - const std::vector<wxString>& messages = log_.getFormattedMessages(includedTypes); - //fast replacement for wxString modelling exponential growth typedef Zbase<wchar_t> zxString; + zxString logText; - zxString newLogText; //perf: wxString doesn't model exponential growth and so is out - - if (!messages.empty()) - for (std::vector<wxString>::const_iterator i = messages.begin(); i != messages.end(); ++i) + const auto& entries = log_.getEntries(); + for (auto iter = entries.begin(); iter != entries.end(); ++iter) + if (iter->type & includedTypes) { - newLogText += copyStringTo<zxString>(*i); - newLogText += wxT("\n"); + logText += copyStringTo<zxString>(formatMessage(*iter)); + logText += L'\n'; } - else //if no messages match selected view filter, show final status message at least - { - const std::vector<wxString>& allMessages = log_.getFormattedMessages(); - if (!allMessages.empty()) - newLogText = copyStringTo<zxString>(allMessages.back()); - } + + if (logText.empty()) //if no messages match selected view filter, show final status message at least + if (!entries.empty()) + logText = copyStringTo<zxString>(formatMessage(entries.back())); wxWindowUpdateLocker dummy(m_textCtrlInfo); - m_textCtrlInfo->ChangeValue(copyStringTo<wxString>(newLogText)); + m_textCtrlInfo->ChangeValue(copyStringTo<wxString>(logText)); m_textCtrlInfo->ShowPosition(m_textCtrlInfo->GetLastPosition()); } - const ErrorLogging log_; + const ErrorLog log_; }; @@ -589,15 +584,20 @@ struct LabelFormatterTimeElapsed : public LabelFormatter { if (secProposed <= 10) return 10; //minimum block size - if (secProposed <= 20) //avoid flicker between 10<->15<->20 sec blocks return bestFit(secProposed, 10, 20); + if (secProposed <= 30) + return bestFit(secProposed, 20, 30); + if (secProposed <= 60) + return bestFit(secProposed, 30, 60); - //for seconds and minutes: nice numbers are 1, 5, 10, 15, 20, 30 + //for minutes: nice numbers are 1, 2, 5, 10, 15, 20, 30 auto calcBlock = [](double val) -> double { + if (val <= 2) + return bestFit(val, 1, 2); // if (val <= 5) - return bestFit(val, 1, 5); // + return bestFit(val, 2, 5); // if (val <= 10) return bestFit(val, 5, 10); // a good candidate for a variadic template! if (val <= 15) @@ -608,15 +608,13 @@ struct LabelFormatterTimeElapsed : public LabelFormatter return bestFit(val, 20, 30); return bestFit(val, 30, 60); }; - - if (secProposed <= 60) - return calcBlock(secProposed); - else if (secProposed <= 3600) + if (secProposed <= 3600) return calcBlock(secProposed / 60) * 60; - else if (secProposed <= 3600 * 24) + + if (secProposed <= 3600 * 24) return nextNiceNumber(secProposed / 3600) * 3600; - else - return nextNiceNumber(secProposed / (24 * 3600)) * 24 * 3600; //round up to full days + + return nextNiceNumber(secProposed / (24 * 3600)) * 24 * 3600; //round up to full days } virtual wxString formatText(double timeElapsed, double optimalBlockSize) const @@ -662,7 +660,7 @@ public: void setStatusText_NoUpdate(const wxString& text); void updateStatusDialogNow(bool allowYield = true); - void processHasFinished(SyncStatus::SyncStatusID id, const ErrorLogging& log); //essential to call this in StatusUpdater derived class destructor at the LATEST(!) to prevent access to currentStatusUpdater + void processHasFinished(SyncStatus::SyncStatusID id, const ErrorLog& log); //essential to call this in StatusUpdater derived class destructor at the LATEST(!) to prevent access to currentStatusUpdater std::wstring getExecWhenFinishedCommand() const; @@ -776,20 +774,20 @@ SyncStatus::SyncStatusImpl::SyncStatusImpl(AbortCallback& abortCb, try //try to get access to Windows 7/Ubuntu taskbar { - taskbar_.reset(new Taskbar(mainDialog != NULL ? *static_cast<wxTopLevelWindow*>(mainDialog) : *this)); + taskbar_.reset(new Taskbar(mainDialog ? *static_cast<wxTopLevelWindow*>(mainDialog) : *this)); } catch (const TaskbarNotAvailable&) {} //hide "processed" statistics until end of process - bSizerFinalStat ->Show(false); - m_buttonOK ->Show(false); - m_staticTextItemsProc->Show(false); - bSizerItemsProc ->Show(false); + bSizerFinalStat ->Show(false); + m_buttonOK ->Show(false); + m_staticTextLabelItemsProc->Show(false); + bSizerItemsProc ->Show(false); SetIcon(GlobalResources::instance().programIcon); //set application icon //register key event - Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(SyncStatusImpl::OnKeyPressed), NULL, this); + Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(SyncStatusImpl::OnKeyPressed), nullptr, this); setCurrentStatus(startStatus); //first state: will be shown while waiting for dir locks (if at all) @@ -919,7 +917,7 @@ void SyncStatus::SyncStatusImpl::showProgressExternally(const wxString& progress { //write status information to systray, if window is minimized if (trayIcon.get()) - trayIcon->setToolTip2(progressText, fraction); + trayIcon->setToolTip(progressText, fraction); wxString progressTextFmt = progressText; progressTextFmt.Replace(wxT("\n"), wxT(" - ")); @@ -1123,7 +1121,6 @@ void SyncStatus::SyncStatusImpl::updateStatusDialogNow(bool allowYield) if (evaluateZorder(*this, *mainDialog) == ZORDER_WRONG) { HWND hProgress = static_cast<HWND>(GetHWND()); - if (::IsWindowVisible(hProgress)) { ::ShowWindow(hProgress, SW_HIDE); //make Windows recalculate z-order @@ -1148,12 +1145,14 @@ void SyncStatus::SyncStatusImpl::updateStatusDialogNow(bool allowYield) */ updateUiNow(); } + else + Update(); //don't wait until next idle event (who knows what blocking process comes next?) } bool SyncStatus::SyncStatusImpl::currentProcessIsRunning() { - return abortCb_ != NULL; + return abortCb_ != nullptr; } @@ -1209,14 +1208,14 @@ void SyncStatus::SyncStatusImpl::setCurrentStatus(SyncStatus::SyncStatusID id) } -void SyncStatus::SyncStatusImpl::processHasFinished(SyncStatus::SyncStatusID id, const ErrorLogging& log) //essential to call this in StatusHandler derived class destructor +void SyncStatus::SyncStatusImpl::processHasFinished(SyncStatus::SyncStatusID id, const ErrorLog& log) //essential to call this in StatusHandler derived class destructor { //at the LATEST(!) to prevent access to currentStatusHandler //enable okay and close events; may be set in this method ONLY wxWindowUpdateLocker dummy(this); //badly needed - abortCb_ = NULL; //avoid callback to (maybe) deleted parent process + abortCb_ = nullptr; //avoid callback to (maybe) deleted parent process setCurrentStatus(id); @@ -1248,16 +1247,18 @@ void SyncStatus::SyncStatusImpl::processHasFinished(SyncStatus::SyncStatusID id, if (totalObjects == currentObjects && //if everything was processed successfully totalData == currentData) { - m_staticTextItemsRem->Show(false); - bSizerItemsRem ->Show(false); + m_staticTextLabelItemsRem->Show(false); + bSizerItemsRem ->Show(false); } - m_staticTextItemsProc->Show(true); - bSizerItemsProc ->Show(true); + m_staticTextLabelItemsProc->Show(true); + bSizerItemsProc ->Show(true); m_staticTextProcessedObj ->SetLabel(toStringSep(currentObjects)); m_staticTextDataProcessed->SetLabel(zen::filesizeToShortString(currentData)); - m_staticTextRemTimeDescr->Show(false); + m_staticTextLabelElapsedTime->SetLabel(_("Total time:")); //it's not "elapsed time" anymore + + m_staticTextLabelRemTime->Show(false); m_staticTextRemTime ->Show(false); updateStatusDialogNow(false); //keep this sequence to avoid display distortion, if e.g. only 1 item is sync'ed @@ -1285,8 +1286,8 @@ void SyncStatus::SyncStatusImpl::processHasFinished(SyncStatus::SyncStatusID id, m_listbookResult->AddPage(logControl, _("Logging"), false); //bSizerHoldStretch->Insert(0, logControl, 1, wxEXPAND); - //show log instead of graph if fatal errors occured! (not required for ignored warnings or errors!) - if (log.typeCount(TYPE_FATAL_ERROR) > 0) + //show log instead of graph if errors occured! (not required for ignored warnings) + if (log.getItemCount(TYPE_ERROR | TYPE_FATAL_ERROR) > 0) m_listbookResult->ChangeSelection(posLog); m_panelBackground->Layout(); //we use a dummy panel as actual background: replaces simple "Layout()" call @@ -1394,11 +1395,11 @@ void SyncStatus::SyncStatusImpl::minimizeToTray() if (!trayIcon.get()) { trayIcon.reset(new FfsTrayIcon); - trayIcon->Connect(FFS_REQUEST_RESUME_TRAY_EVENT, wxCommandEventHandler(SyncStatus::SyncStatusImpl::OnResumeFromTray), NULL, this); + trayIcon->Connect(FFS_REQUEST_RESUME_TRAY_EVENT, wxCommandEventHandler(SyncStatus::SyncStatusImpl::OnResumeFromTray), nullptr, this); //tray icon has shorter lifetime than this => no need to disconnect event later } - updateStatusDialogNow(false); //set tooltip: in pause mode there is no statistics update, so this is the only chance + updateStatusDialogNow(false); //set tooltip: e.g. in pause mode there was no GUI update, so this is the last chance Hide(); if (mainDialog) @@ -1444,8 +1445,7 @@ SyncStatus::SyncStatus(AbortCallback& abortCb, if (showProgress) { pimpl->Show(); - pimpl->updateStatusDialogNow(false); //update visual statistics to get rid of "dummy" texts - pimpl->Update(); //don't wait until next idle event (who knows what blocking process comes next?) + pimpl->updateStatusDialogNow(false); //clear gui flicker: window must be visible to make this work! } else pimpl->minimizeToTray(); @@ -1506,7 +1506,7 @@ void SyncStatus::resumeTimer() return pimpl->resumeTimer(); } -void SyncStatus::processHasFinished(SyncStatusID id, const ErrorLogging& log) +void SyncStatus::processHasFinished(SyncStatusID id, const ErrorLog& log) { pimpl->processHasFinished(id, log); } diff --git a/ui/progress_indicator.h b/ui/progress_indicator.h index 3fa3f8f9..858f6ce9 100644 --- a/ui/progress_indicator.h +++ b/ui/progress_indicator.h @@ -7,16 +7,12 @@ #ifndef PROGRESSINDICATOR_H_INCLUDED #define PROGRESSINDICATOR_H_INCLUDED +#include <zen/error_log.h> #include <zen/zstring.h> #include <wx/toplevel.h> #include "../lib/status_handler.h" #include "main_dlg.h" -namespace zen -{ -class ErrorLogging; -} - class CompareStatus { @@ -57,7 +53,7 @@ public: }; SyncStatus(AbortCallback& abortCb, - MainDialog* parentWindow, //may be NULL + MainDialog* parentWindow, //may be nullptr SyncStatusID startStatus, bool showProgress, const wxString& jobName, @@ -82,7 +78,7 @@ public: //essential to call one of these two methods in StatusUpdater derived class destructor at the LATEST(!) //to prevent access to callback to updater (e.g. request abort) - void processHasFinished(SyncStatusID id, const zen::ErrorLogging& log); + void processHasFinished(SyncStatusID id, const zen::ErrorLog& log); void closeWindowDirectly(); //don't wait for user private: diff --git a/ui/search.cpp b/ui/search.cpp index 8112db6c..af62686b 100644 --- a/ui/search.cpp +++ b/ui/search.cpp @@ -106,11 +106,11 @@ private: template <bool respectCase> -int findRow(const Grid& grid, //return -1 if no matching row found - size_t compPos, - const wxString& searchString, - int rowFirst, //specify area to search: - int rowLast) // [rowFirst, rowLast) +ptrdiff_t findRow(const Grid& grid, //return -1 if no matching row found + size_t compPos, + const wxString& searchString, + size_t rowFirst, //specify area to search: + size_t rowLast) // [rowFirst, rowLast) { auto prov = grid.getDataProvider(compPos); std::vector<Grid::ColumnAttribute> colAttr = grid.getColumnConfig(compPos); @@ -119,7 +119,7 @@ int findRow(const Grid& grid, //return -1 if no matching row found { const FindInText<respectCase> searchTxt(searchString); - for (int row = rowFirst; row < rowLast; ++row) + for (size_t row = rowFirst; row < rowLast; ++row) for (auto iterCol = colAttr.begin(); iterCol != colAttr.end(); ++iterCol) if (searchTxt.found(prov->getValue(row, iterCol->type_))) return row; @@ -129,12 +129,12 @@ int findRow(const Grid& grid, //return -1 if no matching row found //syntactic sugar... -int findRow(const Grid& grid, - size_t compPos, - bool respectCase, - const wxString& searchString, - int rowFirst, //specify area to search: - int rowLast) // [rowFirst, rowLast) +ptrdiff_t findRow(const Grid& grid, + size_t compPos, + bool respectCase, + const wxString& searchString, + size_t rowFirst, //specify area to search: + size_t rowLast) // [rowFirst, rowLast) { return respectCase ? findRow<true>( grid, compPos, searchString, rowFirst, rowLast) : @@ -162,11 +162,11 @@ void executeSearch(bool forceShowDialog, searchDialogWasShown = true; } - const int rowCount = grid.getRowCount(); + const size_t rowCount = grid.getRowCount(); auto cursorPos = grid.getGridCursor(); //(row, component pos) - int cursorRow = cursorPos.first; - if (cursorRow < 0 || cursorRow >= rowCount) + size_t cursorRow = cursorPos.first; + if (cursorRow >= rowCount) cursorRow = 0; if (cursorPos.second == compPosRight) @@ -177,9 +177,9 @@ void executeSearch(bool forceShowDialog, { wxBusyCursor showHourGlass; - auto finishSearch = [&](size_t compPos, int rowFirst, int rowLast) -> bool + auto finishSearch = [&](size_t compPos, size_t rowFirst, size_t rowLast) -> bool { - const int targetRow = findRow(grid, compPos, respectCase, lastSearchString, rowFirst, rowLast); + const ptrdiff_t targetRow = findRow(grid, compPos, respectCase, lastSearchString, rowFirst, rowLast); if (targetRow >= 0) { grid.setGridCursor(targetRow, compPos); diff --git a/ui/small_dlgs.cpp b/ui/small_dlgs.cpp index 55a7021a..20e5da4e 100644 --- a/ui/small_dlgs.cpp +++ b/ui/small_dlgs.cpp @@ -34,8 +34,8 @@ public: AboutDlg(wxWindow* parent); private: - void OnClose(wxCloseEvent& event); - void OnOK(wxCommandEvent& event); + void OnClose(wxCloseEvent& event) { EndModal(0); } + void OnOK (wxCommandEvent& event) { EndModal(0); } }; @@ -101,21 +101,9 @@ AboutDlg::AboutDlg(wxWindow* parent) : AboutDlgGenerated(parent) } -void AboutDlg::OnClose(wxCloseEvent& event) -{ - EndModal(0); -} - - -void AboutDlg::OnOK(wxCommandEvent& event) -{ - EndModal(0); -} - - void zen::showAboutDialog() { - AboutDlg aboutDlg(NULL); + AboutDlg aboutDlg(nullptr); aboutDlg.ShowModal(); } //######################################################################################## @@ -130,17 +118,18 @@ public: ~FilterDlg() {} private: - void OnClose (wxCloseEvent& event); + void OnClose ( wxCloseEvent& event) { EndModal(0); } + void OnCancel (wxCommandEvent& event) { EndModal(0); } void OnHelp (wxCommandEvent& event); void OnDefault (wxCommandEvent& event); void OnApply (wxCommandEvent& event); - void OnCancel (wxCommandEvent& event); void OnUpdateChoice(wxCommandEvent& event) { updateGui(); } void OnUpdateNameFilter(wxCommandEvent& event) { updateGui(); } void updateGui(); void setFilter(const FilterConfig& filter); FilterConfig getFilter() const; + void onKeyEvent(wxKeyEvent& event); const bool isGlobalFilter_; FilterConfig& outputRef; @@ -161,12 +150,19 @@ FilterDlg::FilterDlg(wxWindow* parent, new zen::MouseMoveWindow(*this); //allow moving main dialog by clicking (nearly) anywhere...; ownership passed to "this" #endif + m_textCtrlInclude->SetMaxLength(0); //allow large filter entries! + m_textCtrlExclude->SetMaxLength(0); // + + m_textCtrlInclude->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(FilterDlg::onKeyEvent), nullptr, this); + m_textCtrlExclude->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(FilterDlg::onKeyEvent), nullptr, this); + enumTimeDescr. - add(UTIME_NONE, _("Inactive")). - add(UTIME_TODAY, _("Today")). - add(UTIME_THIS_WEEK, _("This week")). - add(UTIME_THIS_MONTH, _("This month")). - add(UTIME_THIS_YEAR, _("This year")); + add(UTIME_NONE, _("Inactive")). + add(UTIME_TODAY, _("Today")). + // add(UTIME_THIS_WEEK, _("This week")). + add(UTIME_THIS_MONTH, _("This month")). + add(UTIME_THIS_YEAR, _("This year")). + add(UTIME_LAST_X_DAYS, _("Last x days")); enumSizeDescr. add(USIZE_NONE, _("Inactive")). @@ -174,8 +170,8 @@ FilterDlg::FilterDlg(wxWindow* parent, add(USIZE_KB, _("KB")). add(USIZE_MB, _("MB")); - m_bitmap26->SetBitmap(GlobalResources::getImage(wxT("filterOn"))); - m_bpButtonHelp->SetBitmapLabel(GlobalResources::getImage(wxT("help"))); + m_bitmap26->SetBitmap(GlobalResources::getImage(L"filterOn")); + m_bpButtonHelp->SetBitmapLabel(GlobalResources::getImage(L"help")); setFilter(filter); @@ -183,41 +179,61 @@ FilterDlg::FilterDlg(wxWindow* parent, m_button10->SetFocus(); //adapt header for global/local dialog - if (isGlobalFilter_) - m_staticTexHeader->SetLabel(_("Filter: All pairs")); - else - m_staticTexHeader->SetLabel(_("Filter: Single pair")); + // if (isGlobalFilter_) + // m_staticTexHeader->SetLabel("Filter all folder pairs")); + // else + // m_staticTexHeader->SetLabel("Filter single folder pair")); + // + m_staticTexHeader->SetLabel(_("Filter")); Fit(); } +void FilterDlg::onKeyEvent(wxKeyEvent& event) +{ + const int keyCode = event.GetKeyCode(); + + if (event.ControlDown()) + switch (keyCode) + { + case 'A': //CTRL + A + { + if (auto textCtrl = dynamic_cast<wxTextCtrl*>(event.GetEventObject())) + textCtrl->SetSelection(-1, -1); //select all + return; + } + } + event.Skip(); +} + + void FilterDlg::updateGui() { FilterConfig activeCfg = getFilter(); m_bitmapInclude->SetBitmap( - !NameFilter(activeCfg.includeFilter, FilterConfig().excludeFilter).isNull() ? - GlobalResources::getImage(wxT("include")) : - greyScale(GlobalResources::getImage(wxT("include")))); + !NameFilter::isNull(activeCfg.includeFilter, FilterConfig().excludeFilter) ? + GlobalResources::getImage(L"include") : + greyScale(GlobalResources::getImage(L"include"))); m_bitmapExclude->SetBitmap( - !NameFilter(FilterConfig().includeFilter, activeCfg.excludeFilter).isNull() ? - GlobalResources::getImage(wxT("exclude")) : - greyScale(GlobalResources::getImage(wxT("exclude")))); + !NameFilter::isNull(FilterConfig().includeFilter, activeCfg.excludeFilter) ? + GlobalResources::getImage(L"exclude") : + greyScale(GlobalResources::getImage(L"exclude"))); m_bitmapFilterDate->SetBitmap( activeCfg.unitTimeSpan != UTIME_NONE ? - GlobalResources::getImage(wxT("clock")) : - greyScale(GlobalResources::getImage(wxT("clock")))); + GlobalResources::getImage(L"clock") : + greyScale(GlobalResources::getImage(L"clock"))); m_bitmapFilterSize->SetBitmap( activeCfg.unitSizeMin != USIZE_NONE || activeCfg.unitSizeMax != USIZE_NONE ? - GlobalResources::getImage(wxT("size")) : - greyScale(GlobalResources::getImage(wxT("size")))); + GlobalResources::getImage(L"size") : + greyScale(GlobalResources::getImage(L"size"))); - //m_spinCtrlTimespan->Enable(activeCfg.unitTimeSpan == UTIME_LAST_X_HOURS); + m_spinCtrlTimespan->Enable(activeCfg.unitTimeSpan == UTIME_LAST_X_DAYS); m_spinCtrlMinSize ->Enable(activeCfg.unitSizeMin != USIZE_NONE); m_spinCtrlMaxSize ->Enable(activeCfg.unitSizeMax != USIZE_NONE); } @@ -286,22 +302,9 @@ void FilterDlg::OnApply(wxCommandEvent& event) } -void FilterDlg::OnCancel(wxCommandEvent& event) -{ - EndModal(0); -} - - -void FilterDlg::OnClose(wxCloseEvent& event) -{ - EndModal(0); -} - - - ReturnSmallDlg::ButtonPressed zen::showFilterDialog(bool isGlobalFilter, FilterConfig& filter) { - FilterDlg filterDlg(NULL, + FilterDlg filterDlg(nullptr, isGlobalFilter, //is main filter dialog filter); return static_cast<ReturnSmallDlg::ButtonPressed>(filterDlg.ShowModal()); @@ -320,8 +323,8 @@ public: private: void OnOK(wxCommandEvent& event); - void OnCancel(wxCommandEvent& event); - void OnClose(wxCloseEvent& event); + void OnCancel(wxCommandEvent& event) { EndModal(ReturnSmallDlg::BUTTON_CANCEL); } + void OnClose (wxCloseEvent& event) { EndModal(ReturnSmallDlg::BUTTON_CANCEL); } void OnDelOnBothSides(wxCommandEvent& event); void OnUseRecycler(wxCommandEvent& event); @@ -403,16 +406,6 @@ void DeleteDialog::OnOK(wxCommandEvent& event) EndModal(ReturnSmallDlg::BUTTON_OKAY); } -void DeleteDialog::OnCancel(wxCommandEvent& event) -{ - EndModal(ReturnSmallDlg::BUTTON_CANCEL); -} - -void DeleteDialog::OnClose(wxCloseEvent& event) -{ - EndModal(ReturnSmallDlg::BUTTON_CANCEL); -} - void DeleteDialog::OnDelOnBothSides(wxCommandEvent& event) { updateGui(); @@ -429,7 +422,7 @@ ReturnSmallDlg::ButtonPressed zen::showDeleteDialog(const std::vector<zen::FileS bool& deleteOnBothSides, bool& useRecycleBin) { - DeleteDialog confirmDeletion(NULL, + DeleteDialog confirmDeletion(nullptr, rowsOnLeft, rowsOnRight, deleteOnBothSides, @@ -518,7 +511,7 @@ ReturnSmallDlg::ButtonPressed zen::showSyncPreviewDlg( const zen::SyncStatistics& statistics, bool& dontShowAgain) { - SyncPreviewDlg preview(NULL, + SyncPreviewDlg preview(nullptr, variantName, statistics, dontShowAgain); @@ -641,7 +634,7 @@ void CompareCfgDialog::OnShowHelp(wxCommandEvent& event) ReturnSmallDlg::ButtonPressed zen::showCompareCfgDialog(CompConfig& cmpConfig) { - CompareCfgDialog syncDlg(NULL, cmpConfig); + CompareCfgDialog syncDlg(nullptr, cmpConfig); return static_cast<ReturnSmallDlg::ButtonPressed>(syncDlg.ShowModal()); } @@ -710,7 +703,7 @@ GlobalSettingsDlg::GlobalSettingsDlg(wxWindow* parent, xmlAccess::XmlGlobalSetti Fit(); //automatically fit column width to match totl grid width - Connect(wxEVT_SIZE, wxSizeEventHandler(GlobalSettingsDlg::OnResize), NULL, this); + Connect(wxEVT_SIZE, wxSizeEventHandler(GlobalSettingsDlg::OnResize), nullptr, this); wxSizeEvent dummy; OnResize(dummy); } @@ -749,7 +742,7 @@ void GlobalSettingsDlg::OnOkay(wxCommandEvent& event) void GlobalSettingsDlg::OnResetDialogs(wxCommandEvent& event) { if (showQuestionDlg(ReturnQuestionDlg::BUTTON_YES | ReturnQuestionDlg::BUTTON_CANCEL, - _("Restore all hidden dialogs?")) == ReturnQuestionDlg::BUTTON_YES) + _("Make hidden dialogs and warning messages visible again?")) == ReturnQuestionDlg::BUTTON_YES) settings.optDialogs.resetDialogs(); } @@ -844,7 +837,7 @@ void GlobalSettingsDlg::OnRemoveRow(wxCommandEvent& event) ReturnSmallDlg::ButtonPressed zen::showGlobalSettingsDlg(xmlAccess::XmlGlobalSettings& globalSettings) { - GlobalSettingsDlg settingsDlg(NULL, globalSettings); + GlobalSettingsDlg settingsDlg(nullptr, globalSettings); return static_cast<ReturnSmallDlg::ButtonPressed>(settingsDlg.ShowModal()); } //######################################################################################## @@ -897,7 +890,7 @@ SelectTimespanDlg::SelectTimespanDlg(wxWindow* parent, Int64& timeFrom, Int64& t new zen::MouseMoveWindow(*this); //allow moving main dialog by clicking (nearly) anywhere...; ownership passed to "this" #endif - long style = wxCAL_SHOW_HOLIDAYS; + long style = wxCAL_SHOW_HOLIDAYS | wxCAL_SHOW_SURROUNDING_WEEKS; #ifdef FFS_WIN DWORD firstDayOfWeek = 0; @@ -925,6 +918,13 @@ SelectTimespanDlg::SelectTimespanDlg(wxWindow* parent, Int64& timeFrom, Int64& t m_calendarTo ->SetDate(utcToLocalDateTime(to<time_t>(timeTo_))); m_buttonOkay->SetFocus(); + + //wxDatePickerCtrl::BestSize() does not respect year field and trims it, both wxMSW/wxGTK - why isn't there anybody testing this wxWidgets stuff??? + wxSize minSz = m_calendarFrom->GetBestSize(); + minSz.x += 30; + m_calendarFrom->SetMinSize(minSz); + m_calendarTo ->SetMinSize(minSz); + Fit(); } @@ -962,6 +962,6 @@ void SelectTimespanDlg::OnOkay(wxCommandEvent& event) ReturnSmallDlg::ButtonPressed zen::showSelectTimespanDlg(Int64& timeFrom, Int64& timeTo) { - SelectTimespanDlg timeSpanDlg(NULL, timeFrom, timeTo); + SelectTimespanDlg timeSpanDlg(nullptr, timeFrom, timeTo); return static_cast<ReturnSmallDlg::ButtonPressed>(timeSpanDlg.ShowModal()); } diff --git a/ui/sorting.h b/ui/sorting.h index 15e04a62..807a9ce3 100644 --- a/ui/sorting.h +++ b/ui/sorting.h @@ -19,16 +19,16 @@ namespace { struct CompileTimeReminder : public FSObjectVisitor { - virtual void visit(const FileMapping& fileObj ) {} + virtual void visit(const FileMapping& fileObj) {} virtual void visit(const SymLinkMapping& linkObj) {} - virtual void visit(const DirMapping& dirObj ) {} + virtual void visit(const DirMapping& dirObj ) {} } checkDymanicCasts; //just a compile-time reminder to check dynamic casts in this file } inline bool isDirectoryMapping(const FileSystemObject& fsObj) { - return dynamic_cast<const DirMapping*>(&fsObj) != NULL; + return dynamic_cast<const DirMapping*>(&fsObj) != nullptr; } @@ -97,8 +97,8 @@ bool lessFilesize(const FileSystemObject& a, const FileSystemObject& b) else if (b.isEmpty<side>()) return true; - const bool isDirA = dynamic_cast<const DirMapping*>(&a) != NULL; - const bool isDirB = dynamic_cast<const DirMapping*>(&b) != NULL; + const bool isDirA = dynamic_cast<const DirMapping*>(&a) != nullptr; + const bool isDirB = dynamic_cast<const DirMapping*>(&b) != nullptr; //directories second last if (isDirA) @@ -110,9 +110,9 @@ bool lessFilesize(const FileSystemObject& a, const FileSystemObject& b) const FileMapping* fileObjB = dynamic_cast<const FileMapping*>(&b); //then symlinks - if (fileObjA == NULL) + if (!fileObjA) return false; - else if (fileObjB == NULL) + else if (!fileObjB) return true; //return list beginning with largest files first @@ -160,9 +160,9 @@ bool lessExtension(const FileSystemObject& a, const FileSystemObject& b) const FileMapping* fileObjA = dynamic_cast<const FileMapping*>(&a); const FileMapping* fileObjB = dynamic_cast<const FileMapping*>(&b); - if (fileObjA == NULL) + if (!fileObjA) return false; //directories last - else if (fileObjB == NULL) + else if (!fileObjB) return true; //directories last return makeSortDirection(LessFilename(), Int2Type<ascending>())(fileObjA->getExtension<side>(), fileObjB->getExtension<side>()); diff --git a/ui/sync_cfg.cpp b/ui/sync_cfg.cpp index 4da98b8e..4f6df013 100644 --- a/ui/sync_cfg.cpp +++ b/ui/sync_cfg.cpp @@ -534,7 +534,7 @@ ReturnSyncConfig::ButtonPressed zen::showSyncConfigDlg(CompareVariant compareVar xmlAccess::OnGuiError* handleError, // ExecWhenFinishedCfg* execWhenFinished) //optional input parameter { - SyncCfgDialog syncDlg(NULL, + SyncCfgDialog syncDlg(nullptr, compareVar, syncCfg, handleError, diff --git a/ui/tray_icon.cpp b/ui/tray_icon.cpp index 26556742..51441e36 100644 --- a/ui/tray_icon.cpp +++ b/ui/tray_icon.cpp @@ -162,20 +162,20 @@ class FfsTrayIcon::TaskBarImpl : public wxTaskBarIcon public: TaskBarImpl(FfsTrayIcon& parent) : parent_(&parent) {} - void parentHasDied() { parent_ = NULL; } + void parentHasDied() { parent_ = nullptr; } private: virtual wxMenu* CreatePopupMenu() { if (!parent_) - return NULL; + return nullptr; wxMenu* contextMenu = new wxMenu; contextMenu->Append(CONTEXT_ABOUT, _("&About...")); contextMenu->AppendSeparator(); contextMenu->Append(CONTEXT_RESTORE, _("&Restore")); //event handling - contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(FfsTrayIcon::OnContextMenuSelection), NULL, parent_); + contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(FfsTrayIcon::OnContextMenuSelection), nullptr, parent_); return contextMenu; //ownership transferred to caller } @@ -188,14 +188,14 @@ FfsTrayIcon::FfsTrayIcon() : trayIcon(new TaskBarImpl(*this)) { trayIcon->SetIcon(generateIcon(0), wxT("FreeFileSync")); - trayIcon->Connect(wxEVT_TASKBAR_LEFT_DCLICK, wxCommandEventHandler(FfsTrayIcon::OnDoubleClick), NULL, this); //register double-click + trayIcon->Connect(wxEVT_TASKBAR_LEFT_DCLICK, wxCommandEventHandler(FfsTrayIcon::OnDoubleClick), nullptr, this); //register double-click } FfsTrayIcon::~FfsTrayIcon() { trayIcon->RemoveIcon(); //hide icon until final deletion takes place - trayIcon->Disconnect(wxEVT_TASKBAR_LEFT_DCLICK, wxCommandEventHandler(FfsTrayIcon::OnDoubleClick), NULL, this); + trayIcon->Disconnect(wxEVT_TASKBAR_LEFT_DCLICK, wxCommandEventHandler(FfsTrayIcon::OnDoubleClick), nullptr, this); trayIcon->parentHasDied(); //TaskBarImpl (potentially) has longer lifetime than FfsTrayIcon: avoid callback! //use wxWidgets delayed destruction: delete during next idle loop iteration (handle late window messages, e.g. when double-clicking) @@ -204,7 +204,7 @@ FfsTrayIcon::~FfsTrayIcon() } -void FfsTrayIcon::setToolTip2(const wxString& toolTipText, double fraction) +void FfsTrayIcon::setToolTip(const wxString& toolTipText, double fraction) { trayIcon->SetIcon(generateIcon(fraction), toolTipText); } diff --git a/ui/tray_icon.h b/ui/tray_icon.h index e9778d1e..d1522602 100644 --- a/ui/tray_icon.h +++ b/ui/tray_icon.h @@ -19,7 +19,7 @@ public: FfsTrayIcon(); ~FfsTrayIcon(); - void setToolTip2(const wxString& toolTipText, double fraction = 0); //number between [0, 1], for small progress indicator + void setToolTip(const wxString& toolTipText, double fraction = 0); //number between [0, 1], for small progress indicator private: FfsTrayIcon(const FfsTrayIcon&); diff --git a/ui/tree_view.cpp b/ui/tree_view.cpp index cd29938e..49548142 100644 --- a/ui/tree_view.cpp +++ b/ui/tree_view.cpp @@ -19,6 +19,21 @@ using namespace zen; +inline +void TreeView::compressNode(Container& cont) //remove single-element sub-trees -> gain clarity + usability (call *after* inclusion check!!!) +{ + if (cont.subDirs.empty() || //single files node or... + (cont.firstFile == nullptr && //single dir node... + cont.subDirs.size() == 1 && // + cont.subDirs[0].firstFile == nullptr && //...that is empty + cont.subDirs[0].subDirs.empty())) // + { + cont.subDirs.clear(); + cont.firstFile = nullptr; + } +} + + template <class Function> //(const FileSystemObject&) -> bool void TreeView::extractVisibleSubtree(HierarchyObject& hierObj, //in TreeView::Container& cont, //out @@ -41,7 +56,7 @@ void TreeView::extractVisibleSubtree(HierarchyObject& hierObj, //in }; - cont.firstFile = NULL; + cont.firstFile = nullptr; std::for_each(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), [&](FileMapping& fileObj) { @@ -80,15 +95,7 @@ void TreeView::extractVisibleSubtree(HierarchyObject& hierObj, //in if (pred(subDirObj) || subDirView.firstFile || !subDirView.subDirs.empty()) { subDirView.objId = subDirObj.getId(); - - //------------------- small hack -------------------------------------------- - //remove single-element sub-trees (*after* inclusion check!!!) - if (subDirView.subDirs.empty() || - (subDirView.firstFile == NULL && subDirView.subDirs.size() == 1 && subDirView.subDirs[0].subDirs.empty() && subDirView.subDirs[0].firstFile == NULL)) - { - subDirView.subDirs.clear(); - subDirView.firstFile = NULL; - } + compressNode(subDirView); } else cont.subDirs.pop_back(); @@ -98,16 +105,15 @@ void TreeView::extractVisibleSubtree(HierarchyObject& hierObj, //in namespace { -//generate nice percentage numbers which sum up to 100 +//generate nice percentage numbers which precisely sum up to 100 void calcPercentage(std::vector<std::pair<UInt64, int*>>& workList) { const UInt64 total = std::accumulate(workList.begin(), workList.end(), UInt64(), - [](UInt64 val, const std::pair<UInt64, int*>& pair) { return val + pair.first; }); + [](UInt64 sum, const std::pair<UInt64, int*>& pair) { return sum + pair.first; }); if (total == 0U) //this case doesn't work with the error minimizing algorithm below { - std::for_each(workList.begin(), workList.end(), - [&](std::pair<UInt64, int*>& pair) { *pair.second = 0; }); + std::for_each(workList.begin(), workList.end(), [](std::pair<UInt64, int*>& pair) { *pair.second = 0; }); return; } @@ -119,18 +125,20 @@ void calcPercentage(std::vector<std::pair<UInt64, int*>>& workList) remainingPercent -= *pair.second; }); - //sort descending by absolute error - std::sort(workList.begin(), workList.end(), - [&](const std::pair<UInt64, int*>& lhs, const std::pair<UInt64, int*>& rhs) + //find #remainingPercent items with largest absolute error + remainingPercent = std::min(remainingPercent, static_cast<int>(workList.size())); + if (remainingPercent > 0) { - //return std::abs(*lhs.second - to<double>(lhs.first) * 100 / total) > std::abs(*rhs.second - to<double>(rhs.first) * 100 / total); - return (to<double>(lhs.first) - to<double>(rhs.first)) * 100 / to<double>(total) > *lhs.second - *rhs.second; - }); + std::nth_element(workList.begin(), workList.begin() + remainingPercent - 1, workList.end(), + [total](const std::pair<UInt64, int*>& lhs, const std::pair<UInt64, int*>& rhs) + { + //return std::abs(*lhs.second - to<double>(lhs.first) * 100 / total) > std::abs(*rhs.second - to<double>(rhs.first) * 100 / total); + return (to<double>(lhs.first) - to<double>(rhs.first)) * 100 / to<double>(total) > *lhs.second - *rhs.second; + }); - //distribute remaining percent so that overall error is minimized as much as possible - remainingPercent = std::min(std::max(0, remainingPercent), static_cast<int>(workList.size())); - std::for_each(workList.begin(), workList.begin() + remainingPercent, - [&](std::pair<UInt64, int*>& pair) { ++*pair.second; }); + //distribute remaining percent so that overall error is minimized as much as possible + std::for_each(workList.begin(), workList.begin() + remainingPercent, [&](std::pair<UInt64, int*>& pair) { ++*pair.second; }); + } } } @@ -253,7 +261,7 @@ void TreeView::applySubView(std::vector<RootNodeImpl>&& newView) case TreeView::TYPE_FILES: break; //none!!! } - return NULL; + return nullptr; }; zen::hash_set<const HierarchyObject*> expandedNodes; @@ -272,8 +280,11 @@ void TreeView::applySubView(std::vector<RootNodeImpl>&& newView) //set default flat tree flatTree.clear(); - if (folderCmpView.size() == 1) - getChildren(folderCmpView[0], 0, flatTree); //do not show root + if (folderCmp.size() == 1) //single folder pair case (empty pairs were already removed!) do NOT use folderCmpView for this check! + { + if (!folderCmpView.empty()) //it may really be! + getChildren(folderCmpView[0], 0, flatTree); //do not show root + } else { std::vector<std::pair<UInt64, int*>> workList; @@ -316,13 +327,19 @@ void TreeView::updateView(Predicate pred) std::for_each(folderCmp.begin(), folderCmp.end(), [&](const std::shared_ptr<BaseDirMapping>& baseObj) { - if (!baseObj->getBaseDirPf<LEFT_SIDE>().empty() || !baseObj->getBaseDirPf<RIGHT_SIDE>().empty()) + newView.push_back(TreeView::RootNodeImpl()); + RootNodeImpl& root = newView.back(); + this->extractVisibleSubtree(*baseObj, root, pred); //"this->" is bogus for a static method, but GCC screws this one up + + //warning: the following lines are almost 1:1 copy from extractVisibleSubtree: + //however we *cannot* reuse code here; this were only possible if we could replace "std::vector<RootNodeImpl>" by "Container"! + if (root.firstFile || !root.subDirs.empty()) { - newView.push_back(TreeView::RootNodeImpl()); - RootNodeImpl& root = newView.back(); root.baseMap = baseObj; - this->extractVisibleSubtree(*baseObj, root, pred); //"this->" is bogus for a static method, but GCC screws this one up + compressNode(root); } + else + newView.pop_back(); }); applySubView(std::move(newView)); @@ -419,15 +436,15 @@ void TreeView::reduceNode(size_t row) } -int TreeView::getParent(size_t row) const +ptrdiff_t TreeView::getParent(size_t row) const { if (row < flatTree.size()) { const size_t level = flatTree[row].level_; - for (; row > 0; --row) - if (flatTree[row - 1].level_ < level) - return row - 1; + while (row-- > 0) + if (flatTree[row].level_ < level) + return row; } return -1; } @@ -525,6 +542,13 @@ void TreeView::setData(FolderComparison& newData) std::vector<TreeLine >().swap(flatTree); //free mem std::vector<RootNodeImpl>().swap(folderCmpView); // folderCmp = newData; + + //remove truly empty folder pairs as early as this: we want to distinguish single/multiple folder pair cases by looking at "folderCmp" + vector_remove_if(folderCmp, [](const std::shared_ptr<BaseDirMapping>& baseObj) + { + return baseObj->getBaseDirPf<LEFT_SIDE >().empty() && + baseObj->getBaseDirPf<RIGHT_SIDE>().empty(); + }); } @@ -561,7 +585,7 @@ std::unique_ptr<TreeView::Node> TreeView::getLine(size_t row) const break; } } - return NULL; + return nullptr; } //########################################################################################################## @@ -606,11 +630,11 @@ public: grid_(grid), showPercentBar(true) { - grid.getMainWin().Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(GridDataNavi::onKeyDown), NULL, this); - grid.Connect(EVENT_GRID_MOUSE_LEFT_DOWN, GridClickEventHandler(GridDataNavi::onMouseLeft ), NULL, this); - grid.Connect(EVENT_GRID_MOUSE_LEFT_DOUBLE, GridClickEventHandler(GridDataNavi::onMouseLeftDouble ), NULL, this); - grid.Connect(EVENT_GRID_COL_LABEL_MOUSE_RIGHT, GridClickEventHandler(GridDataNavi::onGridLabelContext), NULL, this ); - grid.Connect(EVENT_GRID_COL_LABEL_MOUSE_LEFT, GridClickEventHandler(GridDataNavi::onGridLabelLeftClick ), NULL, this ); + grid.getMainWin().Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(GridDataNavi::onKeyDown), nullptr, this); + grid.Connect(EVENT_GRID_MOUSE_LEFT_DOWN, GridClickEventHandler(GridDataNavi::onMouseLeft ), nullptr, this); + grid.Connect(EVENT_GRID_MOUSE_LEFT_DOUBLE, GridClickEventHandler(GridDataNavi::onMouseLeftDouble ), nullptr, this); + grid.Connect(EVENT_GRID_COL_LABEL_MOUSE_RIGHT, GridClickEventHandler(GridDataNavi::onGridLabelContext), nullptr, this ); + grid.Connect(EVENT_GRID_COL_LABEL_MOUSE_LEFT, GridClickEventHandler(GridDataNavi::onGridLabelLeftClick ), nullptr, this ); } void setShowPercentage(bool value) { showPercentBar = value; grid_.Refresh(); } @@ -619,7 +643,7 @@ public: private: virtual size_t getRowCount() const { return treeDataView_ ? treeDataView_->linesTotal() : 0; } - virtual wxString getValue(int row, ColumnType colType) const + virtual wxString getValue(size_t row, ColumnType colType) const { if (treeDataView_) { @@ -677,7 +701,7 @@ private: static const int CELL_BORDER = 2; - virtual void renderRowBackgound(wxDC& dc, const wxRect& rect, int row, bool enabled, bool selected, bool hasFocus) + virtual void renderRowBackgound(wxDC& dc, const wxRect& rect, size_t row, bool enabled, bool selected, bool hasFocus) { if (enabled) { @@ -691,7 +715,7 @@ private: clearArea(dc, rect, wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); } - virtual void renderCell(Grid& grid, wxDC& dc, const wxRect& rect, int row, ColumnType colType) + virtual void renderCell(Grid& grid, wxDC& dc, const wxRect& rect, size_t row, ColumnType colType) { //wxRect rectTmp= drawCellBorder(dc, rect); wxRect rectTmp = rect; @@ -714,8 +738,8 @@ private: // rect.height)), wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); //consume space - rectTmp.x += node->level_ * widthLevelStep; - rectTmp.width -= node->level_ * widthLevelStep; + rectTmp.x += static_cast<int>(node->level_) * widthLevelStep; + rectTmp.width -= static_cast<int>(node->level_) * widthLevelStep; rectTmp.x += CELL_BORDER; rectTmp.width -= CELL_BORDER; @@ -777,7 +801,7 @@ private: dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.DrawRectangle(areaPerc); } - dc.DrawLabel(toString<wxString>(node->percent_) + L"%", areaPerc, wxALIGN_CENTER); + dc.DrawLabel(numberTo<wxString>(node->percent_) + L"%", areaPerc, wxALIGN_CENTER); rectTmp.x += widthPercentBar + 2 * CELL_BORDER; rectTmp.width -= widthPercentBar + 2 * CELL_BORDER; @@ -867,7 +891,7 @@ private: } } - virtual size_t getBestSize(wxDC& dc, int row, ColumnType colType) + virtual size_t getBestSize(wxDC& dc, size_t row, ColumnType colType) { // -> synchronize renderCell() <-> getBestSize() <-> onMouseLeft() @@ -910,7 +934,7 @@ private: if (cellArea.width > 0 && cellArea.height > 0) { const int tolerance = 1; - const int xNodeStatusFirst = -tolerance + cellArea.x + node->level_ * widthLevelStep + CELL_BORDER + (showPercentBar ? widthPercentBar + 2 * CELL_BORDER : 0); + const int xNodeStatusFirst = -tolerance + cellArea.x + static_cast<int>(node->level_) * widthLevelStep + CELL_BORDER + (showPercentBar ? widthPercentBar + 2 * CELL_BORDER : 0); const int xNodeStatusLast = xNodeStatusFirst + widthNodeStatus + 2 * tolerance; // -> synchronize renderCell() <-> getBestSize() <-> onMouseLeft() @@ -964,54 +988,49 @@ private: keyCode = WXK_NUMPAD_LEFT; } - int row = grid_.getGridCursor().first; - if (row < 0) - { - row = 0; - grid_.setGridCursor(0); - } + const size_t rowCount = grid_.getRowCount(); + if (rowCount == 0) return; + + size_t row = grid_.getGridCursor().first; + if (event.ShiftDown()) + ; + else if (event.ControlDown()) + ; else - { - if (event.ShiftDown()) - ; - else if (event.ControlDown()) - ; - else - switch (keyCode) - { - case WXK_LEFT: - case WXK_NUMPAD_LEFT: - if (treeDataView_) - switch (treeDataView_->getStatus(row)) - { - case TreeView::STATUS_EXPANDED: - return reduceNode(row); - case TreeView::STATUS_REDUCED: - case TreeView::STATUS_EMPTY: - - const int parentRow = treeDataView_->getParent(row); - if (parentRow >= 0) - grid_.setGridCursor(parentRow); - break; - } - return; //swallow event + switch (keyCode) + { + case WXK_LEFT: + case WXK_NUMPAD_LEFT: + if (treeDataView_) + switch (treeDataView_->getStatus(row)) + { + case TreeView::STATUS_EXPANDED: + return reduceNode(row); + case TreeView::STATUS_REDUCED: + case TreeView::STATUS_EMPTY: - case WXK_RIGHT: - case WXK_NUMPAD_RIGHT: - if (treeDataView_) - switch (treeDataView_->getStatus(row)) - { - case TreeView::STATUS_EXPANDED: - grid_.setGridCursor(std::min(static_cast<int>(grid_.getRowCount()) - 1, row + 1)); - break; - case TreeView::STATUS_REDUCED: - return expandNode(row); - case TreeView::STATUS_EMPTY: - break; - } - return; //swallow event - } - } + const int parentRow = treeDataView_->getParent(row); + if (parentRow >= 0) + grid_.setGridCursor(parentRow); + break; + } + return; //swallow event + + case WXK_RIGHT: + case WXK_NUMPAD_RIGHT: + if (treeDataView_) + switch (treeDataView_->getStatus(row)) + { + case TreeView::STATUS_EXPANDED: + grid_.setGridCursor(std::min(rowCount - 1, row + 1)); + break; + case TreeView::STATUS_REDUCED: + return expandNode(row); + case TreeView::STATUS_EMPTY: + break; + } + return; //swallow event + } event.Skip(); } @@ -1076,7 +1095,7 @@ private: } } - void expandNode(int row) + void expandNode(size_t row) { treeDataView_->expandNode(row); grid_.Refresh(); //this one clears selection (changed row count) @@ -1084,7 +1103,7 @@ private: //grid_.autoSizeColumns(); -> doesn't look as good as expected } - void reduceNode(int row) + void reduceNode(size_t row) { treeDataView_->reduceNode(row); grid_.Refresh(); //this one clears selection (changed row count) diff --git a/ui/tree_view.h b/ui/tree_view.h index 9f8cb526..3bb741e6 100644 --- a/ui/tree_view.h +++ b/ui/tree_view.h @@ -84,13 +84,13 @@ public: BaseDirMapping& baseMap_; }; - std::unique_ptr<Node> getLine(size_t row) const; //return NULL on error + std::unique_ptr<Node> getLine(size_t row) const; //return nullptr on error size_t linesTotal() const { return flatTree.size(); } void expandNode(size_t row); void reduceNode(size_t row); NodeStatus getStatus(size_t row) const; - int getParent(size_t row) const; //return < 0 if none + ptrdiff_t getParent(size_t row) const; //return < 0 if none void setSortDirection(ColumnTypeNavi colType, bool ascending); //apply permanently! std::pair<ColumnTypeNavi, bool> getSortDirection() { return std::make_pair(sortColumn, sortAscending); } @@ -101,7 +101,7 @@ private: struct Container { - Container() : firstFile(NULL) {} + Container() : firstFile(nullptr) {} UInt64 bytesGross; UInt64 bytesNet; //files in this directory only std::vector<DirNodeImpl> subDirs; @@ -110,7 +110,7 @@ private: struct DirNodeImpl : public Container { - DirNodeImpl() : objId(NULL) {} + DirNodeImpl() : objId(nullptr) {} FileSystemObject::ObjectId objId; //weak pointer to DirMapping }; @@ -129,14 +129,15 @@ private: struct TreeLine { - TreeLine(unsigned int level, int percent, const Container* node, enum NodeType type) : level_(level), percent_(percent), node_(node), type_(type) {} + TreeLine(size_t level, int percent, const Container* node, enum NodeType type) : level_(level), percent_(percent), node_(node), type_(type) {} - unsigned int level_; + size_t level_; int percent_; //[0, 100] const Container* node_; // NodeType type_; //we choose to increase size of "flatTree" rather than "folderCmpView" by not using dynamic polymorphism! }; + static void compressNode(Container& cont); template <class Function> static void extractVisibleSubtree(HierarchyObject& hierObj, Container& cont, Function includeObject); void getChildren(const Container& cont, size_t level, std::vector<TreeLine>& output); diff --git a/version/version.h b/version/version.h index e5445e1c..64e9edc3 100644 --- a/version/version.h +++ b/version/version.h @@ -3,7 +3,7 @@ namespace zen { -const wchar_t currentVersion[] = L"5.0"; //internal linkage! + const wchar_t currentVersion[] = L"5.1"; //internal linkage! } #endif diff --git a/version/version.rc b/version/version.rc index a0af4f4d..2ba8abb6 100644 --- a/version/version.rc +++ b/version/version.rc @@ -1,2 +1,2 @@ -#define VER_FREEFILESYNC 5,0,0,0 -#define VER_FREEFILESYNC_STR "5.0\0" +#define VER_FREEFILESYNC 5,1,0,0 +#define VER_FREEFILESYNC_STR "5.1\0" diff --git a/wx+/button.cpp b/wx+/button.cpp index 9efdf071..1e9cb7f0 100644 --- a/wx+/button.cpp +++ b/wx+/button.cpp @@ -38,12 +38,12 @@ BitmapButton::BitmapButton(wxWindow* parent, } -void BitmapButton::setBitmapFront(const wxBitmap& bitmap, unsigned spaceAfter) +void BitmapButton::setBitmapFront(const wxBitmap& bitmap, size_t spaceAfter) { if (!isEqual(bitmap, bitmapFront) || spaceAfter != m_spaceAfter) //avoid flicker { bitmapFront = bitmap; - m_spaceAfter = spaceAfter; + m_spaceAfter = static_cast<unsigned int>(spaceAfter); refreshButtonLabel(); } } @@ -60,12 +60,12 @@ void BitmapButton::setTextLabel(const wxString& text) } -void BitmapButton::setBitmapBack(const wxBitmap& bitmap, unsigned spaceBefore) +void BitmapButton::setBitmapBack(const wxBitmap& bitmap, size_t spaceBefore) { if (!isEqual(bitmap, bitmapBack) || spaceBefore != m_spaceBefore) //avoid flicker { bitmapBack = bitmap; - m_spaceBefore = spaceBefore; + m_spaceBefore = static_cast<unsigned int>(spaceBefore); refreshButtonLabel(); } } @@ -106,7 +106,7 @@ wxSize getSizeNeeded(const wxString& text, wxFont& font) wxString textFormatted = text; textFormatted.Replace(wxT("&"), wxT(""), false); //remove accelerator - dc.GetMultiLineTextExtent(textFormatted, &width, &height , NULL, &font); + dc.GetMultiLineTextExtent(textFormatted, &width, &height, nullptr, &font); return wxSize(width, height); } diff --git a/wx+/button.h b/wx+/button.h index 471a5b5a..bf741945 100644 --- a/wx+/button.h +++ b/wx+/button.h @@ -24,18 +24,18 @@ public: const wxValidator& validator = wxDefaultValidator, const wxString& name = wxButtonNameStr); - void setBitmapFront(const wxBitmap& bitmap, unsigned spaceAfter = 0); + void setBitmapFront(const wxBitmap& bitmap, size_t spaceAfter = 0); void setTextLabel( const wxString& text); - void setBitmapBack( const wxBitmap& bitmap, unsigned spaceBefore = 0); + void setBitmapBack( const wxBitmap& bitmap, size_t spaceBefore = 0); private: wxBitmap createBitmapFromText(const wxString& text); void refreshButtonLabel(); wxBitmap bitmapFront; - unsigned m_spaceAfter; + unsigned int m_spaceAfter; wxString textLabel; - unsigned m_spaceBefore; + unsigned int m_spaceBefore; wxBitmap bitmapBack; }; diff --git a/wx+/context_menu.h b/wx+/context_menu.h index 894da832..8f80fac2 100644 --- a/wx+/context_menu.h +++ b/wx+/context_menu.h @@ -27,12 +27,12 @@ namespace zen class ContextMenu : private wxEvtHandler { public: - void addItem(const wxString& label, const std::function<void()>& command, const wxBitmap* bmp = NULL, bool enabled = true) + void addItem(const wxString& label, const std::function<void()>& command, const wxBitmap* bmp = nullptr, bool enabled = true) { wxMenuItem* newItem = new wxMenuItem(&menu, wxID_ANY, label); - if (bmp) newItem->SetBitmap(*bmp); - if (!enabled) newItem->Enable(false); - menu.Append(newItem); //do NOT append item before setting bitmap! wxWidgets screws up for yet another crappy reason + if (bmp) newItem->SetBitmap(*bmp); //do not set AFTER appending item! wxWidgets screws up for yet another crappy reason + menu.Append(newItem); + if (!enabled) newItem->Enable(false); //do not enable BEFORE appending item! wxWidgets screws up for yet another crappy reason menu.Connect(newItem->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(ContextMenu::onSelection), new GenericCommand(command), /*pass ownership*/ this); } diff --git a/wx+/file_drop.h b/wx+/file_drop.h index c2a14423..0e9ba538 100644 --- a/wx+/file_drop.h +++ b/wx+/file_drop.h @@ -18,8 +18,8 @@ namespace zen void setupFileDrop(wxWindow& wnd); //2. register events: -//wnd.Connect (EVENT_DROP_FILE, FileDropEventHandler(MyDlg::OnFilesDropped), NULL, this); -//wnd.Disconnect(EVENT_DROP_FILE, FileDropEventHandler(MyDlg::OnFilesDropped), NULL, this); +//wnd.Connect (EVENT_DROP_FILE, FileDropEventHandler(MyDlg::OnFilesDropped), nullptr, this); +//wnd.Disconnect(EVENT_DROP_FILE, FileDropEventHandler(MyDlg::OnFilesDropped), nullptr, this); //3. do something: //void MyDlg::OnFilesDropped(FileDropEvent& event); diff --git a/wx+/format_unit.cpp b/wx+/format_unit.cpp index 0a054534..f6d2e5c2 100644 --- a/wx+/format_unit.cpp +++ b/wx+/format_unit.cpp @@ -35,7 +35,7 @@ std::wstring zen::filesizeToShortString(Int64 size) if (numeric::abs(size) <= 999) return replaceCpy(_P("1 Byte", "%x Bytes", to<int>(size)), L"%x", - toString<std::wstring>(size)); + numberTo<std::wstring>(size)); else { double filesize = to<double>(size); @@ -131,7 +131,7 @@ std::wstring zen::remainingTimeToShortString(double timeInSec) output = _P("1 day", "%x days", formattedTime); break; } - return replaceCpy(output, L"%x", zen::toString<std::wstring>(formattedTime)); + return replaceCpy(output, L"%x", zen::numberTo<std::wstring>(formattedTime)); } @@ -151,7 +151,7 @@ std::wstring zen::ffs_Impl::includeNumberSeparator(const std::wstring& number) if (i <= 3) break; i -= 3; - if (!cStringIsDigit(output[i - 1])) + if (!isDigit(output[i - 1])) break; output.insert(i, zen::getThousandsSeparator()); } @@ -164,10 +164,10 @@ std::wstring zen::ffs_Impl::includeNumberSeparator(const std::wstring& number) void zen::scrollToBottom(wxScrolledWindow* scrWindow) { int height = 0; - scrWindow->GetClientSize(NULL, &height); + scrWindow->GetClientSize(nullptr, &height); int pixelPerLine = 0; - scrWindow->GetScrollPixelsPerUnit(NULL, &pixelPerLine); + scrWindow->GetScrollPixelsPerUnit(nullptr, &pixelPerLine); if (height > 0 && pixelPerLine > 0) { @@ -203,7 +203,7 @@ std::wstring zen::utcToLocalTimeString(Int64 utcTime) &systemTimeUtc)) //__out LPSYSTEMTIME lpSystemTime return _("Error"); - if (!::SystemTimeToTzSpecificLocalTime(NULL, //__in_opt LPTIME_ZONE_INFORMATION lpTimeZone, + if (!::SystemTimeToTzSpecificLocalTime(nullptr, //__in_opt LPTIME_ZONE_INFORMATION lpTimeZone, &systemTimeUtc, //__in LPSYSTEMTIME lpUniversalTime, &systemTimeLocal)) //__out LPSYSTEMTIME lpLocalTime return _("Error"); diff --git a/wx+/format_unit.h b/wx+/format_unit.h index 361818cc..71501db7 100644 --- a/wx+/format_unit.h +++ b/wx+/format_unit.h @@ -57,7 +57,7 @@ std::wstring includeNumberSeparator(const std::wstring& number); template <class NumberType> inline std::wstring toStringSep(NumberType number) { - return ffs_Impl::includeNumberSeparator(zen::toString<std::wstring>(number)); + return ffs_Impl::includeNumberSeparator(zen::numberTo<std::wstring>(number)); } } diff --git a/wx+/graph.cpp b/wx+/graph.cpp index 7bbfa805..185121f1 100644 --- a/wx+/graph.cpp +++ b/wx+/graph.cpp @@ -20,6 +20,8 @@ using namespace numeric; const wxEventType zen::wxEVT_GRAPH_SELECTION = wxNewEventType(); +const std::shared_ptr<LabelFormatter> Graph2D::GraphAttributes::defaultFormat = std::make_shared<DecimalNumberFormatter>(); //for some buggy reason MSVC isn't able to use a temporary as a default argument instead + namespace { inline @@ -239,10 +241,10 @@ Graph2D::Graph2D(wxWindow* parent, const wxString& name) : wxPanel(parent, winid, pos, size, style, name) { - Connect(wxEVT_PAINT, wxPaintEventHandler(Graph2D::onPaintEvent), NULL, this); - Connect(wxEVT_SIZE, wxEventHandler(Graph2D::onRefreshRequired), NULL, this); + Connect(wxEVT_PAINT, wxPaintEventHandler(Graph2D::onPaintEvent), nullptr, this); + Connect(wxEVT_SIZE, wxEventHandler(Graph2D::onRefreshRequired), nullptr, this); //http://wiki.wxwidgets.org/Flicker-Free_Drawing - Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(Graph2D::onEraseBackGround), NULL, this); + Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(Graph2D::onEraseBackGround), nullptr, this); //SetDoubleBuffered(true); slow as hell! @@ -252,10 +254,10 @@ Graph2D::Graph2D(wxWindow* parent, SetBackgroundStyle(wxBG_STYLE_CUSTOM); #endif - Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(Graph2D::OnMouseLeftDown), NULL, this); - Connect(wxEVT_MOTION, wxMouseEventHandler(Graph2D::OnMouseMovement), NULL, this); - Connect(wxEVT_LEFT_UP, wxMouseEventHandler(Graph2D::OnMouseLeftUp), NULL, this); - Connect(wxEVT_MOUSE_CAPTURE_LOST, wxMouseCaptureLostEventHandler(Graph2D::OnMouseCaptureLost), NULL, this); + Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(Graph2D::OnMouseLeftDown), nullptr, this); + Connect(wxEVT_MOTION, wxMouseEventHandler(Graph2D::OnMouseMovement), nullptr, this); + Connect(wxEVT_LEFT_UP, wxMouseEventHandler(Graph2D::OnMouseLeftUp), nullptr, this); + Connect(wxEVT_MOUSE_CAPTURE_LOST, wxMouseCaptureLostEventHandler(Graph2D::OnMouseCaptureLost), nullptr, this); } @@ -483,11 +485,11 @@ void Graph2D::render(wxDC& dc) const wxPoint currentPos = activeSel->refCurrentPos() - dataOrigin; //normalize positions - restrict(startPos .x, 0, dataArea.width); //allow for one past the end(!) to enable "full range selections" - restrict(currentPos.x, 0, dataArea.width); // + confine(startPos .x, 0, dataArea.width); //allow for one past the end(!) to enable "full range selections" + confine(currentPos.x, 0, dataArea.width); // - restrict(startPos .y, 0, dataArea.height); // - restrict(currentPos.y, 0, dataArea.height); // + confine(startPos .y, 0, dataArea.height); // + confine(currentPos.y, 0, dataArea.height); // //save current selection as double coordinates activeSel->refSelection().from = SelectionBlock::Point(cvrtX.screenToReal(startPos.x + 0.5), //+0.5 start selection in the middle of a pixel @@ -547,7 +549,7 @@ void Graph2D::render(wxDC& dc) const if (!curve.empty()) { dc.SetPen(wxPen(j->second.color, j->second.lineWidth)); - dc.DrawLines(curve.size(), &curve[0]); + dc.DrawLines(static_cast<int>(curve.size()), &curve[0]); } } } diff --git a/wx+/graph.h b/wx+/graph.h index 19de4869..db52753b 100644 --- a/wx+/graph.h +++ b/wx+/graph.h @@ -93,12 +93,12 @@ double nextNiceNumber(double blockSize); //round to next number which is conveni struct DecimalNumberFormatter : public LabelFormatter { virtual double getOptimalBlockSize(double sizeProposed) const { return nextNiceNumber(sizeProposed); } - virtual wxString formatText(double value, double optimalBlockSize) const { return zen::toString<wxString>(value); } + virtual wxString formatText(double value, double optimalBlockSize) const { return zen::numberTo<wxString>(value); } }; //------------------------------------------------------------------------------------------------------------ //emit data selection event -//Usage: wnd.Connect(wxEVT_GRAPH_SELECTION, GraphSelectEventHandler(MyDlg::OnGraphSelection), NULL, this); +//Usage: wnd.Connect(wxEVT_GRAPH_SELECTION, GraphSelectEventHandler(MyDlg::OnGraphSelection), nullptr, this); // void MyDlg::OnGraphSelection(GraphSelectEvent& event); @@ -154,14 +154,14 @@ public: LineAttributes() : autoColor(true), lineWidth(2) {} LineAttributes& setColor(const wxColour& col) { color = col; autoColor = false; return *this; } - LineAttributes& setLineWidth(size_t width) { lineWidth = width; return *this; } + LineAttributes& setLineWidth(size_t width) { lineWidth = static_cast<int>(width); return *this; } private: friend class Graph2D; bool autoColor; wxColour color; - size_t lineWidth; + int lineWidth; }; void setData(const std::shared_ptr<GraphData>& data, const LineAttributes& attr = LineAttributes()); @@ -218,17 +218,19 @@ public: GraphAttributes& setAutoSize() { minXauto = true; maxXauto = true; minYauto = true; maxYauto = true; return *this; } - GraphAttributes& setLabelX(PosLabelX posX, size_t height = 25, const std::shared_ptr<LabelFormatter>& newLabelFmt = std::shared_ptr<LabelFormatter>(new DecimalNumberFormatter())) + static const std::shared_ptr<LabelFormatter> defaultFormat; + + GraphAttributes& setLabelX(PosLabelX posX, size_t height = 25, const std::shared_ptr<LabelFormatter>& newLabelFmt = defaultFormat) { labelposX = posX; - labelHeightX = height; + labelHeightX = static_cast<int>(height); labelFmtX = newLabelFmt; return *this; } - GraphAttributes& setLabelY(PosLabelY posY, size_t width = 60, const std::shared_ptr<LabelFormatter>& newLabelFmt = std::shared_ptr<LabelFormatter>(new DecimalNumberFormatter())) + GraphAttributes& setLabelY(PosLabelY posY, size_t width = 60, const std::shared_ptr<LabelFormatter>& newLabelFmt = defaultFormat) { labelposY = posY; - labelWidthY = width; + labelWidthY = static_cast<int>(width); labelFmtY = newLabelFmt; return *this; } @@ -249,11 +251,11 @@ public: double maxY; PosLabelX labelposX; - size_t labelHeightX; + int labelHeightX; std::shared_ptr<LabelFormatter> labelFmtX; PosLabelY labelposY; - size_t labelWidthY; + int labelWidthY; std::shared_ptr<LabelFormatter> labelFmtY; SelMode mouseSelMode; diff --git a/wx+/grid.cpp b/wx+/grid.cpp index bfb08eb1..10e427ef 100644 --- a/wx+/grid.cpp +++ b/wx+/grid.cpp @@ -105,7 +105,7 @@ private: //another fix for yet another poor wxWidgets implementation (wxDCClipper does *not* stack) -hash_map<wxDC*, wxRect> clippingAreas; +hash_map<wxDC*, wxRect> clippingAreas; //associate "active" clipping area with each DC class DcClipper { @@ -132,7 +132,7 @@ public: ~DcClipper() { dc_.DestroyClippingRegion(); - if (oldRect.get() != NULL) + if (oldRect.get() != nullptr) { dc_.SetClippingRegion(*oldRect); clippingAreas[&dc_] = *oldRect; @@ -159,13 +159,13 @@ const wxEventType zen::EVENT_GRID_MOUSE_RIGHT_UP = wxNewEventType(); const wxEventType zen::EVENT_GRID_SELECT_RANGE = wxNewEventType(); //---------------------------------------------------------------------------------------------------------------- -void GridData::renderRowBackgound(wxDC& dc, const wxRect& rect, int row, bool enabled, bool selected, bool hasFocus) +void GridData::renderRowBackgound(wxDC& dc, const wxRect& rect, size_t row, bool enabled, bool selected, bool hasFocus) { drawCellBackground(dc, rect, enabled, selected, hasFocus, getColorMainWinBackground()); } -void GridData::renderCell(Grid& grid, wxDC& dc, const wxRect& rect, int row, ColumnType colType) +void GridData::renderCell(Grid& grid, wxDC& dc, const wxRect& rect, size_t row, ColumnType colType) { wxRect rectTmp = drawCellBorder(dc, rect); @@ -175,7 +175,7 @@ void GridData::renderCell(Grid& grid, wxDC& dc, const wxRect& rect, int row, Col } -size_t GridData::getBestSize(wxDC& dc, int row, ColumnType colType) +size_t GridData::getBestSize(wxDC& dc, size_t row, ColumnType colType) { return dc.GetTextExtent(getValue(row, colType)).GetWidth() + 2 * COLUMN_BORDER_LEFT; //some border on left and right side } @@ -283,10 +283,10 @@ public: wxWindow(&parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS | wxBORDER_NONE, wxPanelNameStr), parent_(parent) { - Connect(wxEVT_PAINT, wxPaintEventHandler(SubWindow::onPaintEvent), NULL, this); - Connect(wxEVT_SIZE, wxEventHandler(SubWindow::onSizeEvent), NULL, this); + Connect(wxEVT_PAINT, wxPaintEventHandler(SubWindow::onPaintEvent), nullptr, this); + Connect(wxEVT_SIZE, wxEventHandler(SubWindow::onSizeEvent), nullptr, this); //http://wiki.wxwidgets.org/Flicker-Free_Drawing - Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(SubWindow::onEraseBackGround), NULL, this); + Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(SubWindow::onEraseBackGround), nullptr, this); //SetDoubleBuffered(true); slow as hell! @@ -296,28 +296,29 @@ public: SetBackgroundStyle(wxBG_STYLE_CUSTOM); #endif - Connect(wxEVT_SET_FOCUS, wxFocusEventHandler(SubWindow::onFocus), NULL, this); - Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(SubWindow::onFocus), NULL, this); - - Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(SubWindow::onMouseLeftDown ), NULL, this); - Connect(wxEVT_LEFT_UP, wxMouseEventHandler(SubWindow::onMouseLeftUp ), NULL, this); - Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(SubWindow::onMouseLeftDouble), NULL, this); - Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(SubWindow::onMouseRightDown ), NULL, this); - Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(SubWindow::onMouseRightUp ), NULL, this); - Connect(wxEVT_MOTION, wxMouseEventHandler(SubWindow::onMouseMovement ), NULL, this); - Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(SubWindow::onLeaveWindow ), NULL, this); - Connect(wxEVT_MOUSE_CAPTURE_LOST, wxMouseCaptureLostEventHandler(SubWindow::onMouseCaptureLost), NULL, this); - - Connect(wxEVT_CHAR, wxKeyEventHandler(SubWindow::onChar ), NULL, this); - Connect(wxEVT_KEY_UP, wxKeyEventHandler(SubWindow::onKeyUp ), NULL, this); - Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(SubWindow::onKeyDown), NULL, this); + Connect(wxEVT_SET_FOCUS, wxFocusEventHandler(SubWindow::onFocus), nullptr, this); + Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(SubWindow::onFocus), nullptr, this); + Connect(wxEVT_CHILD_FOCUS, wxEventHandler(SubWindow::onChildFocus), nullptr, this); + + Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(SubWindow::onMouseLeftDown ), nullptr, this); + Connect(wxEVT_LEFT_UP, wxMouseEventHandler(SubWindow::onMouseLeftUp ), nullptr, this); + Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(SubWindow::onMouseLeftDouble), nullptr, this); + Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(SubWindow::onMouseRightDown ), nullptr, this); + Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(SubWindow::onMouseRightUp ), nullptr, this); + Connect(wxEVT_MOTION, wxMouseEventHandler(SubWindow::onMouseMovement ), nullptr, this); + Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(SubWindow::onLeaveWindow ), nullptr, this); + Connect(wxEVT_MOUSE_CAPTURE_LOST, wxMouseCaptureLostEventHandler(SubWindow::onMouseCaptureLost), nullptr, this); + + Connect(wxEVT_CHAR, wxKeyEventHandler(SubWindow::onChar ), nullptr, this); + Connect(wxEVT_KEY_UP, wxKeyEventHandler(SubWindow::onKeyUp ), nullptr, this); + Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(SubWindow::onKeyDown), nullptr, this); } Grid& refParent() { return parent_; } const Grid& refParent() const { return parent_; } template <class T> - bool sendEventNow(T& event) //return "true" if a suitable event handler function was found and executed, and the function did not call wxEvent::Skip. + bool sendEventNow(T&& event) //take both "rvalue + lvalues", return "true" if a suitable event handler function was found and executed, and the function did not call wxEvent::Skip. { if (wxEvtHandler* evtHandler = parent_.GetEventHandler()) return evtHandler->ProcessEvent(event); @@ -333,7 +334,7 @@ protected: if (text != oldText) { if (text.IsEmpty()) - SetToolTip(NULL); //wxGTK doesn't allow wxToolTip with empty text! + SetToolTip(nullptr); //wxGTK doesn't allow wxToolTip with empty text! else { //wxWidgets bug: tooltip multiline property is defined by first tooltip text containing newlines or not (same is true for maximum width) @@ -351,6 +352,7 @@ private: virtual void render(wxDC& dc, const wxRect& rect) = 0; virtual void onFocus(wxFocusEvent& event) { event.Skip(); } + virtual void onChildFocus(wxEvent& event) {} //wxGTK::wxScrolledWindow automatically scrolls to child window when child gets focus -> prevent! virtual void onMouseLeftDown (wxMouseEvent& event) { event.Skip(); } virtual void onMouseLeftUp (wxMouseEvent& event) { event.Skip(); } @@ -437,51 +439,49 @@ public: SubWindow(parent), rowHeight(DEFAULT_ROW_HEIGHT) {} - int getBestWidth(int rowFrom, int rowTo) + int getBestWidth(ptrdiff_t rowFrom, ptrdiff_t rowTo) { wxClientDC dc(this); int bestWidth = 0; - for (int i = rowFrom; i <= rowTo; ++i) + for (ptrdiff_t i = rowFrom; i <= rowTo; ++i) bestWidth = std::max(bestWidth, dc.GetTextExtent(formatRow(i)).GetWidth() + 2 * ROW_LABEL_BORDER); return bestWidth; } - int getLogicalHeight() const { return refParent().getRowCount() * rowHeight; } + size_t getLogicalHeight() const { return refParent().getRowCount() * rowHeight; } - int getRowAtPos(int posY) const //returns < 0 if row not found + ptrdiff_t getRowAtPos(ptrdiff_t posY) const //returns < 0 if row not found { if (posY >= 0 && rowHeight > 0) { - const int row = posY / rowHeight; - if (row < static_cast<int>(refParent().getRowCount())) + const size_t row = posY / rowHeight; + if (row < refParent().getRowCount()) return row; } return -1; } - int getRowHeight() const { return rowHeight; } - void setRowHeight(int height) { rowHeight = height; } + ptrdiff_t getRowHeight() const { return std::max<ptrdiff_t>(1, rowHeight); } //guarantees to return size >= 1 ! + void setRowHeight(size_t height) { rowHeight = height; } - wxRect getRowLabelArea(int row) const //returns empty rect if row not found + wxRect getRowLabelArea(ptrdiff_t row) const { return wxRect(wxPoint(0, rowHeight * row), wxSize(GetClientSize().GetWidth(), rowHeight)); } - std::pair<int, int> getRowsOnClient(const wxRect& clientRect) const //returns range [begin, end) + std::pair<ptrdiff_t, ptrdiff_t> getRowsOnClient(const wxRect& clientRect) const //returns range [begin, end) { const int yFrom = refParent().CalcUnscrolledPosition(clientRect.GetTopLeft ()).y; const int yTo = refParent().CalcUnscrolledPosition(clientRect.GetBottomRight()).y; - const int rowBegin = std::max(yFrom / rowHeight, 0); - const int rowEnd = std::min((yTo / rowHeight) + 1, static_cast<int>(refParent().getRowCount())); - - return std::make_pair(rowBegin, rowEnd); + return std::make_pair(std::max<ptrdiff_t>(yFrom / rowHeight, 0), + std::min<ptrdiff_t>((yTo / rowHeight) + 1, refParent().getRowCount())); } private: - static wxString formatRow(int row) { return toStringSep(row + 1); } //convert number to std::wstring including thousands separator + static wxString formatRow(size_t row) { return toStringSep(row + 1); } //convert number to std::wstring including thousands separator virtual bool AcceptsFocus() const { return false; } @@ -497,9 +497,8 @@ private: dc.SetFont(labelFont); dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); - const std::pair<int, int> rowRange = getRowsOnClient(rect); //returns range [begin, end) - - for (int row = rowRange.first; row < rowRange.second; ++row) + auto rowRange = getRowsOnClient(rect); //returns range [begin, end) + for (auto row = rowRange.first; row < rowRange.second; ++row) { wxRect singleLabelArea = getRowLabelArea(row); if (singleLabelArea.GetHeight() > 0) @@ -510,7 +509,7 @@ private: } } - void drawRowLabel(wxDC& dc, const wxRect& rect, int row) + void drawRowLabel(wxDC& dc, const wxRect& rect, size_t row) { //clearArea(dc, rect, getColorRowLabel()); dc.GradientFillLinear(rect, COLOR_LABEL_GRADIENT_FROM, COLOR_LABEL_GRADIENT_TO, wxWEST); //clear overlapping cells @@ -540,7 +539,7 @@ private: virtual void onMouseMovement(wxMouseEvent& event) { refParent().redirectRowLabelEvent(event); } virtual void onMouseLeftUp (wxMouseEvent& event) { refParent().redirectRowLabelEvent(event); } - int rowHeight; + ptrdiff_t rowHeight; }; @@ -549,7 +548,7 @@ namespace class ColumnResizing { public: - ColumnResizing(wxWindow& wnd, int col, size_t compPos, int startWidth, int clientPosX) : + ColumnResizing(wxWindow& wnd, size_t col, size_t compPos, ptrdiff_t startWidth, int clientPosX) : wnd_(wnd), col_(col), compPos_(compPos), @@ -557,24 +556,24 @@ public: clientPosX_(clientPosX) { wnd_.CaptureMouse(); } ~ColumnResizing() { if (wnd_.HasCapture()) wnd_.ReleaseMouse(); } - int getColumn () const { return col_; } - size_t getComponentPos() const { return compPos_; } - int getStartWidth () const { return startWidth_; } - int getStartPosX () const { return clientPosX_; } + size_t getColumn () const { return col_; } + size_t getComponentPos() const { return compPos_; } + ptrdiff_t getStartWidth () const { return startWidth_; } + int getStartPosX () const { return clientPosX_; } private: wxWindow& wnd_; - const int col_; - const size_t compPos_; - const int startWidth_; - const int clientPosX_; + const size_t col_; + const size_t compPos_; + const ptrdiff_t startWidth_; + const int clientPosX_; }; class ColumnMove { public: - ColumnMove(wxWindow& wnd, int colFrom, size_t compPos, int clientPosX) : + ColumnMove(wxWindow& wnd, size_t colFrom, size_t compPos, int clientPosX) : wnd_(wnd), colFrom_(colFrom), compPos_(compPos), @@ -583,19 +582,19 @@ public: singleClick_(true) { wnd_.CaptureMouse(); } ~ColumnMove() { if (wnd_.HasCapture()) wnd_.ReleaseMouse(); } - int getColumnFrom() const { return colFrom_; } - int& refColumnTo() { return colTo_; } - size_t getComponentPos() const { return compPos_; } - int getStartPosX () const { return clientPosX_; } + size_t getColumnFrom() const { return colFrom_; } + size_t& refColumnTo() { return colTo_; } + size_t getComponentPos() const { return compPos_; } + int getStartPosX () const { return clientPosX_; } bool isRealMove() const { return !singleClick_; } - bool setRealMove() { return singleClick_ = false; } + void setRealMove() { singleClick_ = false; } private: wxWindow& wnd_; - const int colFrom_; + const size_t colFrom_; const size_t compPos_; - int colTo_; + size_t colTo_; const int clientPosX_; bool singleClick_; }; @@ -607,7 +606,7 @@ private: class Grid::ColLabelWin : public SubWindow { public: - ColLabelWin(Grid& parent) : SubWindow(parent), highlight(-1, 0) {} + ColLabelWin(Grid& parent) : SubWindow(parent) {} private: virtual bool AcceptsFocus() const { return false; } @@ -643,13 +642,14 @@ private: } } - void drawColumnLabel(wxDC& dc, const wxRect& rect, int col, ColumnType colType, size_t compPos) + void drawColumnLabel(wxDC& dc, const wxRect& rect, size_t col, ColumnType colType, size_t compPos) { if (auto dataView = refParent().getDataProvider(compPos)) { const bool isHighlighted = activeResizing ? col == activeResizing->getColumn () && compPos == activeResizing->getComponentPos() : //highlight column on mouse-over activeMove ? col == activeMove ->getColumnFrom() && compPos == activeMove ->getComponentPos() : - /**/ col == highlight.first && compPos == highlight.second; + highlight ? col == highlight->first && compPos == highlight->second : + false; DcClipper clip(dc, rect); dataView->renderColumnLabel(refParent(), dc, rect, colType, isHighlighted); @@ -680,9 +680,9 @@ private: { if (event.LeftDClick()) //auto-size visible range on double-click { - const int bestWidth = refParent().getBestColumnSize(action->col, action->compPos); //return -1 on error + const auto bestWidth = refParent().getBestColumnSize(action->col, action->compPos); //return -1 on error if (bestWidth >= 0) - refParent().setColWidth(action->col, action->compPos, std::max(COLUMN_MIN_WIDTH, bestWidth)); + refParent().setColWidth(action->col, action->compPos, std::max<ptrdiff_t>(COLUMN_MIN_WIDTH, bestWidth)); } else { @@ -707,8 +707,8 @@ private: { if (refParent().columnMoveAllowed(compPos)) { - const int colFrom = activeMove->getColumnFrom(); - int colTo = activeMove->refColumnTo(); + const auto colFrom = activeMove->getColumnFrom(); + auto colTo = activeMove->refColumnTo(); if (colTo > colFrom) //simulate "colFrom" deletion --colTo; @@ -718,12 +718,8 @@ private: } else //notify single label click { - const Opt<ColumnType> colType = refParent().colToType(activeMove->getColumnFrom(), compPos); - if (colType) - { - GridClickEvent clickEvent(EVENT_GRID_COL_LABEL_MOUSE_LEFT, event, -1, *colType, compPos); - sendEventNow(clickEvent); - } + if (const Opt<ColumnType> colType = refParent().colToType(activeMove->getColumnFrom(), compPos)) + sendEventNow(GridClickEvent(EVENT_GRID_COL_LABEL_MOUSE_LEFT, event, -1, *colType, compPos)); } activeMove.reset(); } @@ -747,19 +743,14 @@ private: if (action && action->wantResize) { //auto-size visible range on double-click - const int bestWidth = refParent().getBestColumnSize(action->col, action->compPos); //return -1 on error + const auto bestWidth = refParent().getBestColumnSize(action->col, action->compPos); //return -1 on error if (bestWidth >= 0) { - const size_t newWidth = std::max(COLUMN_MIN_WIDTH, bestWidth); + const auto newWidth = std::max<ptrdiff_t>(COLUMN_MIN_WIDTH, bestWidth); refParent().setColWidth(action->col, action->compPos, newWidth); - const Opt<ColumnType> colType = refParent().colToType(action->col, action->compPos); - if (colType) - { - //notify column resize - GridColumnResizeEvent sizeEvent(newWidth, *colType, action->compPos); - sendEventNow(sizeEvent); - } + if (const Opt<ColumnType> colType = refParent().colToType(action->col, action->compPos)) + sendEventNow(GridColumnResizeEvent(newWidth, *colType, action->compPos)); //notify column resize } } event.Skip(); @@ -769,23 +760,18 @@ private: { if (activeResizing) { - const int col = activeResizing->getColumn(); - const size_t compPos = activeResizing->getComponentPos(); + const auto col = activeResizing->getColumn(); + const auto compPos = activeResizing->getComponentPos(); if (Opt<size_t> colWidth = refParent().getAbsoluteWidth(col, compPos)) { - const int newWidth = std::max(COLUMN_MIN_WIDTH, activeResizing->getStartWidth() + event.GetPosition().x - activeResizing->getStartPosX()); - if (newWidth != static_cast<int>(*colWidth)) + const size_t newWidth = std::max<ptrdiff_t>(COLUMN_MIN_WIDTH, activeResizing->getStartWidth() + event.GetPosition().x - activeResizing->getStartPosX()); + if (newWidth != *colWidth) { refParent().setColWidth(col, compPos, newWidth); - const Opt<ColumnType> colType = refParent().colToType(col, compPos); - if (colType) - { - //notify column resize - GridColumnResizeEvent sizeEvent(newWidth, *colType, compPos); - sendEventNow(sizeEvent); - } + if (const Opt<ColumnType> colType = refParent().colToType(col, compPos)) + sendEventNow(GridColumnResizeEvent(static_cast<int>(newWidth), *colType, compPos)); //notify column resize refParent().Refresh(); } @@ -798,18 +784,16 @@ private: { activeMove->setRealMove(); - const int col = refParent().clientPosToMoveTargetColumn(event.GetPosition(), activeMove->getComponentPos()); + const auto col = refParent().clientPosToMoveTargetColumn(event.GetPosition(), activeMove->getComponentPos()); if (col >= 0) activeMove->refColumnTo() = col; } } else { - const Opt<ColAction> action = refParent().clientPosToColumnAction(event.GetPosition()); - if (action) + if (const Opt<ColAction> action = refParent().clientPosToColumnAction(event.GetPosition())) { - highlight.first = action->col; - highlight.second = action->compPos; + highlight.reset(new std::pair<size_t, size_t>(action->col, action->compPos)); if (action->wantResize) SetCursor(wxCURSOR_SIZEWE); //set window-local only! :) @@ -818,21 +802,18 @@ private: } else { - highlight.first = -1; + highlight.reset(); SetCursor(*wxSTANDARD_CURSOR); } } - //change tooltip + //update tooltip const wxString toolTip = [&]() -> wxString { const wxPoint absPos = refParent().CalcUnscrolledPosition(event.GetPosition()); - - const auto colInfo = refParent().getColumnAtPos(absPos.x); //returns (column type, compPos), column < 0 if not found - if (colInfo) + if (const auto colInfo = refParent().getColumnAtPos(absPos.x)) //returns (column type, compPos) { - auto prov = refParent().getDataProvider(colInfo->second); - if (prov) + if (auto prov = refParent().getDataProvider(colInfo->second)) return prov->getToolTip(colInfo->first); } return wxString(); @@ -845,30 +826,24 @@ private: virtual void onLeaveWindow(wxMouseEvent& event) { - highlight.first = -1; //onLeaveWindow() does not respect mouse capture! -> however highlight is drawn unconditionally during move/resize! + highlight.reset(); //onLeaveWindow() does not respect mouse capture! -> however highlight is drawn unconditionally during move/resize! Refresh(); event.Skip(); } virtual void onMouseRightDown(wxMouseEvent& event) { - const Opt<ColAction> action = refParent().clientPosToColumnAction(event.GetPosition()); - if (action) + if (const Opt<ColAction> action = refParent().clientPosToColumnAction(event.GetPosition())) { - const Opt<ColumnType> colType = refParent().colToType(action->col, action->compPos); - if (colType) - { - //notify right click - GridClickEvent clickEvent(EVENT_GRID_COL_LABEL_MOUSE_RIGHT, event, -1, *colType, action->compPos); - sendEventNow(clickEvent); - } + if (const Opt<ColumnType> colType = refParent().colToType(action->col, action->compPos)) + sendEventNow(GridClickEvent(EVENT_GRID_COL_LABEL_MOUSE_RIGHT, event, -1, *colType, action->compPos)); //notify right click } event.Skip(); } std::unique_ptr<ColumnResizing> activeResizing; std::unique_ptr<ColumnMove> activeMove; - std::pair<int, size_t> highlight; //(column, component) mouse-over, row < 0 if none + std::unique_ptr<std::pair<size_t, size_t>> highlight; //(column, component) mouse-over }; //---------------------------------------------------------------------------------------------------------------- @@ -882,19 +857,18 @@ public: ColLabelWin& colLabelWin) : SubWindow(parent), rowLabelWin_(rowLabelWin), colLabelWin_(colLabelWin), - cursor(-1, -1), - selectionAnchor(-1) {} + selectionAnchor(0) {} - void makeRowVisible(int row) + void makeRowVisible(size_t row) { const wxRect labelRect = rowLabelWin_.getRowLabelArea(row); //returns empty rect if column not found if (labelRect.height > 0) { int scrollPosX = 0; - refParent().GetViewStart(&scrollPosX, NULL); + refParent().GetViewStart(&scrollPosX, nullptr); int pixelsPerUnitY = 0; - refParent().GetScrollPixelsPerUnit(NULL, &pixelsPerUnitY); + refParent().GetScrollPixelsPerUnit(nullptr, &pixelsPerUnitY); if (pixelsPerUnitY <= 0) return; const int clientPosY = refParent().CalcScrolledPosition(labelRect.GetTopLeft()).y; @@ -925,12 +899,12 @@ public: } } - void setCursor(int row, size_t compPos) + void setCursor(size_t row, size_t compPos) { cursor = std::make_pair(row, compPos); selectionAnchor = row; } - std::pair<int, size_t> getCursor() const { return cursor; } // (row, component position) + std::pair<size_t, size_t> getCursor() const { return cursor; } // (row, component position) private: virtual void render(wxDC& dc, const wxRect& rect) @@ -956,8 +930,8 @@ private: std::vector<std::vector<VisibleColumn>> compAbsWidths = refParent().getAbsoluteWidths(); //resolve negative/stretched widths for (auto iterComp = compAbsWidths.begin(); iterComp != compAbsWidths.end(); ++iterComp) { - const int compWidth = std::accumulate(iterComp->begin(), iterComp->end(), 0, - [](int val, const VisibleColumn& vc) { return val + vc.width_; }); + const ptrdiff_t compWidth = std::accumulate(iterComp->begin(), iterComp->end(), static_cast<ptrdiff_t>(0), + [](ptrdiff_t sum, const VisibleColumn& vc) { return sum + vc.width_; }); const size_t compPos = iterComp - compAbsWidths.begin(); if (auto prov = refParent().getDataProvider(compPos)) @@ -1017,14 +991,9 @@ private: virtual void onMouseLeftDouble(wxMouseEvent& event) { const wxPoint absPos = refParent().CalcUnscrolledPosition(event.GetPosition()); - const int row = rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position - const auto colInfo = refParent().getColumnAtPos(absPos.x); //returns (column type, compPos), column < 0 if not found - if (colInfo) - { - //notify event - GridClickEvent mouseEvent(EVENT_GRID_MOUSE_LEFT_DOUBLE, event, row, colInfo->first, colInfo->second); - sendEventNow(mouseEvent); - } + const auto row = rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position + if (const auto colInfo = refParent().getColumnAtPos(absPos.x)) //returns (column type, compPos) + sendEventNow(GridClickEvent(EVENT_GRID_MOUSE_LEFT_DOUBLE, event, row, colInfo->first, colInfo->second)); event.Skip(); } @@ -1035,10 +1004,10 @@ private: const wxPoint absPos = refParent().CalcUnscrolledPosition(event.GetPosition()); - const int row = rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position - const auto colInfo = refParent().getColumnAtPos(absPos.x); //returns (column type, compPos), column < 0 if not found + const ptrdiff_t row = rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position + const auto colInfo = refParent().getColumnAtPos(absPos.x); //returns (column type, compPos) const ColumnType colType = colInfo ? colInfo->first : DUMMY_COLUMN_TYPE; - const int compPos = colInfo ? colInfo->second : -1; + const ptrdiff_t compPos = colInfo ? colInfo->second : -1; //notify event GridClickEvent mouseEvent(event.RightDown() ? EVENT_GRID_MOUSE_RIGHT_DOWN : EVENT_GRID_MOUSE_LEFT_DOWN, event, row, colType, compPos); @@ -1053,26 +1022,28 @@ private: { if (row >= 0 && compPos >= 0) activeSelection.reset(new MouseSelection(*this, row, compPos, !refParent().isSelected(row, compPos))); - selectionAnchor = row; + selectionAnchor = cursor.first; //[!] anchor is coupled with cursor, *not* row } else if (event.ShiftDown()) { if (row >= 0 && compPos >= 0) activeSelection.reset(new MouseSelection(*this, selectionAnchor, compPos, true)); + else + selectionAnchor = cursor.first; refParent().clearSelectionAll(); } else { if (row >= 0 && compPos >= 0) activeSelection.reset(new MouseSelection(*this, row, compPos, true)); - selectionAnchor = row; + selectionAnchor = cursor.first; refParent().clearSelectionAll(); } } Refresh(); } - event.Skip(); //allow changin focus + event.Skip(); //allow changing focus } void onMouseUp(wxMouseEvent& event) @@ -1081,10 +1052,10 @@ private: if (activeSelection) { - const int rowFrom = activeSelection->getStartRow(); - const int rowTo = activeSelection->getCurrentRow(); - const size_t compPos = activeSelection->getComponentPos(); - const bool positive = activeSelection->isPositiveSelect(); + const auto rowFrom = activeSelection->getStartRow(); + const auto rowTo = activeSelection->getCurrentRow(); + const auto compPos = activeSelection->getComponentPos(); + const bool positive = activeSelection->isPositiveSelect(); refParent().selectRange(rowFrom, rowTo, compPos, positive); cursor.first = activeSelection->getCurrentRow(); //slight deviation from Explorer: change cursor while dragging mouse! -> unify behavior with shift + direction keys @@ -1095,15 +1066,14 @@ private: //this one may point to row which is not in visible area! const wxPoint absPos = refParent().CalcUnscrolledPosition(event.GetPosition()); - const int row = rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position - const auto colInfo = refParent().getColumnAtPos(absPos.x); //returns (column type, compPos), column < 0 if not found + const auto row = rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position + const auto colInfo = refParent().getColumnAtPos(absPos.x); //returns optional pair (column type, compPos) const ColumnType colType = colInfo ? colInfo->first : DUMMY_COLUMN_TYPE; //we probably should notify even if colInfo is invalid! - const int compPos = colInfo ? colInfo->second : 0; + const size_t compPos = colInfo ? colInfo->second : 0; //notify event - GridClickEvent mouseEvent(event.RightUp() ? EVENT_GRID_MOUSE_RIGHT_UP : EVENT_GRID_MOUSE_LEFT_UP, event, row, colType, compPos); - sendEventNow(mouseEvent); + sendEventNow(GridClickEvent(event.RightUp() ? EVENT_GRID_MOUSE_RIGHT_UP : EVENT_GRID_MOUSE_LEFT_UP, event, row, colType, compPos)); Refresh(); event.Skip(); //allow changing focus @@ -1126,12 +1096,11 @@ private: { const wxPoint absPos = refParent().CalcUnscrolledPosition(event.GetPosition()); - const int row = rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position - const auto colInfo = refParent().getColumnAtPos(absPos.x); //returns (column type, compPos), column < 0 if not found + const auto row = rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position + const auto colInfo = refParent().getColumnAtPos(absPos.x); //returns (column type, compPos) if (colInfo && row >= 0) { - auto prov = refParent().getDataProvider(colInfo->second); - if (prov) + if (auto prov = refParent().getDataProvider(colInfo->second)) return prov->getToolTip(row, colInfo->first); } return wxString(); @@ -1157,27 +1126,33 @@ private: keyCode = WXK_NUMPAD_LEFT; } - const int rowCount = refParent().getRowCount(); + const ptrdiff_t rowCount = refParent().getRowCount(); + if (rowCount <= 0 || refParent().comp.empty()) + { + event.Skip(); + return; + } - auto setSingleSelection = [&](int row, int compPos) + auto setSingleSelection = [&](ptrdiff_t row, ptrdiff_t compPos) { - numeric::restrict(row, 0, rowCount - 1); - numeric::restrict(compPos, 0, static_cast<int>(refParent().comp.size()) - 1); - refParent().setGridCursor(row, compPos); + numeric::confine<ptrdiff_t>(row, 0, rowCount - 1); + numeric::confine<ptrdiff_t>(compPos, 0, refParent().comp.size() - 1); + refParent().setGridCursor(row, compPos); //behave like an "external" set cursor! }; - auto setSelectionRange = [&](int row) + auto setSelectionRange = [&](ptrdiff_t row) { - numeric::restrict(row, 0, rowCount - 1); + //unlike "setSingleSelection" this function doesn't seem to belong into Grid: management of selectionAnchor should be local - cursor.first = row; - if (selectionAnchor < 0) - selectionAnchor = row; - this->makeRowVisible(row); + numeric::confine<ptrdiff_t>(row, 0, rowCount - 1); auto& comp = refParent().comp; std::for_each(comp.begin(), comp.end(), [](Grid::Component& c) { c.selection.clear(); }); //clear selection, do NOT fire event refParent().selectRange(selectionAnchor, row, cursor.second); //set new selection + fire event + + cursor.first = row; //don't call setCursor() since it writes to "selectionAnchor"! + this->makeRowVisible(row); + refParent().Refresh(); }; switch (keyCode) @@ -1190,7 +1165,7 @@ private: refParent().scrollDelta(0, -1); else setSingleSelection(cursor.first - 1, cursor.second); - break; + return; //swallow event: wxScrolledWindow, wxWidgets 2.9.3 on Kubuntu x64 processes arrow keys: prevent this! case WXK_DOWN: case WXK_NUMPAD_DOWN: @@ -1200,7 +1175,7 @@ private: refParent().scrollDelta(0, 1); else setSingleSelection(cursor.first + 1, cursor.second); - break; + return; //swallow event case WXK_LEFT: case WXK_NUMPAD_LEFT: @@ -1210,7 +1185,7 @@ private: ; else setSingleSelection(cursor.first, cursor.second - 1); - break; + return; case WXK_RIGHT: case WXK_NUMPAD_RIGHT: @@ -1220,7 +1195,7 @@ private: ; else setSingleSelection(cursor.first, cursor.second + 1); - break; + return; case WXK_HOME: case WXK_NUMPAD_HOME: @@ -1230,7 +1205,7 @@ private: setSingleSelection(0, 0); else setSingleSelection(0, cursor.second); - break; + return; case WXK_END: case WXK_NUMPAD_END: @@ -1240,7 +1215,7 @@ private: setSingleSelection(rowCount - 1, refParent().comp.size() - 1); else setSingleSelection(rowCount - 1, cursor.second); - break; + return; case WXK_PAGEUP: case WXK_NUMPAD_PAGEUP: @@ -1250,7 +1225,7 @@ private: ; else setSingleSelection(cursor.first - GetClientSize().GetHeight() / rowLabelWin_.getRowHeight(), cursor.second); - break; + return; case WXK_PAGEDOWN: case WXK_NUMPAD_PAGEDOWN: @@ -1260,7 +1235,7 @@ private: ; else setSingleSelection(cursor.first + GetClientSize().GetHeight() / rowLabelWin_.getRowHeight(), cursor.second); - break; + return; case 'A': //Ctrl + A - select all if (event.ControlDown()) @@ -1270,10 +1245,9 @@ private: case WXK_NUMPAD_ADD: //CTRL + '+' - auto-size all if (event.ControlDown()) refParent().autoSizeColumns(cursor.second); - break; + return; } - Refresh(); event.Skip(); } @@ -1282,26 +1256,24 @@ private: class MouseSelection : private wxEvtHandler { public: - MouseSelection(MainWin& wnd, - int rowStart, - size_t compPos, - bool positiveSelect) : wnd_(wnd), rowStart_(rowStart), compPos_(compPos), rowCurrent_(rowStart), positiveSelect_(positiveSelect), toScrollX(0), toScrollY(0), tickCountLast(clock()) + MouseSelection(MainWin& wnd, ptrdiff_t rowStart, size_t compPos, bool positiveSelect) : + wnd_(wnd), rowStart_(rowStart), compPos_(compPos), rowCurrent_(rowStart), positiveSelect_(positiveSelect), toScrollX(0), toScrollY(0), tickCountLast(clock()) { wnd_.CaptureMouse(); - timer.Connect(wxEVT_TIMER, wxEventHandler(MouseSelection::onTimer), NULL, this); + timer.Connect(wxEVT_TIMER, wxEventHandler(MouseSelection::onTimer), nullptr, this); timer.Start(100); //timer interval in ms evalMousePos(); } ~MouseSelection() { if (wnd_.HasCapture()) wnd_.ReleaseMouse(); } - int getStartRow () const { return rowStart_; } - size_t getComponentPos () const { return compPos_; } - int getCurrentRow () const { return rowCurrent_; } - bool isPositiveSelect() const { return positiveSelect_; } //are we selecting or unselecting? + ptrdiff_t getStartRow () const { return rowStart_; } + size_t getComponentPos () const { return compPos_; } + ptrdiff_t getCurrentRow () const { return rowCurrent_; } + bool isPositiveSelect() const { return positiveSelect_; } //are we selecting or unselecting? void evalMousePos() { - const clock_t now = clock(); + const clock_t now = std::clock(); const double deltaTime = static_cast<double>(now - tickCountLast) / CLOCKS_PER_SEC; //unit: [sec] tickCountLast = now; @@ -1316,7 +1288,7 @@ private: clientPos.x >= clientSize.GetWidth() ? clientPos.x - (clientSize.GetWidth() - 1) : 0; int pixelsPerUnitY = 0; - wnd_.refParent().GetScrollPixelsPerUnit(NULL, &pixelsPerUnitY); + wnd_.refParent().GetScrollPixelsPerUnit(nullptr, &pixelsPerUnitY); if (pixelsPerUnitY <= 0) return; const double mouseDragSpeedIncScrollU = pixelsPerUnitY > 0 ? MOUSE_DRAG_ACCELERATION * wnd_.rowLabelWin_.getRowHeight() / pixelsPerUnitY : 0; //unit: [scroll units / (pixel * sec)] @@ -1345,14 +1317,14 @@ private: { //select current row *after* scrolling wxPoint clientPosTrimmed = clientPos; - numeric::restrict(clientPosTrimmed.y, 0, clientSize.GetHeight() - 1); //do not select row outside client window! + numeric::confine(clientPosTrimmed.y, 0, clientSize.GetHeight() - 1); //do not select row outside client window! wxPoint absPos = wnd_.refParent().CalcUnscrolledPosition(clientPosTrimmed); - int currentRow = wnd_.rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position //make sure "current row" is always at a valid position while moving! + ptrdiff_t currentRow = wnd_.rowLabelWin_.getRowAtPos(absPos.y); //return -1 if no row at this position if (currentRow < 0) - currentRow = static_cast<int>(wnd_.refParent().getRowCount()) - 1; //seems, we hit the empty space at the end + currentRow = wnd_.refParent().getRowCount() - 1; //seems, we hit the empty space at the end: empty size covered! if (currentRow >= 0 && rowCurrent_ != currentRow) { @@ -1366,9 +1338,9 @@ private: void onTimer(wxEvent& event) { evalMousePos(); } MainWin& wnd_; - const int rowStart_; + const ptrdiff_t rowStart_; const size_t compPos_; - int rowCurrent_; + ptrdiff_t rowCurrent_; const bool positiveSelect_; wxTimer timer; double toScrollX; //count outstanding scroll units to scroll while dragging mouse @@ -1391,8 +1363,8 @@ private: std::unique_ptr<MouseSelection> activeSelection; //bound while user is selecting with mouse - std::pair<int, int> cursor; //(row, component position) -1 if none - int selectionAnchor; //-1 if none + std::pair<ptrdiff_t, ptrdiff_t> cursor; //(row, component position), always valid! still unsigned type to facilitate "onKeyDown()" + size_t selectionAnchor; }; //---------------------------------------------------------------------------------------------------------------- @@ -1411,9 +1383,9 @@ Grid::Grid(wxWindow* parent, comp(1), colSizeOld(0) { - Connect(wxEVT_PAINT, wxPaintEventHandler(Grid::onPaintEvent ), NULL, this); - Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(Grid::onEraseBackGround), NULL, this); - Connect(wxEVT_SIZE, wxEventHandler (Grid::onSizeEvent ), NULL, this); + Connect(wxEVT_PAINT, wxPaintEventHandler(Grid::onPaintEvent ), nullptr, this); + Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(Grid::onEraseBackGround), nullptr, this); + Connect(wxEVT_SIZE, wxEventHandler (Grid::onSizeEvent ), nullptr, this); cornerWin_ = new CornerWin (*this); // rowLabelWin_ = new RowLabelWin(*this); //owership handled by "this" @@ -1440,7 +1412,6 @@ void Grid::updateWindowSizes(bool updateScrollbar) GetClientRect(); -> possibly trimmed by scrollbars /|\ mainWin_->GetClientSize() -> also trimmed, since it's a sub-window ! - */ //update scrollbars: showing/hiding scrollbars changes client size! @@ -1454,7 +1425,7 @@ void Grid::updateWindowSizes(bool updateScrollbar) int scrollPosY = 0; GetViewStart(&scrollPosX, &scrollPosY); //preserve current scroll position - const int pixPerScrollUnitY = std::max(1, rowLabelWin_->getRowHeight()); + const int pixPerScrollUnitY = rowLabelWin_->getRowHeight(); const int pixPerScrollUnitX = pixPerScrollUnitY; const int scrollUnitsX = std::ceil(static_cast<double>( getMinAbsoluteWidthTotal()) / pixPerScrollUnitX); @@ -1462,7 +1433,7 @@ void Grid::updateWindowSizes(bool updateScrollbar) SetScrollbars(pixPerScrollUnitX, pixPerScrollUnitY, //another abysmal wxWidgets design decision: why is precision needlessly reduced to "pixelsPerUnit"???? scrollUnitsX, scrollUnitsY, - scrollPosX, scrollPosY); + scrollPosX, scrollPosY); } const wxRect clientRect = GetClientRect(); @@ -1472,16 +1443,16 @@ void Grid::updateWindowSizes(bool updateScrollbar) int rowLabelWidth = 0; //calculate optimal row label width if (drawRowLabel) { - const int heightTotal = rowLabelWin_->getLogicalHeight(); + const auto heightTotal = rowLabelWin_->getLogicalHeight(); if (heightTotal > 0) { - int yFrom = CalcUnscrolledPosition(wxPoint(0, 0)).y; - int yTo = CalcUnscrolledPosition(wxPoint(0, mainWinHeight - 1)).y ; - numeric::restrict(yFrom, 0, heightTotal - 1); - numeric::restrict(yTo, 0, heightTotal - 1); + ptrdiff_t yFrom = CalcUnscrolledPosition(wxPoint(0, 0)).y; + ptrdiff_t yTo = CalcUnscrolledPosition(wxPoint(0, mainWinHeight - 1)).y ; + numeric::confine<ptrdiff_t>(yFrom, 0, heightTotal - 1); + numeric::confine<ptrdiff_t>(yTo, 0, heightTotal - 1); - const int rowFrom = rowLabelWin_->getRowAtPos(yFrom); - const int rowTo = rowLabelWin_->getRowAtPos(yTo); + const ptrdiff_t rowFrom = rowLabelWin_->getRowAtPos(yFrom); + const ptrdiff_t rowTo = rowLabelWin_->getRowAtPos(yTo); if (rowFrom >= 0 && rowTo >= 0) rowLabelWidth = rowLabelWin_->getBestWidth(rowFrom, rowTo); } @@ -1513,9 +1484,9 @@ void Grid::showRowLabel(bool show) } -std::vector<int> Grid::getSelectedRows(size_t compPos) const +std::vector<size_t> Grid::getSelectedRows(size_t compPos) const { - return compPos < comp.size() ? comp[compPos].selection.get() : std::vector<int>(); + return compPos < comp.size() ? comp[compPos].selection.get() : std::vector<size_t>(); } @@ -1532,8 +1503,8 @@ void Grid::scrollDelta(int deltaX, int deltaY) //const int unitsTotalY = GetScrollLines(wxVERTICAL); //if (unitsTotalX <= 0 || unitsTotalY <= 0) return; -> premature - //numeric::restrict(scrollPosX, 0, unitsTotalX - 1); //make sure scroll target is in valid range - //numeric::restrict(scrollPosY, 0, unitsTotalY - 1); // + //numeric::confine(scrollPosX, 0, unitsTotalX - 1); //make sure scroll target is in valid range + //numeric::confine(scrollPosY, 0, unitsTotalY - 1); // Scroll(scrollPosX, scrollPosY); updateWindowSizes(); //may show horizontal scroll bar @@ -1543,7 +1514,8 @@ void Grid::scrollDelta(int deltaX, int deltaY) void Grid::redirectRowLabelEvent(wxMouseEvent& event) { event.m_x = 0; - mainWin_->ProcessEvent(event); + if (wxEvtHandler* evtHandler = mainWin_->GetEventHandler()) + evtHandler->ProcessEvent(event); if (event.ButtonDown() && wxWindow::FindFocus() != mainWin_) mainWin_->SetFocus(); @@ -1569,7 +1541,7 @@ void Grid::Refresh(bool eraseBackground, const wxRect* rect) } -void Grid::setRowHeight(int height) +void Grid::setRowHeight(size_t height) { rowLabelWin_->setRowHeight(height); updateWindowSizes(); @@ -1707,13 +1679,15 @@ wxRect Grid::getColumnLabelArea(ColumnType colType, size_t compPos) const auto iterCol = std::find_if(iterComp->begin(), iterComp->end(), [&](const VisibleColumn& vc) { return vc.type_ == colType; }); if (iterCol != iterComp->end()) { - int posX = std::accumulate(compAbsWidths.begin(), iterComp, 0, - [](int val, const std::vector<VisibleColumn>& cols) + ptrdiff_t posX = std::accumulate(compAbsWidths.begin(), iterComp, static_cast<ptrdiff_t>(0), + [](ptrdiff_t sum, const std::vector<VisibleColumn>& cols) { - return val + std::accumulate(cols.begin(), cols.end(), 0, [](int val2, const VisibleColumn& vc) { return val2 + vc.width_; }); + return sum + std::accumulate(cols.begin(), cols.end(), static_cast<ptrdiff_t>(0), + [](ptrdiff_t val2, const VisibleColumn& vc) { return val2 + vc.width_; }); }); - posX += std::accumulate(iterComp->begin(), iterCol, 0, [](int val, const VisibleColumn& vc) { return val + vc.width_; }); + posX += std::accumulate(iterComp->begin(), iterCol, static_cast<ptrdiff_t>(0), + [](ptrdiff_t sum, const VisibleColumn& vc) { return sum + vc.width_; }); return wxRect(wxPoint(posX, 0), wxSize(iterCol->width_, colLabelHeight)); } @@ -1727,7 +1701,7 @@ Opt<Grid::ColAction> Grid::clientPosToColumnAction(const wxPoint& pos) const const int absPosX = CalcUnscrolledPosition(pos).x; if (absPosX >= 0) { - int accuWidth = 0; + ptrdiff_t accuWidth = 0; std::vector<std::vector<VisibleColumn>> compAbsWidths = getAbsoluteWidths(); //resolve negative/stretched widths for (auto iterComp = compAbsWidths.begin(); iterComp != compAbsWidths.end(); ++iterComp) @@ -1780,7 +1754,7 @@ void Grid::moveColumn(size_t colFrom, size_t colTo, size_t compPos) } -int Grid::clientPosToMoveTargetColumn(const wxPoint& pos, size_t compPos) const +ptrdiff_t Grid::clientPosToMoveTargetColumn(const wxPoint& pos, size_t compPos) const { std::vector<std::vector<VisibleColumn>> compAbsWidths = getAbsoluteWidths(); //resolve negative/stretched widths if (compPos < compAbsWidths.size()) @@ -1788,16 +1762,16 @@ int Grid::clientPosToMoveTargetColumn(const wxPoint& pos, size_t compPos) const auto iterComp = compAbsWidths.begin() + compPos; const int absPosX = CalcUnscrolledPosition(pos).x; - int accuWidth = std::accumulate(compAbsWidths.begin(), iterComp, 0, - [](int val, const std::vector<VisibleColumn>& cols) + ptrdiff_t accuWidth = std::accumulate(compAbsWidths.begin(), iterComp, static_cast<ptrdiff_t>(0), + [](ptrdiff_t sum, const std::vector<VisibleColumn>& cols) { - return val + std::accumulate(cols.begin(), cols.end(), 0, - [](int val2, const VisibleColumn& vc) { return val2 + vc.width_; }); + return sum + std::accumulate(cols.begin(), cols.end(), static_cast<ptrdiff_t>(0), + [](ptrdiff_t sum2, const VisibleColumn& vc) { return sum2 + vc.width_; }); }); for (auto iterCol = iterComp->begin(); iterCol != iterComp->end(); ++iterCol) { - const int width = iterCol->width_; //beware dreaded unsigned conversions! + const ptrdiff_t width = iterCol->width_; //beware dreaded unsigned conversions! accuWidth += width; if (absPosX < accuWidth - width / 2) @@ -1821,7 +1795,7 @@ Opt<ColumnType> Grid::colToType(size_t col, size_t compPos) const } -int Grid::getRowAtPos(int posY) const { return rowLabelWin_->getRowAtPos(posY); } +ptrdiff_t Grid::getRowAtPos(int posY) const { return rowLabelWin_->getRowAtPos(posY); } Opt<std::pair<ColumnType, size_t>> Grid::getColumnAtPos(int posX) const @@ -1830,7 +1804,7 @@ Opt<std::pair<ColumnType, size_t>> Grid::getColumnAtPos(int posX) const { std::vector<std::vector<VisibleColumn>> compAbsWidths = getAbsoluteWidths(); //resolve negative/stretched widths - int accWidth = 0; + ptrdiff_t accWidth = 0; for (auto iterComp = compAbsWidths.begin(); iterComp != compAbsWidths.end(); ++iterComp) for (auto iterCol = iterComp->begin(); iterCol != iterComp->end(); ++iterCol) { @@ -1846,7 +1820,7 @@ Opt<std::pair<ColumnType, size_t>> Grid::getColumnAtPos(int posX) const } -wxRect Grid::getCellArea(int row, ColumnType colType, size_t compPos) const +wxRect Grid::getCellArea(size_t row, ColumnType colType, size_t compPos) const { const wxRect& colArea = getColumnLabelArea(colType, compPos); const wxRect& rowArea = rowLabelWin_->getRowLabelArea(row); @@ -1854,7 +1828,7 @@ wxRect Grid::getCellArea(int row, ColumnType colType, size_t compPos) const } -void Grid::setGridCursor(int row, size_t compPos) +void Grid::setGridCursor(size_t row, size_t compPos) { if (compPos < comp.size()) { @@ -1864,11 +1838,12 @@ void Grid::setGridCursor(int row, size_t compPos) mainWin_->setCursor(row, compPos); mainWin_->makeRowVisible(row); mainWin_->Refresh(); + rowLabelWin_->Refresh(); //row labels! (Kubuntu) } } -void Grid::selectRange(int rowFrom, int rowTo, size_t compPos, bool positive) +void Grid::selectRange(ptrdiff_t rowFrom, ptrdiff_t rowTo, size_t compPos, bool positive) { if (compPos < comp.size()) { @@ -1893,17 +1868,17 @@ void Grid::clearSelectionAll() } -void Grid::scrollTo(int row) +void Grid::scrollTo(size_t row) { const wxRect labelRect = rowLabelWin_->getRowLabelArea(row); //returns empty rect if column not found if (labelRect.height > 0) { int pixelsPerUnitY = 0; - GetScrollPixelsPerUnit(NULL, &pixelsPerUnitY); - if (pixelsPerUnitY >= 0) + GetScrollPixelsPerUnit(nullptr, &pixelsPerUnitY); + if (pixelsPerUnitY > 0) { int scrollPosX = 0; - GetViewStart(&scrollPosX, NULL); + GetViewStart(&scrollPosX, nullptr); int scrollPosY = labelRect.GetTopLeft().y / pixelsPerUnitY; Scroll(scrollPosX, scrollPosY); @@ -1914,13 +1889,13 @@ void Grid::scrollTo(int row) } -std::pair<int, size_t> Grid::getGridCursor() const +std::pair<size_t, size_t> Grid::getGridCursor() const { return mainWin_->getCursor(); } -int Grid::getBestColumnSize(size_t col, size_t compPos) const +ptrdiff_t Grid::getBestColumnSize(size_t col, size_t compPos) const { if (compPos < comp.size()) { @@ -1934,9 +1909,9 @@ int Grid::getBestColumnSize(size_t col, size_t compPos) const dc.SetFont(mainWin_->GetFont()); size_t maxSize = 0; - const std::pair<int, int> rowRange = rowLabelWin_->getRowsOnClient(mainWin_->GetClientRect()); //returns range [begin, end) - for (int row = rowRange.first; row < rowRange.second; ++row) + auto rowRange = rowLabelWin_->getRowsOnClient(mainWin_->GetClientRect()); //returns range [begin, end) + for (auto row = rowRange.first; row < rowRange.second; ++row) maxSize = std::max(maxSize, dataView->getBestSize(dc, row, type)); return maxSize; @@ -1957,13 +1932,12 @@ void Grid::autoSizeColumns(size_t compPos) const int bestWidth = getBestColumnSize(col, compPos); //return -1 on error if (bestWidth >= 0) { - const size_t newWidth = std::max(COLUMN_MIN_WIDTH, bestWidth); + const auto newWidth = std::max(COLUMN_MIN_WIDTH, bestWidth); iter->width_ = newWidth; //notify column resize (asynchronously!) GridColumnResizeEvent sizeEvent(newWidth, iter->type_, compPos); - wxEvtHandler* evtHandler = GetEventHandler(); - if (evtHandler) + if (wxEvtHandler* evtHandler = GetEventHandler()) evtHandler->AddPendingEvent(sizeEvent); } } @@ -1973,9 +1947,9 @@ void Grid::autoSizeColumns(size_t compPos) } -int Grid::getMinAbsoluteWidthTotal() const +ptrdiff_t Grid::getMinAbsoluteWidthTotal() const { - int minWidthTotal = 0; + ptrdiff_t minWidthTotal = 0; //bool haveStretchedCols = false; std::for_each(comp.begin(), comp.end(), [&](const Component& c) @@ -2000,9 +1974,9 @@ std::vector<std::vector<Grid::VisibleColumn>> Grid::getAbsoluteWidths() const // { std::vector<std::vector<VisibleColumn>> output; - std::vector<std::pair<int, VisibleColumn*>> stretchedCols; //(factor, column to stretch) - int factorTotal = 0; - int minWidthTotal = 0; + std::vector<std::pair<ptrdiff_t, VisibleColumn*>> stretchedCols; //(factor, column to stretch) + ptrdiff_t factorTotal = 0; + ptrdiff_t minWidthTotal = 0; output.reserve(comp.size()); std::for_each(comp.begin(), comp.end(), @@ -2033,13 +2007,13 @@ std::vector<std::vector<Grid::VisibleColumn>> Grid::getAbsoluteWidths() const // if (!stretchedCols.empty()) { - const int widthToFill = mainWin_->GetClientSize().GetWidth() - minWidthTotal; + const ptrdiff_t widthToFill = mainWin_->GetClientSize().GetWidth() - minWidthTotal; if (widthToFill > 0) { int widthRemaining = widthToFill; for (auto iter = stretchedCols.begin(); iter != stretchedCols.end(); ++iter) { - const int addWidth = (widthToFill * iter->first) / factorTotal; //round down + const ptrdiff_t addWidth = (widthToFill * iter->first) / factorTotal; //round down iter->second->width_ += addWidth; widthRemaining -= addWidth; } @@ -35,7 +35,7 @@ extern const wxEventType EVENT_GRID_SELECT_RANGE; //generates: GridRangeSelectEv //NOTE: neither first nor second row need to match EVENT_GRID_MOUSE_LEFT_DOWN/EVENT_GRID_MOUSE_LEFT_UP: user holding SHIFT; moving out of window... //=> range always specifies *valid* rows -//example: wnd.Connect(EVENT_GRID_COL_LABEL_LEFT_CLICK, GridClickEventHandler(MyDlg::OnLeftClick), NULL, this); +//example: wnd.Connect(EVENT_GRID_COL_LABEL_LEFT_CLICK, GridClickEventHandler(MyDlg::OnLeftClick), nullptr, this); struct GridClickEvent : public wxMouseEvent @@ -96,11 +96,11 @@ public: virtual size_t getRowCount() const = 0; //if there are multiple grid components, only the first one will be polled for row count! //grid area - virtual wxString getValue(int row, ColumnType colType) const = 0; - virtual void renderRowBackgound(wxDC& dc, const wxRect& rect, int row, bool enabled, bool selected, bool hasFocus); //default implementation - virtual void renderCell(Grid& grid, wxDC& dc, const wxRect& rect, int row, ColumnType colType); // - virtual size_t getBestSize(wxDC& dc, int row, ColumnType colType); //must correspond to renderCell()! - virtual wxString getToolTip(int row, ColumnType colType) const { return wxString(); } + virtual wxString getValue(size_t row, ColumnType colType) const = 0; + virtual void renderRowBackgound(wxDC& dc, const wxRect& rect, size_t row, bool enabled, bool selected, bool hasFocus); //default implementation + virtual void renderCell(Grid& grid, wxDC& dc, const wxRect& rect, size_t row, ColumnType colType); // + virtual size_t getBestSize(wxDC& dc, size_t row, ColumnType colType); //must correspond to renderCell()! + virtual wxString getToolTip(size_t row, ColumnType colType) const { return wxString(); } //label area virtual wxString getColumnLabel(ColumnType colType) const = 0; @@ -130,7 +130,7 @@ public: size_t getRowCount() const; - void setRowHeight(int height); + void setRowHeight(size_t height); //grid component := a grid is divided into multiple components each of which is essentially a set of connected columns void setComponentCount(size_t count) { comp.resize(count); updateWindowSizes(); } @@ -148,8 +148,8 @@ public: std::vector<ColumnAttribute> getColumnConfig(size_t compPos = 0) const; void setDataProvider(const std::shared_ptr<GridData>& dataView, size_t compPos = 0) { if (compPos < comp.size()) comp[compPos].dataView_ = dataView; } - /**/ GridData* getDataProvider(size_t compPos = 0) { return compPos < comp.size() ? comp[compPos].dataView_.get() : NULL; } - const GridData* getDataProvider(size_t compPos = 0) const { return compPos < comp.size() ? comp[compPos].dataView_.get() : NULL; } + /**/ GridData* getDataProvider(size_t compPos = 0) { return compPos < comp.size() ? comp[compPos].dataView_.get() : nullptr; } + const GridData* getDataProvider(size_t compPos = 0) const { return compPos < comp.size() ? comp[compPos].dataView_.get() : nullptr; } //----------------------------------------------------------------------------- void setColumnLabelHeight(int height); @@ -157,7 +157,7 @@ public: void showScrollBars(bool horizontal, bool vertical); - std::vector<int> getSelectedRows(size_t compPos = 0) const; + std::vector<size_t> getSelectedRows(size_t compPos = 0) const; void clearSelection(size_t compPos = 0) { if (compPos < comp.size()) comp[compPos].selection.clear(); } void scrollDelta(int deltaX, int deltaY); //in scroll units @@ -167,20 +167,20 @@ public: wxWindow& getColLabelWin(); wxWindow& getMainWin (); - int getRowAtPos(int posY) const; //returns < 0 if column not found; absolute coordinates! + ptrdiff_t getRowAtPos(int posY) const; //returns < 0 if column not found; absolute coordinates! Opt<std::pair<ColumnType, size_t>> getColumnAtPos(int posX) const; //returns (column type, component pos) - wxRect getCellArea(int row, ColumnType colType, size_t compPos = 0) const; //returns empty rect if column not found; absolute coordinates! + wxRect getCellArea(size_t row, ColumnType colType, size_t compPos = 0) const; //returns empty rect if column not found; absolute coordinates! void enableColumnMove (bool value, size_t compPos = 0) { if (compPos < comp.size()) comp[compPos].allowColumnMove = value; } void enableColumnResize(bool value, size_t compPos = 0) { if (compPos < comp.size()) comp[compPos].allowColumnResize = value; } - void setGridCursor(int row, size_t compPos = 0); //set + show + select cursor - std::pair<int, size_t> getGridCursor() const; //(row, component pos) row == -1 if none + void setGridCursor(size_t row, size_t compPos = 0); //set + show + select cursor + std::pair<size_t, size_t> getGridCursor() const; //(row, component pos) - void scrollTo(int row); + void scrollTo(size_t row); - virtual void Refresh(bool eraseBackground = true, const wxRect* rect = NULL); + virtual void Refresh(bool eraseBackground = true, const wxRect* rect = nullptr); virtual bool Enable( bool enable = true) { Refresh(); return wxScrolledWindow::Enable(enable); } void autoSizeColumns(size_t compPos = 0); @@ -198,7 +198,7 @@ private: void SetScrollbar(int orientation, int position, int thumbSize, int range, bool refresh); //get rid of scrollbars, but preserve scrolling behavior! #endif - int getBestColumnSize(size_t col, size_t compPos) const; //return -1 on error + ptrdiff_t getBestColumnSize(size_t col, size_t compPos) const; //return -1 on error friend class GridData; class SubWindow; @@ -212,9 +212,9 @@ private: public: void init(size_t rowCount) { rowSelectionValue.resize(rowCount); clear(); } - std::vector<int> get() const + std::vector<size_t> get() const { - std::vector<int> selection; + std::vector<size_t> selection; for (auto iter = rowSelectionValue.begin(); iter != rowSelectionValue.end(); ++iter) if (*iter != 0) selection.push_back(iter - rowSelectionValue.begin()); @@ -225,13 +225,13 @@ private: bool isSelected(size_t row) const { return row < rowSelectionValue.size() ? rowSelectionValue[row] != 0 : false; } - void selectRange(int rowFrom, int rowTo, bool positive = true) //select [rowFrom, rowTo], very tolerant: trims and swaps if required! + void selectRange(ptrdiff_t rowFrom, ptrdiff_t rowTo, bool positive = true) //select [rowFrom, rowTo], very tolerant: trims and swaps if required! { - int rowFirst = std::min(rowFrom, rowTo); - int rowLast = std::max(rowFrom, rowTo) + 1; + auto rowFirst = std::min(rowFrom, rowTo); + auto rowLast = std::max(rowFrom, rowTo) + 1; - numeric::restrict(rowFirst, 0, static_cast<int>(rowSelectionValue.size())); - numeric::restrict(rowLast, 0, static_cast<int>(rowSelectionValue.size())); + numeric::confine<ptrdiff_t>(rowFirst, 0, rowSelectionValue.size()); + numeric::confine<ptrdiff_t>(rowLast, 0, rowSelectionValue.size()); std::fill(rowSelectionValue.begin() + rowFirst, rowSelectionValue.begin() + rowLast, positive); } @@ -242,9 +242,9 @@ private: struct VisibleColumn { - VisibleColumn(ColumnType type, int width) : type_(type), width_(width) {} + VisibleColumn(ColumnType type, ptrdiff_t width) : type_(type), width_(width) {} ColumnType type_; - int width_; //may be NEGATIVE => treat as proportional stretch! use getAbsoluteWidths() to evaluate!!! + ptrdiff_t width_; //may be NEGATIVE => treat as proportional stretch! use getAbsoluteWidths() to evaluate!!! }; struct Component @@ -260,7 +260,7 @@ private: std::vector<ColumnAttribute> oldColAttributes; //visible + nonvisible columns; use for conversion in setColumnConfig()/getColumnConfig() *only*! }; - int getMinAbsoluteWidthTotal() const; //assigns minimum width to stretched columns + ptrdiff_t getMinAbsoluteWidthTotal() const; //assigns minimum width to stretched columns std::vector<std::vector<VisibleColumn>> getAbsoluteWidths() const; //evaluate negative widths as stretched absolute values! structure matches "comp" Opt<size_t> getAbsoluteWidth(size_t col, size_t compPos) const //resolve stretched columns @@ -271,7 +271,7 @@ private: return NoValue(); } - void setColWidth(size_t col, size_t compPos, int width) //width may be >= 0: absolute, or < 0: stretched + void setColWidth(size_t col, size_t compPos, ptrdiff_t width) //width may be >= 0: absolute, or < 0: stretched { if (compPos < comp.size() && col < comp[compPos].visibleCols.size()) comp[compPos].visibleCols[col].width_ = width; @@ -279,10 +279,11 @@ private: wxRect getColumnLabelArea(ColumnType colType, size_t compPos) const; //returns empty rect if column not found - void selectRange(int rowFrom, int rowTo, size_t compPos, bool positive = true); //select range + notify event! + void selectRange(ptrdiff_t rowFrom, ptrdiff_t rowTo, size_t compPos, bool positive = true); //select range + notify event! + void clearSelectionAll(); //clear selection + notify event - bool isSelected(int row, size_t compPos) const { return compPos < comp.size() ? comp[compPos].selection.isSelected(row) : false; } + bool isSelected(size_t row, size_t compPos) const { return compPos < comp.size() ? comp[compPos].selection.isSelected(row) : false; } bool columnMoveAllowed (size_t compPos) const { return compPos < comp.size() ? comp[compPos].allowColumnMove : false; } bool columnResizeAllowed(size_t compPos) const { return compPos < comp.size() ? comp[compPos].allowColumnResize : false; } @@ -295,11 +296,10 @@ private: }; Opt<ColAction> clientPosToColumnAction(const wxPoint& pos) const; void moveColumn(size_t colFrom, size_t colTo, size_t compPos); - int clientPosToMoveTargetColumn(const wxPoint& pos, size_t compPos) const; + ptrdiff_t clientPosToMoveTargetColumn(const wxPoint& pos, size_t compPos) const; //return < 0 on error Opt<ColumnType> colToType(size_t col, size_t compPos) const; - /* Visual layout: ------------------------------------------------ diff --git a/wx+/mouse_move_dlg.cpp b/wx+/mouse_move_dlg.cpp index 20e6d420..697a5d47 100644 --- a/wx+/mouse_move_dlg.cpp +++ b/wx+/mouse_move_dlg.cpp @@ -49,7 +49,7 @@ MouseMoveWindow::MouseMoveWindow(wxWindow& parent, bool includeParent) : wxWindo dynamic_cast<wxPanel*> (&wnd) || dynamic_cast<wxFrame*> (&wnd) || dynamic_cast<wxDialog*> (&wnd)) - wnd.Connect(wxEVT_LEFT_DOWN, memFunMouseDown, NULL, this); + wnd.Connect(wxEVT_LEFT_DOWN, memFunMouseDown, nullptr, this); }; if (includeParent) diff --git a/wx+/no_flicker.h b/wx+/no_flicker.h index f745a12a..22952977 100644 --- a/wx+/no_flicker.h +++ b/wx+/no_flicker.h @@ -12,7 +12,7 @@ namespace zen { inline -void setText(wxTextCtrl& control, const wxString& newText, bool* additionalLayoutChange = NULL) +void setText(wxTextCtrl& control, const wxString& newText, bool* additionalLayoutChange = nullptr) { if (additionalLayoutChange && !*additionalLayoutChange) //never revert from true to false! *additionalLayoutChange = control.GetValue().length() != newText.length(); //avoid screen flicker: update layout only when necessary @@ -22,7 +22,7 @@ void setText(wxTextCtrl& control, const wxString& newText, bool* additionalLayou } inline -void setText(wxStaticText& control, const wxString& newText, bool* additionalLayoutChange = NULL) +void setText(wxStaticText& control, const wxString& newText, bool* additionalLayoutChange = nullptr) { if (additionalLayoutChange && !*additionalLayoutChange) *additionalLayoutChange = control.GetLabel().length() != newText.length(); //avoid screen flicker: update layout only when necessary @@ -101,6 +101,6 @@ #include <stdexcept> //Boost -#include <boost/scoped_array.hpp> + #endif //FFS_PRECOMPILED_HEADER diff --git a/wx+/serialize.h b/wx+/serialize.h index 4a06c001..b6a478cd 100644 --- a/wx+/serialize.h +++ b/wx+/serialize.h @@ -51,43 +51,54 @@ private: }; -//wxInputStream proxy throwing FileError on error -class CheckedReader +class CheckedIo +{ +protected: + CheckedIo(wxStreamBase& stream) : stream_(stream) {} + + void check() const + { + if (stream_.GetLastError() != wxSTREAM_NO_ERROR) + throwException(); + } + virtual void throwException() const = 0; + +private: + wxStreamBase& stream_; +}; + + +//wxInputStream proxy throwing exception on error +class CheckedReader : private CheckedIo { public: - CheckedReader(wxInputStream& stream, const Zstring& errorObjName) : stream_(stream), errorObjName_(errorObjName) {} + CheckedReader(wxInputStream& stream) : CheckedIo(stream), stream_(stream) {} template <class T> - T readNumberC() const; //throw FileError, checked read operation + T readPOD() const; //throw! template <class S> - S readStringC() const; //throw FileError, checked read operation + S readString() const; //throw! private: - void check() const; - wxInputStream& stream_; - const Zstring& errorObjName_; //used for error text only }; //wxOutputStream proxy throwing FileError on error -class CheckedWriter +class CheckedWriter : private CheckedIo { public: - CheckedWriter(wxOutputStream& stream, const Zstring& errorObjName) : stream_(stream), errorObjName_(errorObjName) {} + CheckedWriter(wxOutputStream& stream) : CheckedIo(stream), stream_(stream) {} template <class T> - void writeNumberC(T number) const; //throw FileError, checked write operation + void writePOD(T number) const; //throw! template <class S> - void writeStringC(const S& str) const; //throw FileError, checked write operation + void writeString(const S& str) const; //throw! private: - void check() const; - wxOutputStream& stream_; - const Zstring& errorObjName_; //used for error text only! }; @@ -139,8 +150,11 @@ S readString(wxInputStream& stream) const auto strLength = readPOD<std::uint32_t>(stream); S output; - output.resize(strLength); //throw std::bad_alloc - stream.Read(&*output.begin(), sizeof(CharType) * strLength); + if (strLength > 0) + { + output.resize(strLength); //throw std::bad_alloc + stream.Read(&*output.begin(), sizeof(CharType) * strLength); + } return output; } @@ -153,68 +167,49 @@ void writeString(wxOutputStream& stream, const S& str) } -inline -void CheckedReader::check() const -{ - if (stream_.GetLastError() != wxSTREAM_NO_ERROR) - throw zen::FileError(_("Error reading from synchronization database:") + L" \n" + L"\"" + errorObjName_ + L"\""); -} - - template <class T> inline -T CheckedReader::readNumberC() const //checked read operation +T CheckedReader::readPOD() const //checked read operation { - T output = readPOD<T>(stream_); + T output = zen::readPOD<T>(stream_); check(); return output; } template <class S> inline -S CheckedReader::readStringC() const //checked read operation +S CheckedReader::readString() const //checked read operation { S output; try { - output = readString<S>(stream_); //throw std::bad_alloc - check(); - if (stream_.LastRead() != output.length() * sizeof(typename S::value_type)) //some additional check - throw FileError(_("Error reading from synchronization database:") + L" \n" + L"\"" + errorObjName_ + L"\""); - } - catch (std::exception&) - { - throw FileError(_("Error reading from synchronization database:") + L" \n" + L"\"" + errorObjName_ + L"\""); + output = zen::readString<S>(stream_); //throw std::bad_alloc } + catch (std::exception&) { throwException(); } + + check(); + if (stream_.LastRead() != output.length() * sizeof(typename S::value_type)) //some additional check + throwException(); return output; } template <class T> inline -void CheckedWriter::writeNumberC(T number) const //checked write operation +void CheckedWriter::writePOD(T number) const //checked write operation { - writePOD<T>(stream_, number); + zen::writePOD<T>(stream_, number); check(); } template <class S> inline -void CheckedWriter::writeStringC(const S& str) const //checked write operation +void CheckedWriter::writeString(const S& str) const //checked write operation { - writeString(stream_, str); + zen::writeString(stream_, str); check(); if (stream_.LastWrite() != str.length() * sizeof(typename S::value_type)) //some additional check - throw FileError(_("Error writing to synchronization database:") + L" \n" + L"\"" + errorObjName_ + L"\""); + throwException(); } - - -inline -void CheckedWriter::check() const -{ - if (stream_.GetLastError() != wxSTREAM_NO_ERROR) - throw FileError(_("Error writing to synchronization database:") + L" \n" + L"\"" + errorObjName_ + L"\""); -} - } #endif //SERIALIZE_H_INCLUDED diff --git a/wx+/shell_execute.h b/wx+/shell_execute.h index 310fe88c..3468a1c8 100644 --- a/wx+/shell_execute.h +++ b/wx+/shell_execute.h @@ -51,9 +51,9 @@ void shellExecute(const wxString& command, ExecutionType type = EXEC_TYPE_ASYNC) if (!argv.empty()) { filename = argv[0]; - for (std::vector<std::wstring>::const_iterator i = argv.begin() + 1; i != argv.end(); ++i) - arguments += (i != argv.begin() ? L" " : L"") + - (i->empty() || std::find_if(i->begin(), i->end(), &cStringIsWhiteSpace<wchar_t>) != i->end() ? L"\"" + *i + L"\"" : *i); + for (auto iter = argv.begin() + 1; iter != argv.end(); ++iter) + arguments += (iter != argv.begin() ? L" " : L"") + + (iter->empty() || std::any_of(iter->begin(), iter->end(), &isWhiteSpace<wchar_t>) ? L"\"" + *iter + L"\"" : *iter); } SHELLEXECUTEINFO execInfo = {}; diff --git a/wx+/timespan.h b/wx+/timespan.h index 241a029e..58d5df4e 100644 --- a/wx+/timespan.h +++ b/wx+/timespan.h @@ -52,10 +52,10 @@ public: Layout(); //connect events - m_spinBtn ->Connect(wxEVT_SCROLL_LINEUP, wxEventHandler (TimeSpanCtrl::OnSpinUp), NULL, this); - m_spinBtn ->Connect(wxEVT_SCROLL_LINEDOWN, wxEventHandler (TimeSpanCtrl::OnSpinDown), NULL, this); - m_textCtrl->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler (TimeSpanCtrl::OnKeyPress), NULL, this); - m_textCtrl->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(TimeSpanCtrl::OnMouseAction), NULL, this); + m_spinBtn ->Connect(wxEVT_SCROLL_LINEUP, wxEventHandler (TimeSpanCtrl::OnSpinUp), nullptr, this); + m_spinBtn ->Connect(wxEVT_SCROLL_LINEDOWN, wxEventHandler (TimeSpanCtrl::OnSpinDown), nullptr, this); + m_textCtrl->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler (TimeSpanCtrl::OnKeyPress), nullptr, this); + m_textCtrl->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(TimeSpanCtrl::OnMouseAction), nullptr, this); setValue(0); } @@ -94,7 +94,7 @@ public: textVal.Trim(false); wxDateTime tmp(time_t(0)); - if (tmp.ParseFormat(textVal, FORMAT_TIMESPAN, wxDateTime(tmp)) == NULL) + if (tmp.ParseFormat(textVal, FORMAT_TIMESPAN, wxDateTime(tmp)) == nullptr) return 0; return (isNegative ? -1 : 1) * diff --git a/wx+/tooltip.cpp b/wx+/tooltip.cpp index 7b4c51e0..6d81cdae 100644 --- a/wx+/tooltip.cpp +++ b/wx+/tooltip.cpp @@ -48,7 +48,7 @@ public: }; -Tooltip::Tooltip() : tipWindow(new PopupFrameGenerated(NULL)) +Tooltip::Tooltip() : tipWindow(new PopupFrameGenerated(nullptr)) { #ifdef FFS_WIN //neither looks good nor works at all on Linux tipWindow->Disable(); //prevent window stealing focus! @@ -94,5 +94,12 @@ void Tooltip::show(const wxString& text, wxPoint mousePos, const wxBitmap* bmp) void Tooltip::hide() { +#ifdef FFS_LINUX + //on wxGTK the tip window occassionally goes blank and stays that way. This is somehow triggered by wxWindow::Hide() and doesn't seem to be a wxWidgets bug (=> GTK?) + //apply brute force: + tipWindow->Destroy(); + tipWindow = new PopupFrameGenerated(nullptr); +#endif + tipWindow->Hide(); } diff --git a/wx+/tooltip.h b/wx+/tooltip.h index 7babe3c3..195ceaf7 100644 --- a/wx+/tooltip.h +++ b/wx+/tooltip.h @@ -17,7 +17,7 @@ public: Tooltip(); ~Tooltip(); - void show(const wxString& text, wxPoint mousePos, const wxBitmap* bmp = NULL); //absolute screen coordinates + void show(const wxString& text, wxPoint mousePos, const wxBitmap* bmp = nullptr); //absolute screen coordinates void hide(); private: diff --git a/zen/FindFilePlus/find_file_plus.cpp b/zen/FindFilePlus/find_file_plus.cpp index 70076aa2..46eb956c 100644 --- a/zen/FindFilePlus/find_file_plus.cpp +++ b/zen/FindFilePlus/find_file_plus.cpp @@ -129,10 +129,10 @@ private: FileSearcher::FileSearcher(const wchar_t* dirname) : - hDir(NULL), + hDir(nullptr), nextEntryOffset(0) { - dirnameNt.Buffer = NULL; + dirnameNt.Buffer = nullptr; dirnameNt.Length = 0; dirnameNt.MaximumLength = 0; @@ -148,17 +148,17 @@ FileSearcher::FileSearcher(const wchar_t* dirname) : // RtlDosPathNameToRelativeNtPathName_U: used by Win7/Win8 available with OS version 5.2 (Windows Server 2003) and higher if (!rtlDosPathNameToNtPathName_U(dirname, //__in dosFileName, &dirnameNt, //__out ntFileName, - NULL, //__out_optFilePart, - NULL)) //__out_opt relativeName - empty if dosFileName is absolute + nullptr, //__out_optFilePart, + nullptr)) //__out_opt relativeName - empty if dosFileName is absolute throw NtFileError(STATUS_OBJECT_PATH_NOT_FOUND); //translates to ERROR_PATH_NOT_FOUND, same behavior like ::FindFirstFileEx() OBJECT_ATTRIBUTES objAttr = {}; - InitializeObjectAttributes(&objAttr, //[out] POBJECT_ATTRIBUTES initializedAttributes, - &dirnameNt, //[in] PUNICODE_STRING objectName, + InitializeObjectAttributes(&objAttr, //[out] POBJECT_ATTRIBUTES initializedAttributes, + &dirnameNt, //[in] PUNICODE_STRING objectName, OBJ_CASE_INSENSITIVE, //[in] ULONG attributes, - NULL, //[in] HANDLE rootDirectory, - NULL); //[in, optional] PSECURITY_DESCRIPTOR securityDescriptor + nullptr, //[in] HANDLE rootDirectory, + nullptr); //[in, optional] PSECURITY_DESCRIPTOR securityDescriptor { IO_STATUS_BLOCK status = {}; NTSTATUS rv = ntOpenFile(&hDir, //__out PHANDLE FileHandle, @@ -236,15 +236,15 @@ void FileSearcher::readDirImpl(FileInformation& output) //throw FileError /* corresponding first access in ::FindFirstFileW() NTSTATUS rv = ntQueryDirectoryFile(hDir, //__in HANDLE fileHandle, - NULL, //__in_opt HANDLE event, - NULL, //__in_opt PIO_APC_ROUTINE apcRoutine, - NULL, //__in_opt PVOID apcContext, + nullptr, //__in_opt HANDLE event, + nullptr, //__in_opt PIO_APC_ROUTINE apcRoutine, + nullptr, //__in_opt PVOID apcContext, &status, //__out PIO_STATUS_BLOCK ioStatusBlock, &buffer, //__out_bcount(Length) PVOID fileInformation, BUFFER_SIZE, //__in ULONG length, ::FindFirstFileW() on all XP/Win7/Win8 uses sizeof(FILE_BOTH_DIR_INFORMATION) + sizeof(TCHAR) * MAX_PATH == 0x268 FileIdBothDirectoryInformation, //__in FILE_INFORMATION_CLASS fileInformationClass - all XP/Win7/Win8 use "FileBothDirectoryInformation" true, //__in BOOLEAN returnSingleEntry, - NULL, //__in_opt PUNICODE_STRING mask, + nullptr, //__in_opt PUNICODE_STRING mask, false); //__in BOOLEAN restartScan */ @@ -253,15 +253,15 @@ void FileSearcher::readDirImpl(FileInformation& output) //throw FileError { IO_STATUS_BLOCK status = {}; NTSTATUS rv = ntQueryDirectoryFile(hDir, //__in HANDLE fileHandle, - NULL, //__in_opt HANDLE event, - NULL, //__in_opt PIO_APC_ROUTINE apcRoutine, - NULL, //__in_opt PVOID apcContext, + nullptr, //__in_opt HANDLE event, + nullptr, //__in_opt PIO_APC_ROUTINE apcRoutine, + nullptr, //__in_opt PVOID apcContext, &status, //__out PIO_STATUS_BLOCK ioStatusBlock, &buffer, //__out_bcount(Length) PVOID fileInformation, BUFFER_SIZE, //__in ULONG length, ::FindNextFileW() on all XP/Win7/Win8 uses sizeof(FILE_BOTH_DIR_INFORMATION) + sizeof(TCHAR) * 2000 == 0x1000 QueryPolicy::fileInformationClass, //__in FILE_INFORMATION_CLASS fileInformationClass - all XP/Win7/Win8 use "FileBothDirectoryInformation" false, //__in BOOLEAN returnSingleEntry, - NULL, //__in_opt PUNICODE_STRING mask, + nullptr, //__in_opt PUNICODE_STRING mask, false); //__in BOOLEAN restartScan if (!NT_SUCCESS(rv)) { diff --git a/zen/FindFilePlus/find_file_plus.h b/zen/FindFilePlus/find_file_plus.h index cf1174eb..7306c32e 100644 --- a/zen/FindFilePlus/find_file_plus.h +++ b/zen/FindFilePlus/find_file_plus.h @@ -44,7 +44,7 @@ class FileSearcher; typedef FileSearcher* FindHandle; DLL_FUNCTION_DECLARATION -FindHandle openDir(const wchar_t* dirname); //returns NULL on error, call ::GetLastError() +FindHandle openDir(const wchar_t* dirname); //returns nullptr on error, call ::GetLastError() //note: do NOT place an asterisk at end, e.g. C:\SomeDir\*, as one would do for ::FindFirstFile() DLL_FUNCTION_DECLARATION diff --git a/zen/basic_math.h b/zen/basic_math.h index e9ab1a2f..dbc2d922 100644 --- a/zen/basic_math.h +++ b/zen/basic_math.h @@ -12,6 +12,7 @@ #include <iterator> #include <limits> #include <functional> +#include <cassert> namespace numeric @@ -32,7 +33,7 @@ template <class T> const T& max(const T& a, const T& b, const T& c); template <class T> -void restrict(T& val, const T& minVal, const T& maxVal); //make sure minVal <= val && val <= maxVal +void confine(T& val, const T& minVal, const T& maxVal); //make sure minVal <= val && val <= maxVal template <class InputIterator> std::pair<InputIterator, InputIterator> minMaxElement(InputIterator first, InputIterator last); @@ -57,13 +58,12 @@ template <class RandomAccessIterator> double median(RandomAccessIterator first, RandomAccessIterator last); //note: invalidates input range! template <class InputIterator> -double stdDeviation(InputIterator first, InputIterator last, double* mean = NULL); //estimate standard deviation (and thereby arithmetic mean) +double stdDeviation(InputIterator first, InputIterator last, double* mean = nullptr); //estimate standard deviation (and thereby arithmetic mean) //median absolute deviation: "mad / 0.6745" is a robust measure for standard deviation of a normal distribution template <class RandomAccessIterator> double mad(RandomAccessIterator first, RandomAccessIterator last); //note: invalidates input range! - template <class InputIterator> double norm2(InputIterator first, InputIterator last); @@ -99,7 +99,10 @@ const double ln2 = 0.693147180559945309417; template <class T> inline T abs(T value) { - return value < 0 ? -1 * value : value; + if (value < 0) + return -value; // operator "?:" caveat: may be different type than "value" + else + return value; } template <class T> inline @@ -131,7 +134,7 @@ const T& max(const T& a, const T& b, const T& c) template <class T> inline -void restrict(T& val, const T& minVal, const T& maxVal) +void confine(T& val, const T& minVal, const T& maxVal) { assert(minVal <= maxVal); if (val < minVal) @@ -142,19 +145,36 @@ void restrict(T& val, const T& minVal, const T& maxVal) template <class InputIterator, class Compare> inline -std::pair<InputIterator, InputIterator> minMaxElement(InputIterator first, InputIterator last, Compare comp) +std::pair<InputIterator, InputIterator> minMaxElement(InputIterator first, InputIterator last, Compare compLess) { + //by factor 1.5 to 3 faster than boost::minmax_element (=two-step algorithm) for built-in types! + InputIterator lowest = first; InputIterator largest = first; if (first != last) - while (++first != last) + { + auto minVal = *lowest; //nice speedup on 64 bit! + auto maxVal = *largest; // + for (;;) { - if (comp(*largest, *first)) // or: if (comp(*largest,*lowest)) for the comp version + ++first; + if (first == last) + break; + const auto val = *first; + + if (compLess(maxVal, val)) + { largest = first; - else if (comp(*first, *lowest)) + maxVal = val; + } + else if (compLess(val, minVal)) + { lowest = first; + minVal = val; + } } + } return std::make_pair(lowest, largest); } @@ -207,10 +227,10 @@ template <class T> struct PowerImpl<10, T>; //not defined: invalidates power<N> for N >= 10 } -template <size_t N, class T> inline +template <size_t n, class T> inline T power(const T& value) { - return PowerImpl<N, T>::result(value); + return PowerImpl<n, T>::result(value); } @@ -231,8 +251,7 @@ double degToRad(double degree) template <class InputIterator> inline double arithmeticMean(InputIterator first, InputIterator last) { - //low level implementation to avoid random-access requirement on iterator - size_t n = 0; + size_t n = 0; //avoid random-access requirement for iterator! double sum_xi = 0; for (; first != last; ++first, ++n) @@ -280,10 +299,7 @@ double mad(RandomAccessIterator first, RandomAccessIterator last) //note: invali if (n % 2 != 0) return midVal; else //n is even and >= 2 in this context: return mean of two middle values - { - const double midVal2 = abs(*std::max_element(first, first + n / 2, lessMedAbs) - m); - return 0.5 * (midVal2 + midVal); - } + return 0.5 * (abs(*std::max_element(first, first + n / 2, lessMedAbs) - m) + midVal); } return 0; } diff --git a/zen/com_error.h b/zen/com_error.h index 7f967f7c..c67c4193 100644 --- a/zen/com_error.h +++ b/zen/com_error.h @@ -63,11 +63,11 @@ Equivalent to: std::wstring formatWin32Msg(DWORD dwMessageId) //return empty string on error { std::wstring output; - LPWSTR buffer = NULL; + LPWSTR buffer = nullptr; if (::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK | FORMAT_MESSAGE_IGNORE_INSERTS | //important: without this flag ::FormatMessage() will fail if message contains placeholders - FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, dwMessageId, 0, reinterpret_cast<LPWSTR>(&buffer), 0, NULL) != 0) + FORMAT_MESSAGE_ALLOCATE_BUFFER, nullptr, dwMessageId, 0, reinterpret_cast<LPWSTR>(&buffer), 0, nullptr) != 0) { if (buffer) //just to be sure { diff --git a/zen/com_ptr.h b/zen/com_ptr.h index b55d873e..98963cd1 100644 --- a/zen/com_ptr.h +++ b/zen/com_ptr.h @@ -20,7 +20,7 @@ Example: -------- ComPtr<IUPnPDeviceFinder> devFinder; if (FAILED(::CoCreateInstance(CLSID_UPnPDeviceFinder, - NULL, + nullptr, CLSCTX_ALL, IID_PPV_ARGS(devFinder.init())))) return -1; diff --git a/zen/com_util.h b/zen/com_util.h index 2845e352..fe02eadd 100644 --- a/zen/com_util.h +++ b/zen/com_util.h @@ -82,7 +82,7 @@ std::vector<ComPtr<T> > convertEnum(const ComPtr<U>& enumObj) if (enumUnknown) { ComPtr<IUnknown> itemTmp; - while (enumUnknown->Next(1, itemTmp.init(), NULL) == S_OK) //returns S_FALSE == 1 when finished! Don't use SUCCEEDED()!!! + while (enumUnknown->Next(1, itemTmp.init(), nullptr) == S_OK) //returns S_FALSE == 1 when finished! Don't use SUCCEEDED()!!! { ComPtr<T> itemNew = com_dynamic_cast<T>(itemTmp); if (itemNew) @@ -103,11 +103,11 @@ std::wstring getText(ComPtr<T> comObj, MemFun memFun) if (!comObj) return std::wstring(); - BSTR bstr = NULL; + BSTR bstr = nullptr; if (FAILED((comObj.get()->*memFun)(&bstr))) return std::wstring(); - if (bstr) //NULL means "no text" + if (bstr) //nullptr means "no text" { text = std::wstring(bstr, ::SysStringLen(bstr)); //correctly copy 0-characters ::SysFreeString(bstr); diff --git a/zen/debug_new.cpp b/zen/debug_new.cpp index 9992f0b3..6cc0e2da 100644 --- a/zen/debug_new.cpp +++ b/zen/debug_new.cpp @@ -15,14 +15,14 @@ namespace { LONG WINAPI writeDumpOnException(EXCEPTION_POINTERS* pExceptionInfo) { - HANDLE hFile = ::CreateFile(L"exception.dmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + HANDLE hFile = ::CreateFile(L"exception.dmp", GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); if (hFile != INVALID_HANDLE_VALUE) { MINIDUMP_EXCEPTION_INFORMATION exInfo = {}; exInfo.ThreadId = ::GetCurrentThreadId(); exInfo.ExceptionPointers = pExceptionInfo; - MINIDUMP_EXCEPTION_INFORMATION* exceptParam = pExceptionInfo ? &exInfo : NULL; + MINIDUMP_EXCEPTION_INFORMATION* exceptParam = pExceptionInfo ? &exInfo : nullptr; /*bool rv = */ ::MiniDumpWriteDump(::GetCurrentProcess(), //__in HANDLE hProcess, @@ -30,8 +30,8 @@ LONG WINAPI writeDumpOnException(EXCEPTION_POINTERS* pExceptionInfo) hFile, //__in HANDLE hFile, MiniDumpWithDataSegs, //__in MINIDUMP_TYPE DumpType, ->Standard: MiniDumpNormal, Medium: MiniDumpWithDataSegs, Full: MiniDumpWithFullMemory exceptParam, //__in PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, - NULL, //__in PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, - NULL); //__in PMINIDUMP_CALLBACK_INFORMATION CallbackParam + nullptr, //__in PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, + nullptr); //__in PMINIDUMP_CALLBACK_INFORMATION CallbackParam ::CloseHandle(hFile); } @@ -45,5 +45,5 @@ struct Dummy { Dummy() { ::SetUnhandledExceptionFilter(writeDumpOnException); }} void mem_check::writeMinidump() { - writeDumpOnException(NULL); + writeDumpOnException(nullptr); } diff --git a/zen/dir_watcher.cpp b/zen/dir_watcher.cpp index 6ab56100..ed07a1e4 100644 --- a/zen/dir_watcher.cpp +++ b/zen/dir_watcher.cpp @@ -28,15 +28,6 @@ using namespace zen; #ifdef FFS_WIN namespace { -inline -bool errorCodeForNotExisting(const DWORD lastError) -{ - return lastError == ERROR_PATH_NOT_FOUND || - lastError == ERROR_BAD_NETPATH || - lastError == ERROR_NETNAME_DELETED; -} - - class SharedData { public: @@ -152,13 +143,13 @@ public: hDir = ::CreateFile(applyLongPathPrefix(dirname.c_str()).c_str(), FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, + nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, - NULL); + nullptr); if (hDir == INVALID_HANDLE_VALUE) { - const std::wstring errorMsg = _("Could not initialize directory monitoring:") + L"\n\"" + dirname + L"\"" + L"\n\n" + zen::getLastErrorFormatted(); + const std::wstring errorMsg = _("Could not initialize directory monitoring:") + L"\n\"" + dirname + L"\"" L"\n\n" + zen::getLastErrorFormatted(); if (errorCodeForNotExisting(::GetLastError())) throw ErrorNotExisting(errorMsg); throw FileError(errorMsg); @@ -185,30 +176,30 @@ public: //actual work OVERLAPPED overlapped = {}; - overlapped.hEvent = ::CreateEvent(NULL, //__in_opt LPSECURITY_ATTRIBUTES lpEventAttributes, - true, //__in BOOL bManualReset, - false, //__in BOOL bInitialState, - NULL); //__in_opt LPCTSTR lpName - if (overlapped.hEvent == NULL) - return shared_->reportError(_("Error when monitoring directories.") + L" (CreateEvent)" + L"\n\n" + getLastErrorFormatted(), ::GetLastError()); - ZEN_ON_BLOCK_EXIT(::CloseHandle(overlapped.hEvent)); + overlapped.hEvent = ::CreateEvent(nullptr, //__in_opt LPSECURITY_ATTRIBUTES lpEventAttributes, + true, //__in BOOL bManualReset, + false, //__in BOOL bInitialState, + nullptr); //__in_opt LPCTSTR lpName + if (overlapped.hEvent == nullptr) + return shared_->reportError(_("Error when monitoring directories.") + L" (CreateEvent)" L"\n\n" + getLastErrorFormatted(), ::GetLastError()); + ZEN_ON_SCOPE_EXIT(::CloseHandle(overlapped.hEvent)); //asynchronous variant: runs on this thread's APC queue! - if (!::ReadDirectoryChangesW(hDir, // __in HANDLE hDirectory, - &buffer[0], // __out LPVOID lpBuffer, + if (!::ReadDirectoryChangesW(hDir, // __in HANDLE hDirectory, + &buffer[0], // __out LPVOID lpBuffer, static_cast<DWORD>(buffer.size()), // __in DWORD nBufferLength, - true, // __in BOOL bWatchSubtree, + true, // __in BOOL bWatchSubtree, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, // __in DWORD dwNotifyFilter, - NULL, // __out_opt LPDWORD lpBytesReturned, + nullptr, // __out_opt LPDWORD lpBytesReturned, &overlapped, // __inout_opt LPOVERLAPPED lpOverlapped, - NULL)) // __in_opt LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine - return shared_->reportError(_("Error when monitoring directories.") + L" (ReadDirectoryChangesW)" + L"\n\n" + getLastErrorFormatted(), ::GetLastError()); + nullptr)) // __in_opt LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine + return shared_->reportError(_("Error when monitoring directories.") + L" (ReadDirectoryChangesW)" L"\n\n" + getLastErrorFormatted(), ::GetLastError()); //async I/O is a resource that needs to be guarded since it will write to local variable "buffer"! - zen::ScopeGuard lockAio = zen::makeGuard([&]() + zen::ScopeGuard guardAio = zen::makeGuard([&] { //http://msdn.microsoft.com/en-us/library/aa363789(v=vs.85).aspx if (::CancelIo(hDir) == TRUE) //cancel all async I/O related to this handle and thread @@ -218,16 +209,15 @@ public: } }); - DWORD bytesWritten = 0; - //wait for results + DWORD bytesWritten = 0; while (!::GetOverlappedResult(hDir, //__in HANDLE hFile, &overlapped, //__in LPOVERLAPPED lpOverlapped, &bytesWritten, //__out LPDWORD lpNumberOfBytesTransferred, false)) //__in BOOL bWait { if (::GetLastError() != ERROR_IO_INCOMPLETE) - return shared_->reportError(_("Error when monitoring directories.") + L" (GetOverlappedResult)" + L"\n\n" + getLastErrorFormatted(), ::GetLastError()); + return shared_->reportError(_("Error when monitoring directories.") + L" (GetOverlappedResult)" L"\n\n" + getLastErrorFormatted(), ::GetLastError()); //execute asynchronous procedure calls (APC) queued on this thread ::SleepEx(50, // __in DWORD dwMilliseconds, @@ -235,7 +225,7 @@ public: boost::this_thread::interruption_point(); } - lockAio.dismiss(); + guardAio.dismiss(); shared_->addChanges(&buffer[0], bytesWritten, dirname); //throw () } @@ -370,8 +360,8 @@ public: DirsOnlyTraverser(std::vector<Zstring>& dirs, const std::shared_ptr<TraverseCallback>& otherMe) : otherMe_(otherMe), dirs_(dirs) {} - virtual void onFile (const Zchar* shortName, const Zstring& fullName, const FileInfo& details) {} - virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) {} + virtual void onFile (const Zchar* shortName, const Zstring& fullName, const FileInfo& details) {} + virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) {} virtual std::shared_ptr<TraverseCallback> onDir(const Zchar* shortName, const Zstring& fullName) { dirs_.push_back(fullName); @@ -21,7 +21,7 @@ Manage DLL function and library ownership Usage: typedef BOOL (WINAPI* IsWow64ProcessFun)(HANDLE hProcess, PBOOL Wow64Process); - const zen::DllFun<IsWow64ProcessFun> isWow64Process(L"kernel32.dll", "IsWow64Process"); + const zen::SysDllFun<IsWow64ProcessFun> isWow64Process(L"kernel32.dll", "IsWow64Process"); if (isWow64Process) ... use function ptr ... */ @@ -29,11 +29,11 @@ template <class Func> class DllFun { public: - DllFun() : fun(NULL) {} + DllFun() : fun(nullptr) {} DllFun(const wchar_t* libraryName, const char* functionName) : hLibRef(new HMODULE(::LoadLibrary(libraryName)), deleter), - fun(*hLibRef ? reinterpret_cast<Func>(::GetProcAddress(*hLibRef, functionName)) : NULL) {} + fun(*hLibRef ? reinterpret_cast<Func>(::GetProcAddress(*hLibRef, functionName)) : nullptr) {} operator Func() const { return fun; } @@ -50,10 +50,13 @@ template <class Func> class SysDllFun { public: - SysDllFun() : fun(NULL) {} + SysDllFun() : fun(nullptr) {} - SysDllFun(const wchar_t* systemLibrary, const char* functionName) : - fun(reinterpret_cast<Func>(::GetProcAddress(::GetModuleHandle(systemLibrary), functionName))) {} + SysDllFun(const wchar_t* systemLibrary, const char* functionName) + { + HMODULE mod = ::GetModuleHandle(systemLibrary); + fun = mod ? reinterpret_cast<Func>(::GetProcAddress(mod, functionName)) : nullptr; + } operator Func() const { return fun; } @@ -88,32 +91,24 @@ std::string getResourceStream(const std::wstring& libraryName, size_t resourceId -//---------------Inline Implementation--------------------------------------------------- +//--------------- implementation--------------------------------------------------- inline std::string getResourceStream(const wchar_t* libraryName, size_t resourceId) { - std::string output; - HMODULE module = ::LoadLibrary(libraryName); - if (module) + if (HMODULE module = ::LoadLibrary(libraryName)) { - ZEN_ON_BLOCK_EXIT(::FreeLibrary(module)); + ZEN_ON_SCOPE_EXIT(::FreeLibrary(module)); - const HRSRC res = ::FindResource(module, MAKEINTRESOURCE(resourceId), RT_RCDATA); - if (res != NULL) + if (HRSRC res = ::FindResource(module, MAKEINTRESOURCE(resourceId), RT_RCDATA)) { - const HGLOBAL resHandle = ::LoadResource(module, res); - if (resHandle != NULL) + if (HGLOBAL resHandle = ::LoadResource(module, res)) { - const char* stream = static_cast<const char*>(::LockResource(resHandle)); - if (stream) - { - const DWORD streamSize = ::SizeofResource(module, res); - output.assign(stream, streamSize); - } + if (const char* stream = static_cast<const char*>(::LockResource(resHandle))) + return std::string(stream, static_cast<size_t>(::SizeofResource(module, res))); //size is 0 on error } } } - return output; + return std::string(); } } diff --git a/zen/dst_hack.cpp b/zen/dst_hack.cpp index 9fe3a550..3ecfd8e9 100644 --- a/zen/dst_hack.cpp +++ b/zen/dst_hack.cpp @@ -17,9 +17,9 @@ namespace Zstring getVolumeName(const Zstring& filename) { //this call is expensive: ~1.5 ms! - // if (!::GetVolumePathName(applyLongPathPrefix(filename).c_str(), //__in LPCTSTR lpszFileName, - // fsName, //__out LPTSTR lpszVolumePathName, - // BUFFER_SIZE)) //__in DWORD cchBufferLength + // if (!::GetVolumePathName(filename.c_str(), //__in LPCTSTR lpszFileName, + // fsName, //__out LPTSTR lpszVolumePathName, + // BUFFER_SIZE)) //__in DWORD cchBufferLength // ... // Zstring volumePath = fsName; // if (!volumePath.EndsWith(FILE_NAME_SEPARATOR)) //a trailing backslash is required @@ -65,11 +65,11 @@ bool dst::isFatDrive(const Zstring& fileName) //throw() //suprisingly fast: ca. 0.03 ms per call! if (!::GetVolumeInformation(volumePath.c_str(), //__in_opt LPCTSTR lpRootPathName, - NULL, //__out LPTSTR lpVolumeNameBuffer, + nullptr, //__out LPTSTR lpVolumeNameBuffer, 0, //__in DWORD nVolumeNameSize, - NULL, //__out_opt LPDWORD lpVolumeSerialNumber, - NULL, //__out_opt LPDWORD lpMaximumComponentLength, - NULL, //__out_opt LPDWORD lpFileSystemFlags, + nullptr, //__out_opt LPDWORD lpVolumeSerialNumber, + nullptr, //__out_opt LPDWORD lpMaximumComponentLength, + nullptr, //__out_opt LPDWORD lpFileSystemFlags, fsName, //__out LPTSTR lpFileSystemNameBuffer, BUFFER_SIZE)) //__in DWORD nFileSystemNameSize { @@ -105,11 +105,11 @@ bool dst::isFatDrive(HANDLE hFile) //throw() wchar_t fsName[BUFFER_SIZE]; if (!getVolumeInformationByHandle(hFile, //__in HANDLE hFile, - NULL, //__out LPTSTR lpVolumeNameBuffer, + nullptr, //__out LPTSTR lpVolumeNameBuffer, 0, //__in DWORD nVolumeNameSize, - NULL, //__out_opt LPDWORD lpVolumeSerialNumber, - NULL, //__out_opt LPDWORD lpMaximumComponentLength, - NULL, //__out_opt LPDWORD lpFileSystemFlags, + nullptr, //__out_opt LPDWORD lpVolumeSerialNumber, + nullptr, //__out_opt LPDWORD lpMaximumComponentLength, + nullptr, //__out_opt LPDWORD lpFileSystemFlags, fsName, //__out LPTSTR lpFileSystemNameBuffer, BUFFER_SIZE)) //__in DWORD nFileSystemNameSize { @@ -158,6 +158,7 @@ Int64 toInt64(const FILETIME& fileTime) } +inline FILETIME utcToLocal(const FILETIME& utcTime) //throw (std::runtime_error) { //treat binary local time representation (which is invariant under DST time zone shift) as logical UTC: @@ -167,14 +168,15 @@ FILETIME utcToLocal(const FILETIME& utcTime) //throw (std::runtime_error) &localTime)) //__out LPFILETIME lpLocalFileTime { const std::wstring errorMessage = _("Conversion error:") + L" FILETIME -> local FILETIME: " + L"(" + - L"High: " + toString<std::wstring>(utcTime.dwHighDateTime) + L" " + - L"Low: " + toString<std::wstring>(utcTime.dwLowDateTime) + L") " + L"\n\n" + getLastErrorFormatted(); + L"High: " + numberTo<std::wstring>(utcTime.dwHighDateTime) + L" " + + L"Low: " + numberTo<std::wstring>(utcTime.dwLowDateTime) + L") " + L"\n\n" + getLastErrorFormatted(); throw std::runtime_error(wideToUtf8<std::string>(errorMessage)); } return localTime; } +inline FILETIME localToUtc(const FILETIME& localTime) //throw (std::runtime_error) { //treat binary local time representation (which is invariant under DST time zone shift) as logical UTC: @@ -184,8 +186,8 @@ FILETIME localToUtc(const FILETIME& localTime) //throw (std::runtime_error) &utcTime)) //__out LPFILETIME lpFileTime { const std::wstring errorMessage = _("Conversion error:") + L" local FILETIME -> FILETIME: " + L"(" + - L"High: " + toString<std::wstring>(localTime.dwHighDateTime) + L" " + - L"Low: " + toString<std::wstring>(localTime.dwLowDateTime) + L") " + L"\n\n" + getLastErrorFormatted(); + L"High: " + numberTo<std::wstring>(localTime.dwHighDateTime) + L" " + + L"Low: " + numberTo<std::wstring>(localTime.dwLowDateTime) + L") " + L"\n\n" + getLastErrorFormatted(); throw std::runtime_error(wideToUtf8<std::string>(errorMessage)); } return utcTime; @@ -214,7 +216,7 @@ const size_t UTC_LOCAL_OFFSET_BITS = 7; const size_t WRITE_TIME_HASH_BITS = CREATE_TIME_INFO_BITS - INDICATOR_EXISTING_BITS - UTC_LOCAL_OFFSET_BITS; -template <size_t precision> +template <size_t precision> inline FILETIME encodeRawInformation(UInt64 rawInfo) { rawInfo *= precision; @@ -225,7 +227,7 @@ FILETIME encodeRawInformation(UInt64 rawInfo) } -template <size_t precision> +template <size_t precision> inline UInt64 extractRawInformation(const FILETIME& createTime) { assert(toUInt64(FAT_MIN_TIME) <= toUInt64(createTime)); @@ -243,6 +245,7 @@ UInt64 extractRawInformation(const FILETIME& createTime) //convert write time to it's minimal representation (no restriction to FAT range "1980 - 2107") +inline UInt64 extractRawWriteTime(const FILETIME& writeTime) { UInt64 rawInfo = toUInt64(writeTime); @@ -253,6 +256,7 @@ UInt64 extractRawWriteTime(const FILETIME& writeTime) //files with different resolution than 2 seconds are rounded up when written to FAT +inline FILETIME roundToFatWriteTime(const FILETIME& writeTime) { UInt64 rawData = toUInt64(writeTime); @@ -284,7 +288,7 @@ std::bitset<UTC_LOCAL_OFFSET_BITS> getUtcLocalShift() timeShiftSec % (60 * 15) != 0) //all known time shift have at least 15 minute granularity! { const std::wstring errorMessage = _("Conversion error:") + L" Unexpected UTC <-> local time shift: " + - L"(" + toString<std::wstring>(timeShiftSec) + L") " + L"\n\n" + getLastErrorFormatted(); + L"(" + numberTo<std::wstring>(timeShiftSec) + L") " + L"\n\n" + getLastErrorFormatted(); throw std::runtime_error(wideToUtf8<std::string>(errorMessage)); } diff --git a/zen/error_log.h b/zen/error_log.h new file mode 100644 index 00000000..f3f67233 --- /dev/null +++ b/zen/error_log.h @@ -0,0 +1,133 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) ZenJu (zhnmju123 AT gmx DOT de) - All Rights Reserved * +// ************************************************************************** + +#ifndef ERRORLOGGING_H_INCLUDED +#define ERRORLOGGING_H_INCLUDED + +#include <algorithm> +#include <vector> +#include <string> +#include <zen/time.h> +#include <zen/i18n.h> + +namespace zen +{ +enum MessageType +{ + TYPE_INFO = 1, + TYPE_WARNING = 2, + TYPE_ERROR = 4, + TYPE_FATAL_ERROR = 8, +}; + +struct LogEntry +{ + time_t time; + MessageType type; + std::wstring message; +}; + +std::wstring formatMessage(const LogEntry& msg); + + +class ErrorLog +{ +public: + void logMsg(const std::wstring& message, MessageType type); + + int getItemCount(int typeFilter = TYPE_INFO | TYPE_WARNING | TYPE_ERROR | TYPE_FATAL_ERROR) const; + + const std::vector<LogEntry>& getEntries() const { return logEntries; } + +private: + std::vector<LogEntry> logEntries; //list of non-resolved errors and warnings +}; + + + + + + + + + + + + + + + + + + + +//######################## implementation ########################## + +inline +void ErrorLog::logMsg(const std::wstring& message, zen::MessageType type) +{ + const LogEntry newEntry = { std::time(nullptr), type, message }; + logEntries.push_back(newEntry); +} + + +inline +int ErrorLog::getItemCount(int typeFilter) const +{ + return static_cast<int>(std::count_if(logEntries.begin(), logEntries.end(), [&](const LogEntry& e) { return e.type & typeFilter; })); +} + + +namespace +{ +std::wstring formatMessageImpl(const LogEntry& entry) //internal linkage +{ + auto getTypeName = [&]() -> std::wstring + { + switch (entry.type) + { + case TYPE_INFO: + return _("Info"); + case TYPE_WARNING: + return _("Warning"); + case TYPE_ERROR: + return _("Error"); + case TYPE_FATAL_ERROR: + return _("Fatal Error"); + } + return std::wstring(); + }; + + std::wstring formattedText = L"[" + formatTime<std::wstring>(FORMAT_TIME, localTime(entry.time)) + L"] " + getTypeName() + L": "; + const size_t prefixLen = formattedText.size(); + + for (auto iter = entry.message.begin(); iter != entry.message.end(); ) + if (*iter == L'\n') + { + formattedText += L'\n'; + + std::wstring blanks; + blanks.resize(prefixLen, L' '); + formattedText += blanks; + + do //skip duplicate newlines + { + ++iter; + } + while (iter != entry.message.end() && *iter == L'\n'); + } + else + formattedText += *iter++; + + return formattedText; +} +} + +inline std::wstring formatMessage(const LogEntry& entry) { return formatMessageImpl(entry); } + +} + +#endif // ERRORLOGGING_H_INCLUDED diff --git a/zen/file_handling.cpp b/zen/file_handling.cpp index dd5276a4..a81b3a80 100644 --- a/zen/file_handling.cpp +++ b/zen/file_handling.cpp @@ -31,7 +31,6 @@ #include <sys/stat.h> #include <time.h> #include <utime.h> -#include <cerrno> #include <sys/time.h> #ifdef HAVE_SELINUX @@ -89,7 +88,8 @@ bool zen::symlinkExists(const Zstring& objname) bool zen::somethingExists(const Zstring& objname) //throw() check whether any object with this name exists { #ifdef FFS_WIN - return ::GetFileAttributes(applyLongPathPrefix(objname).c_str()) != INVALID_FILE_ATTRIBUTES; + const DWORD rv = ::GetFileAttributes(applyLongPathPrefix(objname).c_str()); + return rv != INVALID_FILE_ATTRIBUTES || ::GetLastError() == ERROR_SHARING_VIOLATION; //"C:\pagefile.sys" #elif defined FFS_LINUX struct stat fileInfo = {}; @@ -142,10 +142,10 @@ void getFileAttrib(const Zstring& filename, FileAttrib& attr, ProcSymlink procSl 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, - NULL); + nullptr); if (hFile == INVALID_HANDLE_VALUE) throw FileError(_("Error reading file attributes:") + L"\n\"" + filename + L"\"" + L"\n\n" + getLastErrorFormatted()); - ZEN_ON_BLOCK_EXIT(::CloseHandle(hFile)); + ZEN_ON_SCOPE_EXIT(::CloseHandle(hFile)); BY_HANDLE_FILE_INFORMATION fileInfoHnd = {}; if (!::GetFileInformationByHandle(hFile, &fileInfoHnd)) @@ -211,12 +211,12 @@ DWORD retrieveVolumeSerial(const Zstring& pathName) //return 0 on error! DWORD volumeSerial = 0; if (!::GetVolumeInformation(volumePath.c_str(), //__in_opt LPCTSTR lpRootPathName, - NULL, //__out LPTSTR lpVolumeNameBuffer, + nullptr, //__out LPTSTR lpVolumeNameBuffer, 0, //__in DWORD nVolumeNameSize, &volumeSerial, //__out_opt LPDWORD lpVolumeSerialNumber, - NULL, //__out_opt LPDWORD lpMaximumComponentLength, - NULL, //__out_opt LPDWORD lpFileSystemFlags, - NULL, //__out LPTSTR lpFileSystemNameBuffer, + nullptr, //__out_opt LPDWORD lpMaximumComponentLength, + nullptr, //__out_opt LPDWORD lpFileSystemFlags, + nullptr, //__out LPTSTR lpFileSystemNameBuffer, 0)) //__in DWORD nFileSystemNameSize return 0; @@ -260,34 +260,27 @@ zen::ResponseSame zen::onSameVolume(const Zstring& folderLeft, const Zstring& fo bool zen::removeFile(const Zstring& filename) //throw FileError; { #ifdef FFS_WIN - //remove file, support for \\?\-prefix - const Zstring filenameFmt = applyLongPathPrefix(filename); + const Zstring& filenameFmt = applyLongPathPrefix(filename); if (!::DeleteFile(filenameFmt.c_str())) #elif defined FFS_LINUX if (::unlink(filename.c_str()) != 0) #endif { + ErrorCode lastError = getLastError(); + if (errorCodeForNotExisting(lastError)) //no error situation if file is not existing! manual deletion relies on it! + return false; #ifdef FFS_WIN - //perf: apply ONLY when necessary! - if (::GetLastError() == ERROR_ACCESS_DENIED) //function fails if file is read-only + else if (lastError == ERROR_ACCESS_DENIED) //function fails if file is read-only { - //(try to) normalize file attributes - ::SetFileAttributes(filenameFmt.c_str(), FILE_ATTRIBUTE_NORMAL); + ::SetFileAttributes(filenameFmt.c_str(), FILE_ATTRIBUTE_NORMAL); //(try to) normalize file attributes - //now try again... - if (::DeleteFile(filenameFmt.c_str())) + if (::DeleteFile(filenameFmt.c_str())) //now try again... return true; + lastError = ::GetLastError(); } - //eval error code before next call - DWORD lastError = ::GetLastError(); -#elif defined FFS_LINUX - int lastError = errno; #endif - - //no error situation if file is not existing! manual deletion relies on it! - //perf: check is placed in error handling block - //warning: this call changes error code!! - if (!somethingExists(filename)) + //after "lastError" evaluation it *may* be redundant to check existence again, but better be safe than sorry: + if (!somethingExists(filename)) //warning: changes global error code!! return false; //neither file nor any other object (e.g. broken symlink) with that name existing throw FileError(_("Error deleting file:") + L"\n\"" + filename + L"\"" + L"\n\n" + getLastErrorFormatted(lastError)); @@ -383,7 +376,7 @@ Zstring getFilenameFmt(const Zstring& filename, Function fun) //throw(); returns { const Zstring filenameFmt = applyLongPathPrefix(filename); - const DWORD bufferSize = fun(filenameFmt.c_str(), NULL, 0); + const DWORD bufferSize = fun(filenameFmt.c_str(), nullptr, 0); if (bufferSize == 0) return Zstring(); @@ -407,11 +400,12 @@ Zstring findUnused8Dot3Name(const Zstring& filename) //find a unique 8.3 short n Zstring extension = afterLast(afterLast(filename, FILE_NAME_SEPARATOR), Zchar('.')); //extension needn't contain reasonable data if (extension.empty()) extension = Zstr("FFS"); - truncate(extension, 3); + else if (extension.length() > 3) + extension.resize(3); for (int index = 0; index < 100000000; ++index) //filename must be representable by <= 8 characters { - const Zstring output = pathPrefix + toString<Zstring>(index) + Zchar('.') + extension; + const Zstring output = pathPrefix + numberTo<Zstring>(index) + Zchar('.') + extension; if (!somethingExists(output)) //ensure uniqueness return output; } @@ -559,7 +553,7 @@ void zen::moveFile(const Zstring& sourceFile, const Zstring& targetFile, bool ig copySymlink(sourceFile, targetFile, false); //throw FileError; don't copy filesystem permissions else { - std::unique_ptr<CopyCallbackImpl> copyCallback(callback != NULL ? new CopyCallbackImpl(sourceFile, targetFile, *callback) : NULL); + std::unique_ptr<CopyCallbackImpl> copyCallback(callback ? new CopyCallbackImpl(sourceFile, targetFile, *callback) : nullptr); copyFile(sourceFile, targetFile, false, true, copyCallback.get()); //throw FileError; } @@ -687,7 +681,7 @@ void moveDirectoryImpl(const Zstring& sourceDir, const Zstring& targetDir, bool } //delete source - std::unique_ptr<RemoveCallbackImpl> removeCallback(callback != NULL ? new RemoveCallbackImpl(*callback) : NULL); + std::unique_ptr<RemoveCallbackImpl> removeCallback(callback ? new RemoveCallbackImpl(*callback) : nullptr); removeDirectory(sourceDir, removeCallback.get()); //throw FileError; if (callback) callback->objectProcessed(); @@ -779,32 +773,32 @@ void zen::removeDirectory(const Zstring& directory, CallbackRemoveDir* callback) std::vector<Zstring> fileList; std::vector<Zstring> dirList; + { + //get all files and directories from current directory (WITHOUT subdirectories!) + FilesDirsOnlyTraverser traverser(fileList, dirList); + traverseFolder(directory, false, traverser); //don't follow symlinks + } - //get all files and directories from current directory (WITHOUT subdirectories!) - FilesDirsOnlyTraverser traverser(fileList, dirList); - traverseFolder(directory, false, traverser); //don't follow symlinks + //delete directories recursively + for (auto iter = dirList.begin(); iter != dirList.end(); ++iter) + removeDirectory(*iter, callback); //call recursively to correctly handle symbolic links //delete files - for (std::vector<Zstring>::const_iterator i = fileList.begin(); i != fileList.end(); ++i) + for (auto iter = fileList.begin(); iter != fileList.end(); ++iter) { - const bool workDone = removeFile(*i); + const bool workDone = removeFile(*iter); if (callback && workDone) - callback->notifyFileDeletion(*i); //call once per file + callback->notifyFileDeletion(*iter); //call once per file } - //delete directories recursively - for (std::vector<Zstring>::const_iterator i = dirList.begin(); i != dirList.end(); ++i) - removeDirectory(*i, callback); //call recursively to correctly handle symbolic links - //parent directory is deleted last #ifdef FFS_WIN - if (!::RemoveDirectory(directoryFmt.c_str())) //remove directory, support for \\?\-prefix + if (!::RemoveDirectory(directoryFmt.c_str())) #else if (::rmdir(directory.c_str()) != 0) #endif - { throw FileError(_("Error deleting directory:") + L"\n\"" + directory + L"\"" + L"\n\n" + getLastErrorFormatted()); - } + if (callback) callback->notifyDirDeletion(directory); //and once per folder } @@ -848,7 +842,7 @@ void zen::setFileTime(const Zstring& filename, const Int64& modificationTime, Pr OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | //needed to open a directory (procSl == SYMLINK_DIRECT ? FILE_FLAG_OPEN_REPARSE_POINT : 0), //process symlinks - NULL); + nullptr); }); if (targetHandle.get() == INVALID_HANDLE_VALUE) @@ -865,8 +859,8 @@ void zen::setFileTime(const Zstring& filename, const Int64& modificationTime, Pr auto isNullTime = [](const FILETIME & ft) { return ft.dwLowDateTime == 0 && ft.dwHighDateTime == 0; }; if (!::SetFileTime(targetHandle.get(), - isNullTime(creationTime) ? NULL : &creationTime, - NULL, + isNullTime(creationTime) ? nullptr : &creationTime, + nullptr, &lastWriteTime)) throw FileError(_("Error changing modification time:") + L"\n\"" + filename + L"\"" + L"\n\n" + getLastErrorFormatted()); @@ -887,7 +881,7 @@ void zen::setFileTime(const Zstring& filename, const Int64& modificationTime, Pr if (procSl == SYMLINK_FOLLOW) { struct utimbuf newTimes = {}; - newTimes.actime = ::time(NULL); + newTimes.actime = ::time(nullptr); newTimes.modtime = to<time_t>(modificationTime); // set new "last write time" @@ -897,7 +891,7 @@ void zen::setFileTime(const Zstring& filename, const Int64& modificationTime, Pr else { struct timeval newTimes[2] = {}; - newTimes[0].tv_sec = ::time(NULL); /* seconds */ + newTimes[0].tv_sec = ::time(nullptr); /* seconds */ newTimes[0].tv_usec = 0; /* microseconds */ newTimes[1].tv_sec = to<time_t>(modificationTime); @@ -913,43 +907,65 @@ void zen::setFileTime(const Zstring& filename, const Int64& modificationTime, Pr bool zen::supportsPermissions(const Zstring& dirname) //throw FileError { #ifdef FFS_WIN - const HANDLE hDir = ::CreateFile(zen::applyLongPathPrefix(dirname).c_str(), - 0, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, // | FILE_FLAG_OPEN_REPARSE_POINT -> follow symlinks - NULL); - if (hDir == INVALID_HANDLE_VALUE) + std::vector<wchar_t> buffer(MAX_PATH + 1); + if (!::GetVolumePathName(dirname.c_str(), //__in LPCTSTR lpszFileName, + &buffer[0], //__out LPTSTR lpszVolumePathName, + static_cast<DWORD>(buffer.size()))) //__in DWORD cchBufferLength throw FileError(_("Error reading file attributes:") + L"\n\"" + dirname + L"\"" + L"\n\n" + getLastErrorFormatted()); - ZEN_ON_BLOCK_EXIT(::CloseHandle(hDir)); - - //dynamically load windows API function (existing since Windows XP) - typedef BOOL (WINAPI* GetVolumeInformationByHandleWFun)(HANDLE hFile, - LPWSTR lpVolumeNameBuffer, - DWORD nVolumeNameSize, - LPDWORD lpVolumeSerialNumber, - LPDWORD lpMaximumComponentLength, - LPDWORD lpFileSystemFlags, - LPWSTR lpFileSystemNameBuffer, - DWORD nFileSystemNameSize); - - const SysDllFun<GetVolumeInformationByHandleWFun> getVolumeInformationByHandleW(L"kernel32.dll", "GetVolumeInformationByHandleW"); - if (!getVolumeInformationByHandleW) - throw FileError(_("Error loading library function:") + L"\n\"" + L"GetVolumeInformationByHandleW" + L"\""); - - DWORD fileSystemFlags = 0; - if (!getVolumeInformationByHandleW(hDir, //__in HANDLE hFile, - NULL, //__out_opt LPTSTR lpVolumeNameBuffer, - 0, //__in DWORD nVolumeNameSize, - NULL, //__out_opt LPDWORD lpVolumeSerialNumber, - NULL, //__out_opt LPDWORD lpMaximumComponentLength, - &fileSystemFlags, //__out_opt LPDWORD lpFileSystemFlags, - NULL, //__out LPTSTR lpFileSystemNameBuffer, - 0)) //__in DWORD nFileSystemNameSize + + DWORD fsFlags = 0; + if (!::GetVolumeInformation(&buffer[0], //__in_opt LPCTSTR lpRootPathName, + nullptr, //__out LPTSTR lpVolumeNameBuffer, + 0, //__in DWORD nVolumeNameSize, + nullptr, //__out_opt LPDWORD lpVolumeSerialNumber, + nullptr, //__out_opt LPDWORD lpMaximumComponentLength, + &fsFlags, //__out_opt LPDWORD lpFileSystemFlags, + nullptr, //__out LPTSTR lpFileSystemNameBuffer, + 0)) //__in DWORD nFileSystemNameSize throw FileError(_("Error reading file attributes:") + L"\n\"" + dirname + L"\"" + L"\n\n" + getLastErrorFormatted()); - return (fileSystemFlags & FILE_PERSISTENT_ACLS) != 0; + return (fsFlags & FILE_PERSISTENT_ACLS) != 0; + + + // -> the following approach is *only* working since Windows Vista: + // const HANDLE hDir = ::CreateFile(zen::applyLongPathPrefix(dirname).c_str(), + // 0, + // FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + // nullptr, + // OPEN_EXISTING, + // FILE_FLAG_BACKUP_SEMANTICS, // | FILE_FLAG_OPEN_REPARSE_POINT -> follow symlinks + // nullptr); + // if (hDir == INVALID_HANDLE_VALUE) + // throw FileError(_("Error reading file attributes:") + L"\n\"" + dirname + L"\"" + L"\n\n" + getLastErrorFormatted()); + // ZEN_ON_SCOPE_EXIT(::CloseHandle(hDir)); + // + // //dynamically load windows API function (existing since Windows XP) + // typedef BOOL (WINAPI* GetVolumeInformationByHandleWFun)(HANDLE hFile, + // LPWSTR lpVolumeNameBuffer, + // DWORD nVolumeNameSize, + // LPDWORD lpVolumeSerialNumber, + // LPDWORD lpMaximumComponentLength, + // LPDWORD lpFileSystemFlags, + // LPWSTR lpFileSystemNameBuffer, + // DWORD nFileSystemNameSize); + // + // const SysDllFun<GetVolumeInformationByHandleWFun> getVolumeInformationByHandleW(L"kernel32.dll", "GetVolumeInformationByHandleW"); //available since Windows Vista + // if (!getVolumeInformationByHandleW) + // return true; //Windows XP, 2000 -> do not show this error message + // //throw FileError(rror loading library function+ L"\n\"" + L"GetVolumeInformationByHandleW" + L"\""); + // + // DWORD fileSystemFlags = 0; + // if (!getVolumeInformationByHandleW(hDir, //__in HANDLE hFile, + // nullptr, //__out_opt LPTSTR lpVolumeNameBuffer, + // 0, //__in DWORD nVolumeNameSize, + // nullptr, //__out_opt LPDWORD lpVolumeSerialNumber, + // nullptr, //__out_opt LPDWORD lpMaximumComponentLength, + // &fileSystemFlags, //__out_opt LPDWORD lpFileSystemFlags, + // nullptr, //__out LPTSTR lpFileSystemNameBuffer, + // 0)) //__in DWORD nFileSystemNameSize + // throw FileError(_("Error reading file attributes:") + L"\n\"" + dirname + L"\"" + L"\n\n" + getLastErrorFormatted()); + // + // return (fileSystemFlags & FILE_PERSISTENT_ACLS) != 0; #elif defined FFS_LINUX return true; @@ -969,10 +985,10 @@ Zstring getSymlinkTargetPath(const Zstring& symlink) //throw FileError 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, //needed to open a directory - NULL); + nullptr); if (hDir == INVALID_HANDLE_VALUE) throw FileError(_("Error resolving symbolic link:") + L"\n\"" + symlink + L"\"" + L"\n\n" + getLastErrorFormatted()); - ZEN_ON_BLOCK_EXIT(::CloseHandle(hDir)); + ZEN_ON_SCOPE_EXIT(::CloseHandle(hDir)); //dynamically load windows API function typedef DWORD (WINAPI* GetFinalPathNameByHandleWFunc)(HANDLE hFile, @@ -1006,7 +1022,7 @@ Zstring getSymlinkTargetPath(const Zstring& symlink) //throw FileError //copy SELinux security context void copySecurityContext(const Zstring& source, const Zstring& target, ProcSymlink procSl) //throw FileError { - security_context_t contextSource = NULL; + security_context_t contextSource = nullptr; const int rv = procSl == SYMLINK_FOLLOW ? ::getfilecon(source.c_str(), &contextSource) : ::lgetfilecon(source.c_str(), &contextSource); @@ -1018,10 +1034,10 @@ void copySecurityContext(const Zstring& source, const Zstring& target, ProcSymli throw FileError(_("Error reading security context:") + L"\n\"" + source + L"\"" + L"\n\n" + getLastErrorFormatted()); } - ZEN_ON_BLOCK_EXIT(::freecon(contextSource)); + ZEN_ON_SCOPE_EXIT(::freecon(contextSource)); { - security_context_t contextTarget = NULL; + security_context_t contextTarget = nullptr; const int rv2 = procSl == SYMLINK_FOLLOW ? ::getfilecon(target.c_str(), &contextTarget) : ::lgetfilecon(target.c_str(), &contextTarget); @@ -1033,7 +1049,7 @@ void copySecurityContext(const Zstring& source, const Zstring& target, ProcSymli } else { - ZEN_ON_BLOCK_EXIT(::freecon(contextTarget)); + ZEN_ON_SCOPE_EXIT(::freecon(contextTarget)); if (::strcmp(contextSource, contextTarget) == 0) //nothing to do return; @@ -1121,11 +1137,11 @@ void copyObjectPermissions(const Zstring& source, const Zstring& target, ProcSym throw FileError(_("Error copying file permissions:") + L"\n\"" + sourceResolved + L"\" ->\n\"" + targetResolved + L"\"" + L"\n\n" + getLastErrorFormatted() + L" (W)"); /* - PSECURITY_DESCRIPTOR buffer = NULL; - PSID owner = NULL; - PSID group = NULL; - PACL dacl = NULL; - PACL sacl = NULL; + PSECURITY_DESCRIPTOR buffer = nullptr; + PSID owner = nullptr; + PSID group = nullptr; + PACL dacl = nullptr; + PACL sacl = nullptr; //File Security and Access Rights: http://msdn.microsoft.com/en-us/library/aa364399(v=VS.85).aspx //SECURITY_INFORMATION Access Rights: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379573(v=vs.85).aspx @@ -1135,10 +1151,10 @@ void copyObjectPermissions(const Zstring& source, const Zstring& target, ProcSym 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | (procSl == SYMLINK_DIRECT ? FILE_FLAG_OPEN_REPARSE_POINT : 0), //FILE_FLAG_BACKUP_SEMANTICS needed to open a directory - NULL); + nullptr); if (hSource == INVALID_HANDLE_VALUE) throw FileError(_("Error copying file permissions:") + L"\n\"" + source + L"\" ->\n\"" + target + L"\"" + L"\n\n" + getLastErrorFormatted() + L" (OR)"); - ZEN_ON_BLOCK_EXIT(::CloseHandle(hSource)); + ZEN_ON_SCOPE_EXIT(::CloseHandle(hSource)); // DWORD rc = ::GetNamedSecurityInfo(const_cast<WCHAR*>(applyLongPathPrefix(source).c_str()), -> does NOT dereference symlinks! DWORD rc = ::GetSecurityInfo(hSource, //__in LPTSTR pObjectName, @@ -1152,7 +1168,7 @@ void copyObjectPermissions(const Zstring& source, const Zstring& target, ProcSym &buffer); //__out_opt PSECURITY_DESCRIPTOR *ppSecurityDescriptor if (rc != ERROR_SUCCESS) throw FileError(_("Error copying file permissions:") + L"\n\"" + source + L"\" ->\n\"" + target + L"\"" + L"\n\n" + getLastErrorFormatted(rc) + L" (R)"); - ZEN_ON_BLOCK_EXIT(::LocalFree(buffer)); + ZEN_ON_SCOPE_EXIT(::LocalFree(buffer)); SECURITY_DESCRIPTOR_CONTROL secCtrl = 0; { @@ -1172,7 +1188,7 @@ void copyObjectPermissions(const Zstring& source, const Zstring& target, ProcSym 0, // lpSecurityAttributes OPEN_EXISTING, // dwCreationDisposition FILE_FLAG_BACKUP_SEMANTICS | (procSl == SYMLINK_DIRECT ? FILE_FLAG_OPEN_REPARSE_POINT : 0), // dwFlagsAndAttributes - NULL); // hTemplateFile + nullptr); // hTemplateFile }); if (targetHandle.get() == INVALID_HANDLE_VALUE) @@ -1233,7 +1249,7 @@ void createDirectory_straight(const Zstring& directory, const Zstring& templateD //- it may fail with "wrong parameter (error code 87)" when source is on mapped online storage //- automatically copies symbolic links if encountered: unfortunately it doesn't copy symlinks over network shares but silently creates empty folders instead (on XP)! //- it isn't able to copy most junctions because of missing permissions (although target path can be retrieved alternatively!) - if (!::CreateDirectory(applyLongPathPrefixCreateDir(directory).c_str(), NULL)) + if (!::CreateDirectory(applyLongPathPrefixCreateDir(directory).c_str(), nullptr)) #elif defined FFS_LINUX if (::mkdir(directory.c_str(), 0755) != 0) #endif @@ -1282,10 +1298,10 @@ void createDirectory_straight(const Zstring& directory, const Zstring& templateD 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, - NULL); + nullptr); if (hDir != INVALID_HANDLE_VALUE) { - ZEN_ON_BLOCK_EXIT(::CloseHandle(hDir)); + ZEN_ON_SCOPE_EXIT(::CloseHandle(hDir)); USHORT cmpState = COMPRESSION_FORMAT_DEFAULT; @@ -1294,16 +1310,16 @@ void createDirectory_straight(const Zstring& directory, const Zstring& templateD FSCTL_SET_COMPRESSION, //dwIoControlCode &cmpState, //input buffer sizeof(cmpState), //size of input buffer - NULL, //lpOutBuffer + nullptr, //lpOutBuffer 0, //OutBufferSize &bytesReturned, //number of bytes returned - NULL); //OVERLAPPED structure + nullptr); //OVERLAPPED structure } } } } #endif - zen::ScopeGuard guardNewDir = zen::makeGuard([&]() { removeDirectory(directory); }); //ensure cleanup: + zen::ScopeGuard guardNewDir = zen::makeGuard([&] { removeDirectory(directory); }); //ensure cleanup: //enforce copying file permissions: it's advertized on GUI... if (copyFilePermissions) @@ -1333,7 +1349,7 @@ void createDirectoryRecursively(const Zstring& directory, const Zstring& templat if (dirExists(directory)) return; #endif - else //if "somethingExists" we needn't create the parent directory + else //if "not somethingExists" we need to create the parent directory { //try to create parent folders first const Zstring dirParent = beforeLast(directory, FILE_NAME_SEPARATOR); @@ -1399,7 +1415,7 @@ void zen::copySymlink(const Zstring& sourceLink, const Zstring& targetLink, bool throw FileError(_("Error copying symbolic link:") + L"\n\"" + sourceLink + L"\" ->\n\"" + targetLink + L"\"" + L"\n\n" + getLastErrorFormatted()); //allow only consistent objects to be created -> don't place before ::symlink, targetLink may already exist - zen::ScopeGuard guardNewDir = zen::makeGuard([&]() + zen::ScopeGuard guardNewDir = zen::makeGuard([&] { #ifdef FFS_WIN if (isDirLink) @@ -1430,7 +1446,7 @@ Zstring createTempName(const Zstring& filename) //ensure uniqueness for (int i = 1; somethingExists(output); ++i) - output = filename + Zchar('_') + toString<Zstring>(i) + zen::TEMP_FILE_ENDING; + output = filename + Zchar('_') + numberTo<Zstring>(i) + zen::TEMP_FILE_ENDING; return output; } @@ -1439,20 +1455,17 @@ Zstring createTempName(const Zstring& filename) class CallbackData { public: - CallbackData(CallbackCopyFile* cb, //may be NULL + CallbackData(CallbackCopyFile* cb, //may be nullptr const Zstring& sourceFile, - const Zstring& targetFile, - bool osIsvistaOrLater) : + const Zstring& targetFile) : userCallback(cb), sourceFile_(sourceFile), targetFile_(targetFile), - osIsvistaOrLater_(osIsvistaOrLater), exceptionInUserCallback(false) {} CallbackCopyFile* userCallback; //optional! const Zstring& sourceFile_; const Zstring& targetFile_; - const bool osIsvistaOrLater_; //there is mixed responsibility in this class, pure read-only data and abstraction for error reporting //however we need to keep it together as ::CopyFileEx() requires! @@ -1526,7 +1539,7 @@ DWORD CALLBACK copyCallbackInternal(LARGE_INTEGER totalFileSize, CallbackData& cbd = *static_cast<CallbackData*>(lpData); if (dwCallbackReason == CALLBACK_STREAM_SWITCH && //called up-front for every file (even if 0-sized) - dwStreamNumber == 1) //ADS! + dwStreamNumber == 1) //consider ADS! { //#################### return source file attributes ################################ BY_HANDLE_FILE_INFORMATION fileInfoSrc = {}; @@ -1556,14 +1569,14 @@ DWORD CALLBACK copyCallbackInternal(LARGE_INTEGER totalFileSize, if (!::GetFileTime(hSourceFile, //__in HANDLE hFile, &creationTime, //__out_opt LPFILETIME lpCreationTime, - NULL, //__out_opt LPFILETIME lpLastAccessTime, - NULL)) //__out_opt LPFILETIME lpLastWriteTime + nullptr, //__out_opt LPFILETIME lpLastAccessTime, + nullptr)) //__out_opt LPFILETIME lpLastWriteTime { cbd.reportError(_("Error reading file attributes:") + L"\n\"" + cbd.sourceFile_ + L"\"" + L"\n\n" + getLastErrorFormatted()); return PROGRESS_CANCEL; } - ::SetFileTime(hDestinationFile, &creationTime, NULL, NULL); //no error handling! + ::SetFileTime(hDestinationFile, &creationTime, nullptr, nullptr); //no error handling! //############################################################################## } @@ -1574,11 +1587,11 @@ DWORD CALLBACK copyCallbackInternal(LARGE_INTEGER totalFileSize, { //some odd check for some possible(?) error condition if (totalBytesTransferred.QuadPart < 0) //let's see if someone answers the call... - ::MessageBox(NULL, L"You've just discovered a bug in WIN32 API function \"CopyFileEx\"! \n\n\ + ::MessageBox(nullptr, L"You've just discovered a bug in WIN32 API function \"CopyFileEx\"! \n\n\ Please write a mail to the author of FreeFileSync at zhnmju123@gmx.de and simply state that\n\ \"totalBytesTransferred.HighPart can be below zero\"!\n\n\ This will then be handled in future versions of FreeFileSync.\n\nThanks -ZenJu", - NULL, 0); + nullptr, 0); try { cbd.userCallback->updateCopyStatus(UInt64(totalBytesTransferred.QuadPart)); @@ -1604,7 +1617,8 @@ void rawCopyWinApi_sub(const Zstring& sourceFile, CallbackCopyFile* callback, FileAttrib* newAttrib) //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked { - zen::ScopeGuard guardTarget = zen::makeGuard([&]() { removeFile(targetFile); }); //transactional behavior: guard just before starting copy, we don't trust ::CopyFileEx(), do we ;) + zen::ScopeGuard guardTarget = zen::makeGuard([&] { try { removeFile(targetFile); } catch (...) {} }); + //transactional behavior: guard just before starting copy, we don't trust ::CopyFileEx(), do we? ;) DWORD copyFlags = COPY_FILE_FAIL_IF_EXISTS; @@ -1612,25 +1626,19 @@ void rawCopyWinApi_sub(const Zstring& sourceFile, static bool nonEncSupported = false; { static boost::once_flag initNonEncOnce = BOOST_ONCE_INIT; //caveat: function scope static initialization is not thread-safe in VS 2010! - boost::call_once(initNonEncOnce, []() { nonEncSupported = winXpOrLater(); }); //encrypted destination is not supported with Windows 2000 + boost::call_once(initNonEncOnce, [] { nonEncSupported = winXpOrLater(); }); //encrypted destination is not supported with Windows 2000 } if (nonEncSupported) copyFlags |= COPY_FILE_ALLOW_DECRYPTED_DESTINATION; - static bool osIsvistaOrLater = false; - { - static boost::once_flag initVistaLaterOnce = BOOST_ONCE_INIT; //caveat: function scope static initialization is not thread-safe in VS 2010! - boost::call_once(initVistaLaterOnce, []() { osIsvistaOrLater = vistaOrLater(); }); - } - - CallbackData cbd(callback, sourceFile, targetFile, osIsvistaOrLater); + CallbackData cbd(callback, sourceFile, targetFile); const bool success = ::CopyFileEx( //same performance like CopyFile() applyLongPathPrefix(sourceFile).c_str(), applyLongPathPrefix(targetFile).c_str(), copyCallbackInternal, &cbd, - NULL, + nullptr, copyFlags) == TRUE; //silence x64 perf warning cbd.evaluateErrors(); //throw ?, process errors in callback first! @@ -1725,8 +1733,8 @@ void rawCopyWinApi(const Zstring& sourceFile, // /* // BackupRead() FileRead() CopyFileEx() // -------------------------------------------- -// Attributes NO NO YES -// create time NO NO NO +// Attributes NO NO YES +// create time NO NO NO // ADS YES NO YES // Encrypted NO(silent fail) NO YES // Compressed NO NO NO @@ -1737,18 +1745,20 @@ void rawCopyWinApi(const Zstring& sourceFile, // compatible with: BackupRead() FileRead() // */ // +//FILE_FLAG_BACKUP_SEMANTICS ?????? +// // //open sourceFile for reading // HANDLE hFileIn = ::CreateFile(applyLongPathPrefix(sourceFile).c_str(), // GENERIC_READ, // FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, //all shared modes are required to read files that are open in other applications -// 0, +// nullptr, // OPEN_EXISTING, // FILE_FLAG_SEQUENTIAL_SCAN, -// NULL); +// nullptr); // if (hFileIn == INVALID_HANDLE_VALUE) // { // const DWORD lastError = ::GetLastError(); -// const std::wstring& errorMessage = _("Error opening file:") + "\n\"" + sourceFile + "\"" + "\n\n" + getLastErrorFormatted(lastError); +// const std::wstring& errorMessage = Error opening file: + "\n\"" + sourceFile + "\"" + "\n\n" + getLastErrorFormatted(lastError); // // //if file is locked (try to) use Windows Volume Shadow Copy Service // if (lastError == ERROR_SHARING_VIOLATION || @@ -1757,12 +1767,12 @@ void rawCopyWinApi(const Zstring& sourceFile, // // throw FileError(errorMessage); // } -// ZEN_ON_BLOCK_EXIT(::CloseHandle, hFileIn); +// ZEN_ON_SCOPE_EXIT(::CloseHandle, hFileIn); // // // BY_HANDLE_FILE_INFORMATION infoFileIn = {}; // if (!::GetFileInformationByHandle(hFileIn, &infoFileIn)) -// throw FileError(_("Error reading file attributes:") + "\n\"" + sourceFile + "\"" + "\n\n" + getLastErrorFormatted()); +// throw FileError(Error reading file attributes:") + "\n\"" + sourceFile + "\"" + "\n\n" + getLastErrorFormatted()); // // //####################################### DST hack ########################################### // if (dst::isFatDrive(sourceFile)) //throw() @@ -1794,15 +1804,14 @@ void rawCopyWinApi(const Zstring& sourceFile, // HANDLE hFileOut = ::CreateFile(applyLongPathPrefix(targetFile).c_str(), // GENERIC_READ | GENERIC_WRITE, //read access required for FSCTL_SET_COMPRESSION // FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, -// 0, +// nullptr, // CREATE_NEW, // (infoFileIn.dwFileAttributes & validAttribs) | FILE_FLAG_SEQUENTIAL_SCAN, -// NULL); +// nullptr); // if (hFileOut == INVALID_HANDLE_VALUE) // { // const DWORD lastError = ::GetLastError(); -// const std::wstring& errorMessage = _("Error writing file:") + "\n\"" + targetFile + "\"" + -// "\n\n" + getLastErrorFormatted(lastError); +// const std::wstring& errorMessage = // // if (lastError == ERROR_FILE_EXISTS) // throw ErrorTargetExisting(errorMessage); @@ -1814,7 +1823,7 @@ void rawCopyWinApi(const Zstring& sourceFile, // } // Loki::ScopeGuard guardTarget = Loki::MakeGuard(&removeFile, targetFile); //transactional behavior: guard just after opening target and before managing hFileOut // -// ZEN_ON_BLOCK_EXIT(::CloseHandle, hFileOut); +// ZEN_ON_SCOPE_EXIT(::CloseHandle, hFileOut); // // //#ifndef _MSC_VER @@ -1822,14 +1831,14 @@ void rawCopyWinApi(const Zstring& sourceFile, //#endif // DWORD fsFlags = 0; // if (!GetVolumeInformationByHandleW(hFileOut, //__in HANDLE hFile, -// NULL, //__out_opt LPTSTR lpVolumeNameBuffer, +// nullptr, //__out_opt LPTSTR lpVolumeNameBuffer, // 0, //__in DWORD nVolumeNameSize, -// NULL, //__out_opt LPDWORD lpVolumeSerialNumber, -// NULL, //__out_opt LPDWORD lpMaximumComponentLength, +// nullptr, //__out_opt LPDWORD lpVolumeSerialNumber, +// nullptr, //__out_opt LPDWORD lpMaximumComponentLength, // &fsFlags, //__out_opt LPDWORD lpFileSystemFlags, -// NULL, //__out LPTSTR lpFileSystemNameBuffer, +// nullptr, //__out LPTSTR lpFileSystemNameBuffer, // 0)) //__in DWORD nFileSystemNameSize -// throw FileError(_("Error reading file attributes:") + "\n\"" + sourceFile + "\"" + "\n\n" + getLastErrorFormatted()); +// throw FileError(Error reading file attributes:") + "\n\"" + sourceFile + "\"" + "\n\n" + getLastErrorFormatted()); // // const bool sourceIsEncrypted = (infoFileIn.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) != 0; // const bool sourceIsCompressed = (infoFileIn.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) != 0; @@ -1851,12 +1860,11 @@ void rawCopyWinApi(const Zstring& sourceFile, // FSCTL_SET_COMPRESSION, //dwIoControlCode // &cmpState, //input buffer // sizeof(cmpState), //size of input buffer -// NULL, //lpOutBuffer +// nullptr, //lpOutBuffer // 0, //OutBufferSize // &bytesReturned, //number of bytes returned -// NULL)) //OVERLAPPED structure -// throw FileError(_("Error writing file:") + "\n\"" + targetFile + "\"" + -// "\n\n" + getLastErrorFormatted() + +// nullptr)) //OVERLAPPED structure +// throw FileError( ddd + // "\nFailed to write NTFS compressed attribute!"); // } // @@ -1868,14 +1876,13 @@ void rawCopyWinApi(const Zstring& sourceFile, // DWORD bytesReturned = 0; // if (!DeviceIoControl(hFileOut, //handle to file // FSCTL_SET_SPARSE, //dwIoControlCode -// NULL, //input buffer +// nullptr, //input buffer // 0, //size of input buffer -// NULL, //lpOutBuffer +// nullptr, //lpOutBuffer // 0, //OutBufferSize // &bytesReturned, //number of bytes returned -// NULL)) //OVERLAPPED structure -// throw FileError(_("Error writing file:") + "\n\"" + targetFile + "\"" + -// "\n\n" + getLastErrorFormatted() + +// nullptr)) //OVERLAPPED structure +// throw FileError(dddd // "\nFailed to write NTFS sparse attribute!"); // } // } @@ -1889,13 +1896,13 @@ void rawCopyWinApi(const Zstring& sourceFile, // // struct ManageCtxt //manage context for BackupRead()/BackupWrite() // { -// ManageCtxt() : read(NULL), write(NULL) {} +// ManageCtxt() : read(nullptr), write(nullptr) {} // ~ManageCtxt() // { -// if (read != NULL) -// ::BackupRead (0, NULL, 0, NULL, true, false, &read); -// if (write != NULL) -// ::BackupWrite(0, NULL, 0, NULL, true, false, &write); +// if (read != nullptr) +// ::BackupRead (0, nullptr, 0, nullptr, true, false, &read); +// if (write != nullptr) +// ::BackupWrite(0, nullptr, 0, nullptr, true, false, &write); // } // // LPVOID read; @@ -1919,19 +1926,19 @@ void rawCopyWinApi(const Zstring& sourceFile, // false, //__in BOOL bAbort, // false, //__in BOOL bProcessSecurity, // &context.read)) //__out LPVOID *lpContext -// throw FileError(_("Error reading file:") + "\n\"" + sourceFile + "\"" + +// throw FileError(Error reading file:") + "\n\"" + sourceFile + "\"" + // "\n\n" + getLastErrorFormatted()); // } // else if (!::ReadFile(hFileIn, //__in HANDLE hFile, // &buffer[0], //__out LPVOID lpBuffer, // BUFFER_SIZE, //__in DWORD nNumberOfBytesToRead, // &bytesRead, //__out_opt LPDWORD lpNumberOfBytesRead, -// NULL)) //__inout_opt LPOVERLAPPED lpOverlapped -// throw FileError(_("Error reading file:") + "\n\"" + sourceFile + "\"" + +// nullptr)) //__inout_opt LPOVERLAPPED lpOverlapped +// throw FileError(Error reading file:") + "\n\"" + sourceFile + "\"" + // "\n\n" + getLastErrorFormatted()); // // if (bytesRead > BUFFER_SIZE) -// throw FileError(_("Error reading file:") + "\n\"" + sourceFile + "\"" + +// throw FileError(Error reading file:") + "\n\"" + sourceFile + "\"" + // "\n\n" + "buffer overflow"); // // if (bytesRead < BUFFER_SIZE) @@ -1948,19 +1955,17 @@ void rawCopyWinApi(const Zstring& sourceFile, // false, //__in BOOL bAbort, // false, //__in BOOL bProcessSecurity, // &context.write)) //__out LPVOID *lpContext -// throw FileError(_("Error writing file:") + "\n\"" + targetFile + "\"" + -// "\n\n" + getLastErrorFormatted() + " (w)"); //w -> distinguish from fopen error message! +// throw FileError(ddd" (w)"); //w -> distinguish from fopen error message! // } // else if (!::WriteFile(hFileOut, //__in HANDLE hFile, // &buffer[0], //__out LPVOID lpBuffer, // bytesRead, //__in DWORD nNumberOfBytesToWrite, // &bytesWritten, //__out_opt LPDWORD lpNumberOfBytesWritten, -// NULL)) //__inout_opt LPOVERLAPPED lpOverlapped -// throw FileError(_("Error writing file:") + "\n\"" + targetFile + "\"" + -// "\n\n" + getLastErrorFormatted() + " (w)"); //w -> distinguish from fopen error message! +// nullptr)) //__inout_opt LPOVERLAPPED lpOverlapped +// throw FileError(ddd" (w)"); //w -> distinguish from fopen error message! // // if (bytesWritten != bytesRead) -// throw FileError(_("Error writing file:") + "\n\"" + targetFile + "\"" + "\n\n" + "incomplete write"); +// throw FileError(ddd + "incomplete write"); // // totalBytesTransferred += bytesRead; // @@ -1969,15 +1974,15 @@ void rawCopyWinApi(const Zstring& sourceFile, //#endif // // //invoke callback method to update progress indicators -// if (callback != NULL) +// if (callback != nullptr) // switch (callback->updateCopyStatus(totalBytesTransferred)) // { // case CallbackCopyFile::CONTINUE: // break; // // case CallbackCopyFile::CANCEL: //a user aborted operation IS an error condition! -// throw FileError(_("Error copying file:") + "\n\"" + sourceFile + "\" ->\n\"" + -// targetFile + "\"\n\n" + _("Operation aborted!")); +// throw FileError(Error copying file:") + "\n\"" + sourceFile + "\" ->\n\"" + +// targetFile + "\"\n\n" + Operation aborted!")); // } // } // while (!eof); @@ -1987,18 +1992,18 @@ void rawCopyWinApi(const Zstring& sourceFile, // { // LARGE_INTEGER inputSize = {}; // if (!::GetFileSizeEx(hFileIn, &inputSize)) -// throw FileError(_("Error reading file attributes:") + "\n\"" + sourceFile + "\"" + "\n\n" + getLastErrorFormatted()); +// throw FileError(Error reading file attributes:") + "\n\"" + sourceFile + "\"" + "\n\n" + getLastErrorFormatted()); // // if (inputSize.QuadPart != 0) -// throw FileError(_("Error reading file:") + "\n\"" + sourceFile + "\"" + "\n\n" + "unknown error"); +// throw FileError(Error reading file:") + "\n\"" + sourceFile + "\"" + "\n\n" + "unknown error"); // } // // //time needs to be set at the end: BackupWrite() changes file time // if (!::SetFileTime(hFileOut, // &infoFileIn.ftCreationTime, -// NULL, +// nullptr, // &infoFileIn.ftLastWriteTime)) -// throw FileError(_("Error changing modification time:") + "\n\"" + targetFile + "\"" + "\n\n" + getLastErrorFormatted()); +// throw FileError(Error changing modification time:") + "\n\"" + targetFile + "\"" + "\n\n" + getLastErrorFormatted()); // // //#ifndef NDEBUG //dst hack: verify data written @@ -2024,15 +2029,15 @@ void rawCopyWinApi(const Zstring& sourceFile, // 0, // CREATE_NEW, // FILE_FLAG_SEQUENTIAL_SCAN, -// NULL); +// nullptr); // DWORD br = 0; -// if (!::DeviceIoControl(hSparse, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &br,NULL)) +// if (!::DeviceIoControl(hSparse, FSCTL_SET_SPARSE, nullptr, 0, nullptr, 0, &br,nullptr)) // throw 1; // // LARGE_INTEGER liDistanceToMove = {}; // liDistanceToMove.QuadPart = 1024 * 1024 * 1024; //create 5 TB sparse file // liDistanceToMove.QuadPart *= 5 * 1024; // -// if (!::SetFilePointerEx(hSparse, liDistanceToMove, NULL, FILE_BEGIN)) +// if (!::SetFilePointerEx(hSparse, liDistanceToMove, nullptr, FILE_BEGIN)) // throw 1; // // if (!SetEndOfFile(hSparse)) @@ -2040,7 +2045,7 @@ void rawCopyWinApi(const Zstring& sourceFile, // // FILE_ZERO_DATA_INFORMATION zeroInfo = {}; // zeroInfo.BeyondFinalZero.QuadPart = liDistanceToMove.QuadPart; -// if (!::DeviceIoControl(hSparse, FSCTL_SET_ZERO_DATA, &zeroInfo, sizeof(zeroInfo), NULL, 0, &br, NULL)) +// if (!::DeviceIoControl(hSparse, FSCTL_SET_ZERO_DATA, &zeroInfo, sizeof(zeroInfo), nullptr, 0, &br, nullptr)) // throw 1; // // ::CloseHandle(hSparse); @@ -2054,7 +2059,7 @@ void rawCopyStream(const Zstring& sourceFile, CallbackCopyFile* callback, FileAttrib* newAttrib) //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting { - zen::ScopeGuard guardTarget = zen::makeGuard([&] { removeFile(targetFile); }); //transactional behavior: place guard before lifetime of FileOutput + zen::ScopeGuard guardTarget = zen::makeGuard([&] { try { removeFile(targetFile); } catch (...) {} }); //transactional behavior: place guard before lifetime of FileOutput try { //open sourceFile for reading diff --git a/zen/file_handling.h b/zen/file_handling.h index 80350731..b0d97a6c 100644 --- a/zen/file_handling.h +++ b/zen/file_handling.h @@ -48,7 +48,7 @@ UInt64 getFilesize(const Zstring& filename); //throw FileError //file handling bool removeFile(const Zstring& filename); //return "true" if file was actually deleted; throw FileError -void removeDirectory(const Zstring& directory, CallbackRemoveDir* callback = NULL); //throw FileError +void removeDirectory(const Zstring& directory, CallbackRemoveDir* callback = nullptr); //throw FileError //rename file or directory: no copying!!! @@ -80,8 +80,8 @@ void copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPathMissi const Zstring& targetFile, //symlink handling: dereference source bool copyFilePermissions, bool transactionalCopy, - CallbackCopyFile* callback, //may be NULL - FileAttrib* newAttrib = NULL); //return current attributes at the time of copy + CallbackCopyFile* callback, //may be nullptr + FileAttrib* newAttrib = nullptr); //return current attributes at the time of copy //Note: it MAY happen that copyFile() leaves temp files behind, e.g. temporary network drop. // => clean them up at an appropriate time (automatically set sync directions to delete them). They have the following ending: const Zstring TEMP_FILE_ENDING = Zstr(".ffs_tmp"); diff --git a/zen/file_id.cpp b/zen/file_id.cpp index 4f9e3600..40efa373 100644 --- a/zen/file_id.cpp +++ b/zen/file_id.cpp @@ -27,13 +27,13 @@ zen::FileId zen::getFileID(const Zstring& filename) const HANDLE hFile = ::CreateFile(zen::applyLongPathPrefix(filename).c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, + nullptr, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, //FILE_FLAG_BACKUP_SEMANTICS needed to open a directory - NULL); + nullptr); if (hFile != INVALID_HANDLE_VALUE) { - ZEN_ON_BLOCK_EXIT(::CloseHandle(hFile)); + ZEN_ON_SCOPE_EXIT(::CloseHandle(hFile)); BY_HANDLE_FILE_INFORMATION fileInfo = {}; if (::GetFileInformationByHandle(hFile, &fileInfo)) diff --git a/zen/file_id_def.h b/zen/file_id_def.h index b65496be..c51a0ecc 100644 --- a/zen/file_id_def.h +++ b/zen/file_id_def.h @@ -21,7 +21,7 @@ namespace zen { #ifdef FFS_WIN -typedef std::pair<decltype(BY_HANDLE_FILE_INFORMATION().dwVolumeSerialNumber), decltype(ULARGE_INTEGER().QuadPart)> FileId; //(volume serial number, file ID) +typedef std::pair<DWORD, ULONGLONG> FileId; //(volume serial number, file ID) inline FileId extractFileID(const BY_HANDLE_FILE_INFORMATION& fileInfo) @@ -41,16 +41,10 @@ FileId extractFileID(DWORD dwVolumeSerialNumber, ULARGE_INTEGER fileId) FileId(dwVolumeSerialNumber, fileId.QuadPart) : FileId(); } -namespace impl -{ -inline -void validate(const FileId& id, const BY_HANDLE_FILE_INFORMATION& fileInfo) -{ - assert_static(sizeof(id.second) == sizeof(fileInfo.nFileIndexHigh) + sizeof(fileInfo.nFileIndexLow)); - assert_static(sizeof(id.first ) == sizeof(DWORD)); - assert_static(sizeof(id.second) == sizeof(ULARGE_INTEGER)); -} -} +assert_static(sizeof(FileId().first ) == sizeof(BY_HANDLE_FILE_INFORMATION().dwVolumeSerialNumber)); +assert_static(sizeof(FileId().second) == sizeof(BY_HANDLE_FILE_INFORMATION().nFileIndexHigh) + sizeof(BY_HANDLE_FILE_INFORMATION().nFileIndexLow)); +assert_static(sizeof(FileId().second) == sizeof(ULARGE_INTEGER)); + #elif defined FFS_LINUX namespace impl { typedef struct ::stat StatDummy; } //sigh... @@ -58,7 +52,7 @@ namespace impl { typedef struct ::stat StatDummy; } //sigh... typedef std::pair<decltype(impl::StatDummy::st_dev), decltype(impl::StatDummy::st_ino)> FileId; //(device id, inode) inline -FileId extractFileID(const struct stat& fileInfo) +FileId extractFileID(const struct ::stat& fileInfo) { return fileInfo.st_dev != 0 && fileInfo.st_ino != 0 ? FileId(fileInfo.st_dev, fileInfo.st_ino) : FileId(); diff --git a/zen/file_io.cpp b/zen/file_io.cpp index ad1ecd6b..4c38bb22 100644 --- a/zen/file_io.cpp +++ b/zen/file_io.cpp @@ -8,9 +8,6 @@ #ifdef FFS_WIN #include "long_path_prefix.h" - -#elif defined FFS_LINUX -#include <cerrno> #endif using namespace zen; @@ -57,36 +54,21 @@ FileInput::FileInput(const Zstring& filename) : //throw FileError, ErrorNotExis for FFS most comparisons are probably between different disks => let's use FILE_FLAG_SEQUENTIAL_SCAN */ - NULL); + nullptr); if (fileHandle == INVALID_HANDLE_VALUE) - { - const DWORD lastError = ::GetLastError(); - - std::wstring errorMessage = _("Error opening file:") + L"\n\"" + filename_ + L"\"" + L"\n\n" + zen::getLastErrorFormatted(lastError); - - if (lastError == ERROR_FILE_NOT_FOUND || - lastError == ERROR_PATH_NOT_FOUND || - lastError == ERROR_BAD_NETPATH || - lastError == ERROR_NETNAME_DELETED) - throw ErrorNotExisting(errorMessage); - - throw FileError(errorMessage); - } - #elif defined FFS_LINUX fileHandle = ::fopen(filename.c_str(), "r,type=record,noseek"); //utilize UTF-8 filename - if (fileHandle == NULL) + if (!fileHandle) +#endif { - const int lastError = errno; - - std::wstring errorMessage = _("Error opening file:") + L"\n\"" + filename_ + L"\"" + L"\n\n" + zen::getLastErrorFormatted(lastError); + const ErrorCode lastError = getLastError(); + std::wstring errorMessage = _("Error reading file:") + L"\n\"" + filename_ + L"\"" + L"\n\n" + zen::getLastErrorFormatted(lastError) + L" (open)"; - if (lastError == ENOENT) + if (errorCodeForNotExisting(lastError)) throw ErrorNotExisting(errorMessage); throw FileError(errorMessage); } -#endif } @@ -95,7 +77,7 @@ FileInput::~FileInput() #ifdef FFS_WIN ::CloseHandle(fileHandle); #elif defined FFS_LINUX - ::fclose(fileHandle); //NEVER allow passing NULL to fclose! -> crash!; fileHandle != NULL in this context! + ::fclose(fileHandle); //NEVER allow passing nullptr to fclose! -> crash!; fileHandle != nullptr in this context! #endif } @@ -108,15 +90,15 @@ size_t FileInput::read(void* buffer, size_t bytesToRead) //returns actual number buffer, //__out LPVOID lpBuffer, static_cast<DWORD>(bytesToRead), //__in DWORD nNumberOfBytesToRead, &bytesRead, //__out_opt LPDWORD lpNumberOfBytesRead, - NULL)) //__inout_opt LPOVERLAPPED lpOverlapped + nullptr)) //__inout_opt LPOVERLAPPED lpOverlapped #elif defined FFS_LINUX const size_t bytesRead = ::fread(buffer, 1, bytesToRead, fileHandle); if (::ferror(fileHandle) != 0) #endif - throw FileError(_("Error reading file:") + L"\n\"" + filename_ + L"\"" + L"\n\n" + zen::getLastErrorFormatted() + L" (r)"); + throw FileError(_("Error reading file:") + L"\n\"" + filename_ + L"\"" + L"\n\n" + zen::getLastErrorFormatted() + L" (read)"); #ifdef FFS_WIN - if (bytesRead < bytesToRead) //falsify only! + if (bytesRead < bytesToRead) //verify only! #elif defined FFS_LINUX if (::feof(fileHandle) != 0) #endif @@ -153,11 +135,11 @@ FileOutput::FileOutput(const Zstring& filename, AccessFlag access) : //throw Fil 0, access == ACC_OVERWRITE ? CREATE_ALWAYS : CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, - NULL); + nullptr); if (fileHandle == INVALID_HANDLE_VALUE) { const DWORD lastError = ::GetLastError(); - std::wstring errorMessage = _("Error writing file:") + L"\n\"" + filename_ + L"\"" + L"\n\n" + zen::getLastErrorFormatted(lastError); + std::wstring errorMessage = _("Error writing file:") + L"\n\"" + filename_ + L"\"" L"\n\n" + zen::getLastErrorFormatted(lastError); if (lastError == ERROR_FILE_EXISTS) throw ErrorTargetExisting(errorMessage); @@ -172,10 +154,10 @@ FileOutput::FileOutput(const Zstring& filename, AccessFlag access) : //throw Fil fileHandle = ::fopen(filename.c_str(), //GNU extension: https://www.securecoding.cert.org/confluence/display/cplusplus/FIO03-CPP.+Do+not+make+assumptions+about+fopen()+and+file+creation access == ACC_OVERWRITE ? "w,type=record,noseek" : "wx,type=record,noseek"); - if (fileHandle == NULL) + if (!fileHandle) { const int lastError = errno; - std::wstring errorMessage = _("Error writing file:") + L"\n\"" + filename_ + L"\"" + L"\n\n" + zen::getLastErrorFormatted(lastError); + std::wstring errorMessage = _("Error writing file:") + L"\n\"" + filename_ + L"\"" L"\n\n" + zen::getLastErrorFormatted(lastError); if (lastError == EEXIST) throw ErrorTargetExisting(errorMessage); @@ -193,7 +175,7 @@ FileOutput::~FileOutput() #ifdef FFS_WIN ::CloseHandle(fileHandle); #elif defined FFS_LINUX - ::fclose(fileHandle); //NEVER allow passing NULL to fclose! -> crash! + ::fclose(fileHandle); //NEVER allow passing nullptr to fclose! -> crash! #endif } @@ -206,13 +188,13 @@ void FileOutput::write(const void* buffer, size_t bytesToWrite) //throw FileErro buffer, //__out LPVOID lpBuffer, static_cast<DWORD>(bytesToWrite), //__in DWORD nNumberOfBytesToWrite, &bytesWritten, //__out_opt LPDWORD lpNumberOfBytesWritten, - NULL)) //__inout_opt LPOVERLAPPED lpOverlapped + nullptr)) //__inout_opt LPOVERLAPPED lpOverlapped #elif defined FFS_LINUX const size_t bytesWritten = ::fwrite(buffer, 1, bytesToWrite, fileHandle); if (::ferror(fileHandle) != 0) #endif - throw FileError(_("Error writing file:") + L"\n\"" + filename_ + L"\"" + L"\n\n" + zen::getLastErrorFormatted() + L" (w)"); //w -> distinguish from fopen error message! + throw FileError(_("Error writing file:") + L"\n\"" + filename_ + L"\"" L"\n\n" + zen::getLastErrorFormatted() + L" (w)"); //w -> distinguish from fopen error message! if (bytesWritten != bytesToWrite) //must be fulfilled for synchronous writes! - throw FileError(_("Error writing file:") + L"\n\"" + filename_ + L"\"" + L"\n\n" + L"incomplete write"); + throw FileError(_("Error writing file:") + L"\n\"" + filename_ + L"\"" L"\n\n" + L"incomplete write"); } diff --git a/zen/file_traverser.cpp b/zen/file_traverser.cpp index a0979c49..c3536825 100644 --- a/zen/file_traverser.cpp +++ b/zen/file_traverser.cpp @@ -21,7 +21,6 @@ #elif defined FFS_LINUX #include <sys/stat.h> #include <dirent.h> -#include <cerrno> #endif using namespace zen; @@ -67,10 +66,10 @@ bool extractFileInfoFromSymlink(const Zstring& linkName, zen::TraverseCallback:: 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, - NULL); + nullptr); if (hFile == INVALID_HANDLE_VALUE) return false; - ZEN_ON_BLOCK_EXIT(::CloseHandle(hFile)); + ZEN_ON_SCOPE_EXIT(::CloseHandle(hFile)); BY_HANDLE_FILE_INFORMATION fileInfoByHandle = {}; if (!::GetFileInformationByHandle(hFile, &fileInfoByHandle)) @@ -92,11 +91,10 @@ DWORD retrieveVolumeSerial(const Zstring& pathName) //returns 0 on error or if s //- indirection: subst S: %USERPROFILE% // -> GetVolumePathName() on the other hand resolves "S:\Desktop\somedir" to "S:\Desktop\" - nice try... - //dynamically load windows API function (existing since Windows XP) typedef BOOL (WINAPI* GetFileInformationByHandleFunc)(HANDLE hFile, LPBY_HANDLE_FILE_INFORMATION lpFileInformation); - const SysDllFun<GetFileInformationByHandleFunc> getFileInformationByHandle(L"kernel32.dll", "GetFileInformationByHandle"); + const SysDllFun<GetFileInformationByHandleFunc> getFileInformationByHandle(L"kernel32.dll", "GetFileInformationByHandle"); //available since Windows XP if (!getFileInformationByHandle) { assert(false); @@ -106,13 +104,13 @@ DWORD retrieveVolumeSerial(const Zstring& pathName) //returns 0 on error or if s const HANDLE hDir = ::CreateFile(zen::applyLongPathPrefix(pathName).c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, + nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS /*needed to open a directory*/ /*| FILE_FLAG_OPEN_REPARSE_POINT -> no, we follow symlinks!*/ , - NULL); + nullptr); if (hDir == INVALID_HANDLE_VALUE) return 0; - ZEN_ON_BLOCK_EXIT(::CloseHandle(hDir)); + ZEN_ON_SCOPE_EXIT(::CloseHandle(hDir)); BY_HANDLE_FILE_INFORMATION fileInfo = {}; if (!getFileInformationByHandle(hDir, //__in HANDLE hFile, @@ -143,12 +141,12 @@ DWORD retrieveVolumeSerial(const Zstring& pathName) //returns 0 on error! DWORD volumeSerial = 0; if (!::GetVolumeInformation(volumePath.c_str(), //__in_opt LPCTSTR lpRootPathName, - NULL, //__out LPTSTR lpVolumeNameBuffer, + nullptr, //__out LPTSTR lpVolumeNameBuffer, 0, //__in DWORD nVolumeNameSize, &volumeSerial, //__out_opt LPDWORD lpVolumeSerialNumber, - NULL, //__out_opt LPDWORD lpMaximumComponentLength, - NULL, //__out_opt LPDWORD lpFileSystemFlags, - NULL, //__out LPTSTR lpFileSystemNameBuffer, + nullptr, //__out_opt LPDWORD lpMaximumComponentLength, + nullptr, //__out_opt LPDWORD lpFileSystemFlags, + nullptr, //__out LPTSTR lpFileSystemNameBuffer, 0)) //__in DWORD nFileSystemNameSize return 0; @@ -194,7 +192,7 @@ struct Win32Traverser { struct DirHandle { - DirHandle() : searchHandle(NULL), firstRead(true) {} + DirHandle() : searchHandle(nullptr), firstRead(true) {} HANDLE searchHandle; bool firstRead; @@ -276,7 +274,7 @@ struct FilePlusTraverser { struct DirHandle { - DirHandle() : searchHandle(NULL) {} + DirHandle() : searchHandle(nullptr) {} findplus::FindHandle searchHandle; }; @@ -286,7 +284,7 @@ struct FilePlusTraverser static void create(const Zstring& directory, DirHandle& hnd) //throw FileError { hnd.searchHandle = ::openDir(applyLongPathPrefix(directory).c_str()); - if (hnd.searchHandle == NULL) + if (hnd.searchHandle == nullptr) throw FileError(_("Error traversing directory:") + L"\n\"" + directory + L"\"" + L"\n\n" + zen::getLastErrorFormatted()); } @@ -315,10 +313,12 @@ struct FilePlusTraverser STATUS_UNSUCCESSFUL | ERROR_GEN_FAILURE STATUS_ACCESS_VIOLATION | ERROR_NOACCESS ->FileIdBothDirectoryInformation on XP accessing UDF */ + if (lastError == ERROR_INVALID_LEVEL || lastError == ERROR_NOT_SUPPORTED || lastError == ERROR_INVALID_PARAMETER || lastError == ERROR_BAD_NET_RESP || + lastError == ERROR_UNEXP_NET_ERR || //traverse network drive hosted by Win98 lastError == ERROR_GEN_FAILURE || lastError == ERROR_NOACCESS) { @@ -407,7 +407,7 @@ private: if (!openSuccess) return; //ignored error - ZEN_ON_BLOCK_EXIT(typedef Trav Trav; Trav::destroy(searchHandle)); + ZEN_ON_SCOPE_EXIT(typedef Trav Trav; Trav::destroy(searchHandle)); typename Trav::FindData fileInfo = {}; @@ -456,8 +456,7 @@ private: } else if (Trav::isDirectory(fileInfo)) //a directory... or symlink that needs to be followed (for directory symlinks this flag is set too!) { - const std::shared_ptr<TraverseCallback> rv = sink.onDir(shortName, fullName); - if (rv) + if (const std::shared_ptr<TraverseCallback> rv = sink.onDir(shortName, fullName)) traverse<Trav>(fullName, *rv, level + 1); } else //a file or symlink that is followed... @@ -471,7 +470,7 @@ private: } else { - Trav::extractFileInfo(fileInfo, volumeSerial, details); //make optional character of volumeSerial explicit in the interface + Trav::extractFileInfo(fileInfo, volumeSerial, details); //####################################### DST hack ########################################### if (isFatFileSystem) @@ -508,15 +507,15 @@ private: const dst::RawTime encodedTime = dst::fatEncodeUtcTime(i->second); //throw (std::runtime_error) { //may need to remove the readonly-attribute (e.g. FAT usb drives) - FileUpdateHandle updateHandle(i->first, [=]() + FileUpdateHandle updateHandle(i->first, [=] { return ::CreateFile(zen::applyLongPathPrefix(i->first).c_str(), - GENERIC_READ | GENERIC_WRITE, //use both when writing over network, see comment in file_io.cpp - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - NULL); + GENERIC_READ | GENERIC_WRITE, //use both when writing over network, see comment in file_io.cpp + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + 0, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + nullptr); }); if (updateHandle.get() == INVALID_HANDLE_VALUE) { @@ -527,7 +526,7 @@ private: if (!::SetFileTime(updateHandle.get(), &encodedTime.createTimeRaw, - NULL, + nullptr, &encodedTime.writeTimeRaw)) { ++failedAttempts; @@ -604,27 +603,27 @@ private: }, sink); - DIR* dirObj = NULL; + DIR* dirObj = nullptr; tryReportingError([&] { dirObj = ::opendir(directory.c_str()); //directory must NOT end with path separator, except "/" - if (dirObj == NULL) + if (!dirObj) throw FileError(_("Error traversing directory:") + L"\n\"" + directory + L"\"" + L"\n\n" + zen::getLastErrorFormatted()); }, sink); - if (dirObj == NULL) + if (!dirObj) return; //ignored error - ZEN_ON_BLOCK_EXIT(::closedir(dirObj)); //never close NULL handles! -> crash + ZEN_ON_SCOPE_EXIT(::closedir(dirObj)); //never close nullptr handles! -> crash while (true) { - struct ::dirent* dirEntry = NULL; + struct ::dirent* dirEntry = nullptr; tryReportingError([&] { if (::readdir_r(dirObj, reinterpret_cast< ::dirent*>(&buffer[0]), &dirEntry) != 0) throw FileError(_("Error traversing directory:") + L"\n\"" + directory + L"\"" + L"\n\n" + zen::getLastErrorFormatted()); }, sink); - if (dirEntry == NULL) //no more items or ignore error + if (!dirEntry) //no more items or ignore error return; diff --git a/zen/file_traverser.h b/zen/file_traverser.h index d6b69f86..ab46621f 100644 --- a/zen/file_traverser.h +++ b/zen/file_traverser.h @@ -66,7 +66,7 @@ struct DstHackCallback; //DST hack not required on Linux void traverseFolder(const Zstring& directory, //throw(); bool followSymlinks, TraverseCallback& sink, - DstHackCallback* dstCallback = NULL); //apply DST hack if callback is supplied + DstHackCallback* dstCallback = nullptr); //apply DST hack if callback is supplied //followSymlinks: //"true": Symlinks dereferenced and reported via onFile() and onDir() => onSymlink not used! //"false": Symlinks directly reported via onSymlink(), directory symlinks are not followed diff --git a/zen/fixed_list.h b/zen/fixed_list.h index 1b2af5bf..eedbfab9 100644 --- a/zen/fixed_list.h +++ b/zen/fixed_list.h @@ -18,13 +18,13 @@ class FixedList { struct Node { - Node() : next(NULL), val() {} - template <class A> Node(A&& a) : next(NULL), val(a) {} - template <class A, class B> Node(A&& a, B&& b) : next(NULL), val(a, b) {} - template <class A, class B, class C> Node(A&& a, B&& b, C&& c) : next(NULL), val(a, b, c) {} - template <class A, class B, class C, class D> Node(A&& a, B&& b, C&& c, D&& d) : next(NULL), val(a, b, c, d) {} - template <class A, class B, class C, class D, class E> Node(A&& a, B&& b, C&& c, D&& d, E&& e) : next(NULL), val(a, b, c, d, e) {} - template <class A, class B, class C, class D, class E, class F> Node(A&& a, B&& b, C&& c, D&& d, E&& e, F&& f) : next(NULL), val(a, b, c, d, e, f) {} + Node() : next(nullptr), val() {} + template <class A> Node(A&& a) : next(nullptr), val(a) {} + template <class A, class B> Node(A&& a, B&& b) : next(nullptr), val(a, b) {} + template <class A, class B, class C> Node(A&& a, B&& b, C&& c) : next(nullptr), val(a, b, c) {} + template <class A, class B, class C, class D> Node(A&& a, B&& b, C&& c, D&& d) : next(nullptr), val(a, b, c, d) {} + template <class A, class B, class C, class D, class E> Node(A&& a, B&& b, C&& c, D&& d, E&& e) : next(nullptr), val(a, b, c, d, e) {} + template <class A, class B, class C, class D, class E, class F> Node(A&& a, B&& b, C&& c, D&& d, E&& e, F&& f) : next(nullptr), val(a, b, c, d, e, f) {} Node* next; //singly linked list is sufficient T val; @@ -32,8 +32,8 @@ class FixedList public: FixedList() : - first(NULL), - lastInsert(NULL), + first(nullptr), + lastInsert(nullptr), sz(0) {} ~FixedList() @@ -51,7 +51,7 @@ public: class ListIterator : public std::iterator<std::forward_iterator_tag, U> { public: - ListIterator(NodeT* it = NULL) : iter(it) {} + ListIterator(NodeT* it = nullptr) : iter(it) {} ListIterator& operator++() { iter = iter->next; return *this; } inline friend bool operator==(const ListIterator& lhs, const ListIterator& rhs) { return lhs.iter == rhs.iter; } inline friend bool operator!=(const ListIterator& lhs, const ListIterator& rhs) { return !(lhs == rhs); } @@ -90,7 +90,7 @@ public: template <class Predicate> void remove_if(Predicate pred) { - Node* prev = NULL; + Node* prev = nullptr; Node* ptr = first; while (ptr) @@ -102,7 +102,7 @@ public: prev->next = ptr = tmp; else first = ptr = tmp; - if (tmp == NULL) + if (!tmp) lastInsert = prev; } else @@ -113,7 +113,7 @@ public: } void clear() { remove_if([](T&) { return true; }); } - bool empty() const { return first == NULL; } + bool empty() const { return first == nullptr; } size_t size() const { return sz; } private: @@ -123,14 +123,14 @@ private: void pushNode(Node* newNode) { ++sz; - if (lastInsert == NULL) + if (lastInsert == nullptr) { - assert(first == NULL); + assert(first == nullptr); first = lastInsert = newNode; } else { - assert(lastInsert->next == NULL); + assert(lastInsert->next == nullptr); lastInsert->next = newNode; lastInsert = newNode; } @@ -33,7 +33,7 @@ struct TranslationHandler virtual std::wstring translate(const std::wstring& singular, const std::wstring& plural, int n) = 0; }; -void setTranslator(TranslationHandler* newHandler = NULL); //takes ownership +void setTranslator(TranslationHandler* newHandler = nullptr); //takes ownership TranslationHandler* getTranslator(); std::wstring getThousandsSeparator(); diff --git a/zen/int64.h b/zen/int64.h index a5140ffd..ea51b23b 100644 --- a/zen/int64.h +++ b/zen/int64.h @@ -49,13 +49,15 @@ class Int64 { public: //safe implicit conversions - Int64() : value(0) {} - Int64(const Int64& rhs) : value(rhs.value) {} - template <class T> - Int64(T rhs, typename EnableIf<IsSignedInt<T>::result && sizeof(T) <= sizeof(std::int64_t)>::Result* = NULL) : value(static_cast<std::int64_t>(rhs)) {} + Int64() : value(0) {} + Int64(const Int64& rhs) : value(rhs.value) {} + template <class T> + Int64(T rhs, typename EnableIf<IsSignedInt<T>::value && sizeof(T) <= sizeof(std::int64_t)>::Type* = nullptr) : + value(static_cast<std::int64_t>(rhs)) {} //unsafe explicit but checked conversion for all other integer types - template <class T> explicit Int64(T rhs, typename EnableIf<!(IsSignedInt<T>::result && sizeof(T) <= sizeof(std::int64_t))>::Result* = NULL) : value(static_cast<std::int64_t>(rhs)) { checkRange<std::int64_t>(rhs); } + template <class T> explicit Int64(T rhs, typename EnableIf<!(IsSignedInt<T>::value && sizeof(T) <= sizeof(std::int64_t))>::Type* = nullptr) : + value(static_cast<std::int64_t>(rhs)) { checkRange<std::int64_t>(rhs); } Int64& operator=(const Int64& rhs) { value = rhs.value; return *this; } @@ -126,13 +128,15 @@ class UInt64 { public: //safe implicit conversions - UInt64() : value(0) {} - UInt64(const UInt64& rhs) : value(rhs.value) {} - template <class T> - UInt64(T rhs, typename EnableIf<IsUnsignedInt<T>::result && sizeof(T) <= sizeof(std::uint64_t)>::Result* = NULL) : value(static_cast<std::uint64_t>(rhs)) {} + UInt64() : value(0) {} + UInt64(const UInt64& rhs) : value(rhs.value) {} + template <class T> + UInt64(T rhs, typename EnableIf<IsUnsignedInt<T>::value && sizeof(T) <= sizeof(std::uint64_t)>::Type* = nullptr) : + value(static_cast<std::uint64_t>(rhs)) {} //unsafe explicit but checked conversion for all other integer types - template <class T> explicit UInt64(T rhs, typename EnableIf<!(IsUnsignedInt<T>::result && sizeof(T) <= sizeof(std::uint64_t))>::Result* = NULL) : value(static_cast<std::uint64_t>(rhs)) { checkRange<std::uint64_t>(rhs); } + template <class T> explicit UInt64(T rhs, typename EnableIf<!(IsUnsignedInt<T>::value && sizeof(T) <= sizeof(std::uint64_t))>::Type* = nullptr) : + value(static_cast<std::uint64_t>(rhs)) { checkRange<std::uint64_t>(rhs); } UInt64& operator=(const UInt64& rhs) { value = rhs.value; return *this; } @@ -248,8 +252,8 @@ public: //specialize zen type trait namespace zen -> we cannot mix signed/unsigned in general arithmetic operations -> we'll use the ostream-approach { -template <> struct IsUnsignedInt<UInt64> { enum { result = true }; }; -template <> struct IsSignedInt <Int64> { enum { result = true }; }; +template <> struct IsUnsignedInt<UInt64> : StaticBool<true> {}; +template <> struct IsSignedInt <Int64> : StaticBool<true> {}; } */ #endif //FFS_LARGE_64_BIT_INTEGER_H_INCLUDED diff --git a/zen/last_error.h b/zen/last_error.h index 6f701992..28982b63 100644 --- a/zen/last_error.h +++ b/zen/last_error.h @@ -20,16 +20,25 @@ #endif - namespace zen { //evaluate GetLastError()/errno and assemble specific error message #ifdef FFS_WIN -std::wstring getLastErrorFormatted(DWORD lastError = 0); +typedef DWORD ErrorCode; #elif defined FFS_LINUX -std::wstring getLastErrorFormatted(int lastError = 0); +typedef int ErrorCode; #endif +std::wstring getLastErrorFormatted(ErrorCode lastError = 0); +ErrorCode getLastError(); + +bool errorCodeForNotExisting(ErrorCode lastError); //check for "not existing" aliases + + + + + + @@ -56,24 +65,37 @@ std::wstring getLastErrorFormatted(int lastError = 0); -//######################## Implementation ######################## + + + +//######################## implementation ######################## +inline +ErrorCode getLastError() +{ #ifdef FFS_WIN + return ::GetLastError(); +#elif defined FFS_LINUX + return errno; +#endif +} + inline -std::wstring getLastErrorFormatted(DWORD lastError) //try to get additional Windows error information +std::wstring getLastErrorFormatted(ErrorCode lastError) { +#ifdef FFS_WIN //determine error code if none was specified if (lastError == 0) lastError = ::GetLastError(); std::wstring output = _("Windows Error Code %x:"); - replace(output, L"%x", toString<std::wstring>(lastError)); + replace(output, L"%x", numberTo<std::wstring>(lastError)); - LPWSTR buffer = NULL; + LPWSTR buffer = nullptr; if (::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK | FORMAT_MESSAGE_IGNORE_INSERTS | //important: without this flag ::FormatMessage() will fail if message contains placeholders - FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, lastError, 0, reinterpret_cast<LPWSTR>(&buffer), 0, NULL) != 0) + FORMAT_MESSAGE_ALLOCATE_BUFFER, nullptr, lastError, 0, reinterpret_cast<LPWSTR>(&buffer), 0, nullptr) != 0) { if (buffer) //just to be sure { @@ -84,27 +106,37 @@ std::wstring getLastErrorFormatted(DWORD lastError) //try to get additional Wind } ::SetLastError(lastError); //restore last error return output; -} #elif defined FFS_LINUX -inline -std::wstring getLastErrorFormatted(int lastError) //try to get additional Linux error information -{ //determine error code if none was specified if (lastError == 0) lastError = errno; //don't use "::", errno is a macro! std::wstring output = _("Linux Error Code %x:"); - replace(output, L"%x", toString<std::wstring>(lastError)); + replace(output, L"%x", numberTo<std::wstring>(lastError)); output += L" "; output += utf8CvrtTo<std::wstring>(::strerror(lastError)); errno = lastError; //restore errno return output; -} #endif } +inline +bool errorCodeForNotExisting(ErrorCode lastError) +{ +#ifdef FFS_WIN + return lastError == ERROR_FILE_NOT_FOUND || + lastError == ERROR_PATH_NOT_FOUND || + lastError == ERROR_BAD_NETPATH || + lastError == ERROR_NETNAME_DELETED; + +#elif defined FFS_LINUX + return lastError == ENOENT; +#endif +} +} + #endif // SYSTEMFUNCTIONS_H_INCLUDED diff --git a/zen/long_path_prefix.h b/zen/long_path_prefix.h index d6255b85..83643906 100644 --- a/zen/long_path_prefix.h +++ b/zen/long_path_prefix.h @@ -55,7 +55,7 @@ template <size_t max_path> inline Zstring applyLongPathPrefixImpl(const Zstring& path) { assert(!path.empty()); //nicely check almost all WinAPI accesses! - assert(!zen::cStringIsWhiteSpace(path[0])); + assert(!zen::isWhiteSpace(path[0])); if (path.length() >= max_path && //maximum allowed path length without prefix is (MAX_PATH - 1) !zen::startsWith(path, LONG_PATH_PREFIX)) diff --git a/zen/notify_removal.cpp b/zen/notify_removal.cpp index 661822cb..d8657ea2 100644 --- a/zen/notify_removal.cpp +++ b/zen/notify_removal.cpp @@ -91,10 +91,10 @@ LRESULT CALLBACK topWndProc(HWND hwnd, //handle to window MessageProvider::MessageProvider() : - process(::GetModuleHandle(NULL)), //get program's module handle - windowHandle(NULL) + process(::GetModuleHandle(nullptr)), //get program's module handle + windowHandle(nullptr) { - if (process == NULL) + if (!process) throw zen::FileError(std::wstring(L"Could not start monitoring window notifications:") + L"\n\n" + getLastErrorFormatted() + L" (GetModuleHandle)"); //register the main window class @@ -110,17 +110,17 @@ MessageProvider::MessageProvider() : //create dummy-window windowHandle = ::CreateWindow(WINDOW_NAME, //LPCTSTR lpClassName OR ATOM in low-order word! - NULL, //LPCTSTR lpWindowName, + nullptr, //LPCTSTR lpWindowName, 0, //DWORD dwStyle, 0, //int x, 0, //int y, 0, //int nWidth, 0, //int nHeight, 0, //note: we need a toplevel window to receive device arrival events, not a message-window (HWND_MESSAGE)! - NULL, //HMENU hMenu, - process, //HINSTANCE hInstance, - NULL); //LPVOID lpParam - if (windowHandle == NULL) + nullptr, //HMENU hMenu, + process, //HINSTANCE hInstance, + nullptr); //LPVOID lpParam + if (!windowHandle) throw zen::FileError(std::wstring(L"Could not start monitoring window notifications:") + L"\n\n" + getLastErrorFormatted() + L" (CreateWindow)"); guardClass.dismiss(); @@ -161,7 +161,7 @@ public: hNotification = ::RegisterDeviceNotification(MessageProvider::instance().getWnd(), //__in HANDLE hRecipient, &filter, //__in LPVOID NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE); //__in DWORD Flags - if (hNotification == NULL) + if (!hNotification) { const DWORD lastError = ::GetLastError(); if (lastError != ERROR_CALL_NOT_IMPLEMENTED && //fail on SAMBA share: this shouldn't be a showstopper! diff --git a/zen/optional.h b/zen/optional.h index 1e04f52c..2bd272ae 100644 --- a/zen/optional.h +++ b/zen/optional.h @@ -34,9 +34,13 @@ template <class T> class Opt { public: - Opt() : valid(false), value() {} - Opt(NoValue) : valid(false), value() {} - Opt(const T& val) : valid(true ), value(val) {} + Opt() : value() , valid(false) {} + Opt(NoValue) : value() , valid(false) {} + Opt(const T& val) : value(val), valid(true ) {} + + //rvalue optimization: only basic exception safety: + Opt(Opt&& tmp) : value(std::move(tmp.value)), valid(tmp.valid) {} + Opt& operator=(const Opt& tmp) { value = std::move(tmp.value); valid = tmp.valid; } #ifdef _MSC_VER private: @@ -52,9 +56,11 @@ public: const T* operator->() const { return &value; } /**/ T* operator->() { return &value; } + + void reset() { valid = false; } private: - const bool valid; T value; + bool valid; }; } @@ -7,14 +7,21 @@ #ifndef DEBUG_PERF_HEADER #define DEBUG_PERF_HEADER -#include <sstream> #include "deprecate.h" + +#ifdef FFS_WIN +#include <sstream> #include "win.h" //includes "windows.h" +#else +#include <iostream> +#include <time.h> +#endif //two macros for quick performance measurements #define PERF_START CpuTimer perfTest; #define PERF_STOP perfTest.showResult(); +#ifdef FFS_WIN class CpuTimer { public: @@ -24,8 +31,10 @@ public: CpuTimer() : frequency(), startTime(), resultShown(false) { SetThreadAffinity dummy; - if (!::QueryPerformanceFrequency(&frequency)) throw TimerError(); - if (!::QueryPerformanceCounter (&startTime)) throw TimerError(); + if (!::QueryPerformanceFrequency(&frequency)) + throw TimerError(); + if (!::QueryPerformanceCounter (&startTime)) + throw TimerError(); } ~CpuTimer() @@ -38,16 +47,18 @@ public: { SetThreadAffinity dummy; LARGE_INTEGER currentTime = {}; - if (!::QueryPerformanceCounter(¤tTime)) throw TimerError(); + if (!::QueryPerformanceCounter(¤tTime)) + throw TimerError(); - const long delta = static_cast<long>(1000.0 * (currentTime.QuadPart - startTime.QuadPart) / frequency.QuadPart); + const auto delta = static_cast<long>(1000.0 * (currentTime.QuadPart - startTime.QuadPart) / frequency.QuadPart); std::ostringstream ss; ss << delta << " ms"; - ::MessageBoxA(NULL, ss.str().c_str(), "Timer", 0); + ::MessageBoxA(nullptr, ss.str().c_str(), "Timer", 0); resultShown = true; - if (!::QueryPerformanceCounter(&startTime)) throw TimerError(); //don't include call to MessageBox()! + if (!::QueryPerformanceCounter(&startTime)) + throw TimerError(); //don't include call to MessageBox()! } private: @@ -57,6 +68,8 @@ private: SetThreadAffinity() : oldmask(::SetThreadAffinityMask(::GetCurrentThread(), 1)) { if (oldmask == 0) throw TimerError(); } ~SetThreadAffinity() { ::SetThreadAffinityMask(::GetCurrentThread(), oldmask); } private: + SetThreadAffinity(const SetThreadAffinity&); + SetThreadAffinity& operator=(const SetThreadAffinity&); const DWORD_PTR oldmask; }; @@ -65,4 +78,46 @@ private: bool resultShown; }; + +#else +class CpuTimer +{ +public: + class TimerError {}; + + ZEN_DEPRECATE + CpuTimer() : startTime(), resultShown(false) + { + //clock() seems to give grossly incorrect results: multi core issue? + //gettimeofday() seems fine but is deprecated + if (::clock_gettime(CLOCK_MONOTONIC_RAW, &startTime) != 0) //CLOCK_MONOTONIC measures time reliably across processors! + throw TimerError(); + } + + ~CpuTimer() + { + if (!resultShown) + showResult(); + } + + void showResult() + { + timespec currentTime = {}; + if (::clock_gettime(CLOCK_MONOTONIC_RAW, ¤tTime) != 0) + throw TimerError(); + + const auto delta = static_cast<long>((currentTime.tv_sec - startTime.tv_sec) * 1000.0 + (currentTime.tv_nsec - startTime.tv_nsec) / 1000000.0); + std::clog << "Perf: duration: " << delta << " ms\n"; + resultShown = true; + + if (::clock_gettime(CLOCK_MONOTONIC_RAW, &startTime) != 0) + throw TimerError(); + } + +private: + timespec startTime; + bool resultShown; +}; +#endif + #endif //DEBUG_PERF_HEADER diff --git a/zen/privilege.cpp b/zen/privilege.cpp index 3b7e9cc5..23a55bd8 100644 --- a/zen/privilege.cpp +++ b/zen/privilege.cpp @@ -11,15 +11,15 @@ namespace { bool privilegeIsActive(LPCTSTR privilege) //throw FileError { - HANDLE hToken = NULL; + HANDLE hToken = nullptr; if (!::OpenProcessToken(::GetCurrentProcess(), //__in HANDLE ProcessHandle, TOKEN_QUERY, //__in DWORD DesiredAccess, &hToken)) //__out PHANDLE TokenHandle throw FileError(_("Error setting privilege:") + L" \"" + privilege + L"\"" + L"\n\n" + getLastErrorFormatted()); - ZEN_ON_BLOCK_EXIT(::CloseHandle(hToken)); + ZEN_ON_SCOPE_EXIT(::CloseHandle(hToken)); LUID luid = {}; - if (!::LookupPrivilegeValue(NULL, //__in_opt LPCTSTR lpSystemName, + if (!::LookupPrivilegeValue(nullptr, //__in_opt LPCTSTR lpSystemName, privilege, //__in LPCTSTR lpName, &luid )) //__out PLUID lpLuid throw FileError(_("Error setting privilege:") + L" \"" + privilege + L"\"" + L"\n\n" + getLastErrorFormatted()); @@ -42,15 +42,15 @@ bool privilegeIsActive(LPCTSTR privilege) //throw FileError void setPrivilege(LPCTSTR privilege, bool enable) //throw FileError { - HANDLE hToken = NULL; + HANDLE hToken = nullptr; if (!::OpenProcessToken(::GetCurrentProcess(), //__in HANDLE ProcessHandle, TOKEN_ADJUST_PRIVILEGES, //__in DWORD DesiredAccess, &hToken)) //__out PHANDLE TokenHandle throw FileError(_("Error setting privilege:") + L" \"" + privilege + L"\"" + L"\n\n" + getLastErrorFormatted()); - ZEN_ON_BLOCK_EXIT(::CloseHandle(hToken)); + ZEN_ON_SCOPE_EXIT(::CloseHandle(hToken)); LUID luid = {}; - if (!::LookupPrivilegeValue(NULL, //__in_opt LPCTSTR lpSystemName, + if (!::LookupPrivilegeValue(nullptr, //__in_opt LPCTSTR lpSystemName, privilege, //__in LPCTSTR lpName, &luid )) //__out PLUID lpLuid throw FileError(_("Error setting privilege:") + L" \"" + privilege + L"\"" + L"\n\n" + getLastErrorFormatted()); @@ -60,12 +60,12 @@ void setPrivilege(LPCTSTR privilege, bool enable) //throw FileError tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0; - if (!::AdjustTokenPrivileges(hToken, //__in HANDLE TokenHandle, - false, //__in BOOL DisableAllPrivileges, - &tp, //__in_opt PTOKEN_PRIVILEGES NewState, - 0, //__in DWORD BufferLength, - NULL, //__out_opt PTOKEN_PRIVILEGES PreviousState, - NULL)) //__out_opt PDWORD ReturnLength + if (!::AdjustTokenPrivileges(hToken, //__in HANDLE TokenHandle, + false, //__in BOOL DisableAllPrivileges, + &tp, //__in_opt PTOKEN_PRIVILEGES NewState, + 0, //__in DWORD BufferLength, + nullptr, //__out_opt PTOKEN_PRIVILEGES PreviousState, + nullptr)) //__out_opt PDWORD ReturnLength throw FileError(_("Error setting privilege:") + L" \"" + privilege + L"\"" + L"\n\n" + getLastErrorFormatted()); if (::GetLastError() == ERROR_NOT_ALL_ASSIGNED) //check although previous function returned with success! diff --git a/zen/privilege.h b/zen/privilege.h index 97d0d201..b940279a 100644 --- a/zen/privilege.h +++ b/zen/privilege.h @@ -15,5 +15,4 @@ namespace zen void activatePrivilege(LPCTSTR privilege); //throw FileError; thread-safe!!! } - #endif // PRIVILEGE_H_INCLUDED diff --git a/zen/scope_guard.h b/zen/scope_guard.h index cc2f31e6..86d22c91 100644 --- a/zen/scope_guard.h +++ b/zen/scope_guard.h @@ -8,6 +8,8 @@ #ifndef ZEN_SCOPEGUARD_8971632487321434 #define ZEN_SCOPEGUARD_8971632487321434 +#include <cassert> + //best of Zen, Loki and C++11 namespace zen @@ -21,7 +23,7 @@ namespace zen //Scope Exit /* - ZEN_ON_BLOCK_EXIT(::CloseHandle(hDir)); + ZEN_ON_SCOPE_EXIT(::CloseHandle(hDir)); */ class ScopeGuardBase @@ -56,7 +58,7 @@ public: { fun_(); } - catch (...) {} + catch (...) { assert(false); } } private: @@ -72,6 +74,6 @@ ScopeGuardImpl<F> makeGuard(F fun) { return ScopeGuardImpl<F>(fun); } #define ZEN_CONCAT_SUB(X, Y) X ## Y #define ZEN_CONCAT(X, Y) ZEN_CONCAT_SUB(X, Y) -#define ZEN_ON_BLOCK_EXIT(X) zen::ScopeGuard ZEN_CONCAT(dummy, __LINE__) = zen::makeGuard([&](){X;}); (void)ZEN_CONCAT(dummy, __LINE__); +#define ZEN_ON_SCOPE_EXIT(X) zen::ScopeGuard ZEN_CONCAT(dummy, __LINE__) = zen::makeGuard([&]{ X; }); (void)ZEN_CONCAT(dummy, __LINE__); #endif //ZEN_SCOPEGUARD_8971632487321434 diff --git a/zen/stl_tools.h b/zen/stl_tools.h index 03a10f96..e9fe149a 100644 --- a/zen/stl_tools.h +++ b/zen/stl_tools.h @@ -9,6 +9,7 @@ #define STL_TOOLS_HEADER_84567184321434 #include <memory> +#include <algorithm> #if defined _MSC_VER && _MSC_VER <= 1600 #include <set> #include <map> @@ -111,17 +112,14 @@ ForwardIterator binary_search(ForwardIterator first, ForwardIterator last, const template <class BidirectionalIterator, class T> inline BidirectionalIterator find_last(const BidirectionalIterator first, BidirectionalIterator last, const T& value) { - //reverse iteration: 1. check 2. decrement 3. evaluate - const BidirectionalIterator iterNotFound = last; - for (;;) //VS 2010 doesn't like "while (true)" + for (BidirectionalIterator iter = last; iter != first;) //reverse iteration: 1. check 2. decrement 3. evaluate { - if (last == first) - return iterNotFound; - --last; + --iter; // - if (*last == value) - return last; + if (*iter == value) + return iter; } + return last; } diff --git a/zen/string_base.h b/zen/string_base.h index ef0d9059..82793a49 100644 --- a/zen/string_base.h +++ b/zen/string_base.h @@ -118,11 +118,7 @@ class StorageRefCountThreadSafe : public AP protected: ~StorageRefCountThreadSafe() {} - static Char* create(size_t size) - { - return create(size, size); - } - + static Char* create(size_t size) { return create(size, size); } static Char* create(size_t size, size_t minCapacity) { const size_t newCapacity = AP::calcCapacity(minCapacity); @@ -157,23 +153,24 @@ protected: return descr(ptr)->refCount == 1 && minCapacity <= descr(ptr)->capacity; } - static size_t length(const Char* ptr) - { - return descr(ptr)->length; - } + static size_t length(const Char* ptr) { return descr(ptr)->length; } static void setLength(Char* ptr, size_t newLength) { assert(canWrite(ptr, newLength)); - descr(ptr)->length = newLength; + descr(ptr)->length = static_cast<std::uint32_t>(newLength); } private: struct Descriptor { - Descriptor(long rc, size_t len, size_t cap) : refCount(rc), length(len), capacity(cap) {} + Descriptor(long rc, size_t len, size_t cap) : + refCount(rc), + length(static_cast<std::uint32_t>(len)), + capacity(static_cast<std::uint32_t>(cap)) {} boost::detail::atomic_count refCount; //practically no perf loss: ~0.2%! (FFS comparison) + //replace by #include <atomic> std::atomic_int when finally getting rid of VS2010 std::uint32_t length; std::uint32_t capacity; //allocated size without null-termination }; @@ -197,7 +194,7 @@ public: Zbase(const Char* source, size_t length); Zbase(const Zbase& source); Zbase(Zbase&& tmp); - explicit Zbase(Char source); //dangerous if implicit: Char buffer[]; Zbase name = buffer; ups... + explicit Zbase(Char source); //dangerous if implicit: Char buffer[]; return buffer[0]; ups... //allow explicit construction from different string type, prevent ambiguity via SFINAE template <class S> explicit Zbase(const S& other, typename S::value_type = 0); ~Zbase(); @@ -217,15 +214,15 @@ public: //std::string functions size_t length() const; - size_t size() const; - const Char* c_str() const; //C-string format with NULL-termination - const Char* data() const; //internal representation, NULL-termination not guaranteed + size_t size () const { return length(); } + const Char* c_str() const { return rawStr; }; //C-string format with 0-termination + const Char* data() const { return rawStr; }; //internal representation, 0-termination not guaranteed const Char operator[](size_t pos) const; - bool empty() const; + bool empty() const { return length() == 0; } void clear(); size_t find (const Zbase& str, size_t pos = 0) const; // - size_t find (const Char* str, size_t pos = 0) const; //returns "npos" if not found - size_t find (Char ch, size_t pos = 0) const; // + size_t find (const Char* str, size_t pos = 0) const; // + size_t find (Char ch, size_t pos = 0) const; //returns "npos" if not found size_t rfind(Char ch, size_t pos = npos) const; // size_t rfind(const Char* str, size_t pos = npos) const; // Zbase& replace(size_t pos1, size_t n1, const Zbase& str); @@ -234,7 +231,7 @@ public: Zbase& append(const Char* source, size_t len); void resize(size_t newSize, Char fillChar = 0); void swap(Zbase& other); - void push_back(Char val); //STL access + void push_back(Char val) { operator+=(val); } //STL access Zbase& operator=(Zbase source); Zbase& operator=(const Char* source); @@ -254,27 +251,24 @@ private: Char* rawStr; }; -template <class Char, template <class, class> class SP, class AP> bool operator==(const Zbase<Char, SP, AP>& lhs, const Zbase<Char, SP, AP>& rhs); -template <class Char, template <class, class> class SP, class AP> bool operator==(const Zbase<Char, SP, AP>& lhs, const Char* rhs); -template <class Char, template <class, class> class SP, class AP> bool operator==(const Char* lhs, const Zbase<Char, SP, AP>& rhs); - -template <class Char, template <class, class> class SP, class AP> bool operator!=(const Zbase<Char, SP, AP>& lhs, const Zbase<Char, SP, AP>& rhs); -template <class Char, template <class, class> class SP, class AP> bool operator!=(const Zbase<Char, SP, AP>& lhs, const Char* rhs); -template <class Char, template <class, class> class SP, class AP> bool operator!=(const Char* lhs, const Zbase<Char, SP, AP>& rhs); - -template <class Char, template <class, class> class SP, class AP> bool operator< (const Zbase<Char, SP, AP>& lhs, const Zbase<Char, SP, AP>& rhs); -template <class Char, template <class, class> class SP, class AP> bool operator< (const Zbase<Char, SP, AP>& lhs, const Char* rhs); -template <class Char, template <class, class> class SP, class AP> bool operator< (const Char* lhs, const Zbase<Char, SP, AP>& rhs); - -template <class Char, template <class, class> class SP, class AP> const Zbase<Char, SP, AP> operator+(const Zbase<Char, SP, AP>& lhs, const Zbase<Char, SP, AP>& rhs); -template <class Char, template <class, class> class SP, class AP> const Zbase<Char, SP, AP> operator+(const Zbase<Char, SP, AP>& lhs, const Char* rhs); -template <class Char, template <class, class> class SP, class AP> const Zbase<Char, SP, AP> operator+(const Char* lhs, const Zbase<Char, SP, AP>& rhs); -template <class Char, template <class, class> class SP, class AP> const Zbase<Char, SP, AP> operator+( Char lhs, const Zbase<Char, SP, AP>& rhs); -template <class Char, template <class, class> class SP, class AP> const Zbase<Char, SP, AP> operator+(const Zbase<Char, SP, AP>& lhs, Char rhs); - +template <class Char, template <class, class> class SP, class AP> bool operator==(const Zbase<Char, SP, AP>& lhs, const Zbase<Char, SP, AP>& rhs); +template <class Char, template <class, class> class SP, class AP> bool operator==(const Zbase<Char, SP, AP>& lhs, const Char* rhs); +template <class Char, template <class, class> class SP, class AP> inline bool operator==(const Char* lhs, const Zbase<Char, SP, AP>& rhs) { return operator==(rhs, lhs); } +template <class Char, template <class, class> class SP, class AP> inline bool operator!=(const Zbase<Char, SP, AP>& lhs, const Zbase<Char, SP, AP>& rhs) { return !operator==(lhs, rhs); } +template <class Char, template <class, class> class SP, class AP> inline bool operator!=(const Zbase<Char, SP, AP>& lhs, const Char* rhs) { return !operator==(lhs, rhs); } +template <class Char, template <class, class> class SP, class AP> inline bool operator!=(const Char* lhs, const Zbase<Char, SP, AP>& rhs) { return !operator==(lhs, rhs); } +template <class Char, template <class, class> class SP, class AP> bool operator<(const Zbase<Char, SP, AP>& lhs, const Zbase<Char, SP, AP>& rhs); +template <class Char, template <class, class> class SP, class AP> bool operator<(const Zbase<Char, SP, AP>& lhs, const Char* rhs); +template <class Char, template <class, class> class SP, class AP> bool operator<(const Char* lhs, const Zbase<Char, SP, AP>& rhs); +//rvalue references: unified first argument! +template <class Char, template <class, class> class SP, class AP> inline Zbase<Char, SP, AP> operator+(Zbase<Char, SP, AP> lhs, const Zbase<Char, SP, AP>& rhs) { return lhs += rhs; } +template <class Char, template <class, class> class SP, class AP> inline Zbase<Char, SP, AP> operator+(Zbase<Char, SP, AP> lhs, const Char* rhs) { return lhs += rhs; } +template <class Char, template <class, class> class SP, class AP> inline Zbase<Char, SP, AP> operator+(Zbase<Char, SP, AP> lhs, Char rhs) { return lhs += rhs; } +template <class Char, template <class, class> class SP, class AP> inline Zbase<Char, SP, AP> operator+( Char lhs, const Zbase<Char, SP, AP>& rhs) { return Zbase<Char, SP, AP>(lhs) += rhs; } +template <class Char, template <class, class> class SP, class AP> inline Zbase<Char, SP, AP> operator+(const Char* lhs, const Zbase<Char, SP, AP>& rhs) { return Zbase<Char, SP, AP>(lhs) += rhs; } @@ -302,13 +296,7 @@ template <class Char, template <class, class> class SP, class AP> const Zbase<Ch - - - - - - -//################################# inline implementation ######################################## +//################################# implementation ######################################## template <class Char, template <class, class> class SP, class AP> inline Zbase<Char, SP, AP>::Zbase() { @@ -355,7 +343,16 @@ Zbase<Char, SP, AP>::Zbase(const Zbase<Char, SP, AP>& source) template <class Char, template <class, class> class SP, class AP> inline Zbase<Char, SP, AP>::Zbase(Zbase<Char, SP, AP>&& tmp) { - rawStr = this->clone(tmp.rawStr); //for a ref-counting string there probably isn't a faster way, even with r-value references + //rawStr = this->clone(tmp.rawStr); NO! do not increment ref-count of a potentially unshared string! We'd lose optimization opportunity of reusing it! + //instead create a dummy string and swap: + if (canWrite(tmp.rawStr, 0)) //perf: this check saves about 4% + { + rawStr = this->create(0); //no perf issue! see comment in default constructor + rawStr[0] = 0; + swap(tmp); + } + else //shared representation: yet another "add ref" won't hurt + rawStr = this->clone(tmp.rawStr); } @@ -524,34 +521,6 @@ bool operator==(const Zbase<Char, SP, AP>& lhs, const Char* rhs) template <class Char, template <class, class> class SP, class AP> inline -bool operator==(const Char* lhs, const Zbase<Char, SP, AP>& rhs) -{ - return operator==(rhs, lhs); -} - - -template <class Char, template <class, class> class SP, class AP> inline -bool operator!=(const Zbase<Char, SP, AP>& lhs, const Zbase<Char, SP, AP>& rhs) -{ - return !operator==(lhs, rhs); -} - - -template <class Char, template <class, class> class SP, class AP> inline -bool operator!=(const Zbase<Char, SP, AP>& lhs, const Char* rhs) -{ - return !operator==(lhs, rhs); -} - - -template <class Char, template <class, class> class SP, class AP> inline -bool operator!=(const Char* lhs, const Zbase<Char, SP, AP>& rhs) -{ - return !operator==(lhs, rhs); -} - - -template <class Char, template <class, class> class SP, class AP> inline bool operator<(const Zbase<Char, SP, AP>& lhs, const Zbase<Char, SP, AP>& rhs) { return std::lexicographical_compare(lhs.begin(), lhs.end(), //respect embedded 0 @@ -583,27 +552,6 @@ size_t Zbase<Char, SP, AP>::length() const template <class Char, template <class, class> class SP, class AP> inline -size_t Zbase<Char, SP, AP>::size() const -{ - return length(); -} - - -template <class Char, template <class, class> class SP, class AP> inline -const Char* Zbase<Char, SP, AP>::c_str() const -{ - return rawStr; -} - - -template <class Char, template <class, class> class SP, class AP> inline -const Char* Zbase<Char, SP, AP>::data() const -{ - return rawStr; -} - - -template <class Char, template <class, class> class SP, class AP> inline const Char Zbase<Char, SP, AP>::operator[](size_t pos) const { assert(pos < length()); @@ -641,20 +589,6 @@ Char* Zbase<Char, SP, AP>::end() template <class Char, template <class, class> class SP, class AP> inline -void Zbase<Char, SP, AP>::push_back(Char val) -{ - operator+=(val); -} - - -template <class Char, template <class, class> class SP, class AP> inline -bool Zbase<Char, SP, AP>::empty() const -{ - return length() == 0; -} - - -template <class Char, template <class, class> class SP, class AP> inline void Zbase<Char, SP, AP>::clear() { if (!empty()) @@ -671,41 +605,6 @@ void Zbase<Char, SP, AP>::clear() template <class Char, template <class, class> class SP, class AP> inline -const Zbase<Char, SP, AP> operator+(const Zbase<Char, SP, AP>& lhs, const Zbase<Char, SP, AP>& rhs) -{ - return Zbase<Char, SP, AP>(lhs) += rhs; -} - - -template <class Char, template <class, class> class SP, class AP> inline -const Zbase<Char, SP, AP> operator+(const Zbase<Char, SP, AP>& lhs, const Char* rhs) -{ - return Zbase<Char, SP, AP>(lhs) += rhs; -} - - -template <class Char, template <class, class> class SP, class AP> inline -const Zbase<Char, SP, AP> operator+(const Char* lhs, const Zbase<Char, SP, AP>& rhs) -{ - return Zbase<Char, SP, AP>(lhs) += rhs; -} - - -template <class Char, template <class, class> class SP, class AP> inline -const Zbase<Char, SP, AP> operator+(Char lhs, const Zbase<Char, SP, AP>& rhs) -{ - return Zbase<Char, SP, AP>(lhs) += rhs; -} - - -template <class Char, template <class, class> class SP, class AP> inline -const Zbase<Char, SP, AP> operator+(const Zbase<Char, SP, AP>& lhs, Char rhs) -{ - return Zbase<Char, SP, AP>(lhs) += rhs; -} - - -template <class Char, template <class, class> class SP, class AP> inline void Zbase<Char, SP, AP>::swap(Zbase<Char, SP, AP>& other) { std::swap(rawStr, other.rawStr); @@ -719,7 +618,7 @@ void Zbase<Char, SP, AP>::reserve(size_t minCapacity) //make unshared and check { //allocate a new string Char* newStr = create(length(), std::max(minCapacity, length())); //reserve() must NEVER shrink the string: logical const! - std::copy(rawStr, rawStr + length() + 1, newStr); //include NULL-termination + std::copy(rawStr, rawStr + length() + 1, newStr); //include 0-termination destroy(rawStr); rawStr = newStr; diff --git a/zen/string_tools.h b/zen/string_tools.h index 602c4258..85eef5df 100644 --- a/zen/string_tools.h +++ b/zen/string_tools.h @@ -23,9 +23,8 @@ //enhance arbitray string class with useful non-member functions: namespace zen { -template <class Char> bool cStringIsWhiteSpace(Char ch); -template <class Char> bool cStringIsDigit (Char ch); //not exactly the same as "std::isdigit" -> we consider '0'-'9' only! - +template <class Char> bool isWhiteSpace(Char ch); +template <class Char> bool isDigit (Char ch); //not exactly the same as "std::isdigit" -> we consider '0'-'9' only! template <class S, class T> bool startsWith(const S& str, const T& prefix); //both S and T can be strings or char/wchar_t arrays or simple char/wchar_t template <class S, class T> bool endsWith (const S& str, const T& postfix); // @@ -36,7 +35,6 @@ template <class S, class T> S afterFirst (const S& str, const T& ch); //returns template <class S, class T> S beforeFirst(const S& str, const T& ch); //returns the whole string if ch not found template <class S, class T> std::vector<S> split(const S& str, const T& delimiter); -template <class S> void truncate(S& str, size_t newLen); template <class S> void trim(S& str, bool fromLeft = true, bool fromRight = true); template <class S, class T, class U> void replace ( S& str, const T& oldOne, const U& newOne, bool replaceAll = true); template <class S, class T, class U> S replaceCpy(const S& str, const T& oldOne, const U& newOne, bool replaceAll = true); @@ -44,8 +42,8 @@ template <class S, class T, class U> S replaceCpy(const S& str, const T& oldO //high-performance conversion between numbers and strings template <class S, class T, class Num> S printNumber(const T& format, const Num& number); //format a single number using std::snprintf() -template <class S, class Num> S toString(const Num& number); -template <class Num, class S > Num toNumber(const S& str); +template <class S, class Num> S numberTo(const Num& number); +template <class Num, class S > Num stringTo(const S& str); //string to string conversion: converts string-like type into char-compatible target string class template <class T, class S> T copyStringTo(const S& str); @@ -83,7 +81,7 @@ template <class T, class S> T copyStringTo(const S& str); //---------------------- implementation ---------------------- template <> inline -bool cStringIsWhiteSpace(char ch) +bool isWhiteSpace(char ch) { //caveat 1: std::isspace() takes an int, but expects an unsigned char //caveat 2: some parts of UTF-8 chars are erroneously seen as whitespace, e.g. the a0 from "\xec\x8b\xa0" (MSVC) @@ -91,13 +89,13 @@ bool cStringIsWhiteSpace(char ch) std::isspace(static_cast<unsigned char>(ch)) != 0; } -template <> inline bool cStringIsWhiteSpace(wchar_t ch) { return std::iswspace(ch) != 0; } +template <> inline bool isWhiteSpace(wchar_t ch) { return std::iswspace(ch) != 0; } template <class Char> inline -bool cStringIsDigit(Char ch) //similar to implmenetation of std::::isdigit()! +bool isDigit(Char ch) //similar to implmenetation of std::::isdigit()! { - assert_static((IsSameType<Char, char>::result || IsSameType<Char, wchar_t>::result)); + assert_static((IsSameType<Char, char>::value || IsSameType<Char, wchar_t>::value)); return static_cast<Char>('0') <= ch && ch <= static_cast<Char>('9'); } @@ -105,9 +103,8 @@ bool cStringIsDigit(Char ch) //similar to implmenetation of std::::isdigit()! template <class S, class T> inline bool startsWith(const S& str, const T& prefix) { - assert_static(IsStringLike<S>::result); - assert_static(IsStringLike<T>::result); - typedef typename GetCharType<S>::Result CharType; + assert_static(IsStringLike<S>::value && IsStringLike<T>::value); + typedef typename GetCharType<S>::Type CharType; const size_t pfLength = strLength(prefix); if (strLength(str) < pfLength) @@ -122,9 +119,8 @@ bool startsWith(const S& str, const T& prefix) template <class S, class T> inline bool endsWith(const S& str, const T& postfix) { - assert_static(IsStringLike<S>::result); - assert_static(IsStringLike<T>::result); - typedef typename GetCharType<S>::Result CharType; + assert_static(IsStringLike<S>::value && IsStringLike<T>::value); + typedef typename GetCharType<S>::Type CharType; const size_t strLen = strLength(str); const size_t pfLen = strLength(postfix); @@ -141,8 +137,8 @@ bool endsWith(const S& str, const T& postfix) template <class S, class T> inline S afterLast(const S& str, const T& ch) { - assert_static(IsStringLike<T>::result); - typedef typename GetCharType<S>::Result CharType; + assert_static(IsStringLike<T>::value); + typedef typename GetCharType<S>::Type CharType; const size_t chLen = strLength(ch); @@ -164,8 +160,8 @@ S afterLast(const S& str, const T& ch) template <class S, class T> inline S beforeLast(const S& str, const T& ch) { - assert_static(IsStringLike<T>::result); - typedef typename GetCharType<S>::Result CharType; + assert_static(IsStringLike<T>::value); + typedef typename GetCharType<S>::Type CharType; const CharType* const strFirst = strBegin(str); const CharType* const strLast = strFirst + strLength(str); @@ -184,8 +180,8 @@ S beforeLast(const S& str, const T& ch) template <class S, class T> inline S afterFirst(const S& str, const T& ch) { - assert_static(IsStringLike<T>::result); - typedef typename GetCharType<S>::Result CharType; + assert_static(IsStringLike<T>::value); + typedef typename GetCharType<S>::Type CharType; const size_t chLen = strLength(ch); const CharType* const strFirst = strBegin(str); @@ -206,8 +202,8 @@ S afterFirst(const S& str, const T& ch) template <class S, class T> inline S beforeFirst(const S& str, const T& ch) { - assert_static(IsStringLike<T>::result); - typedef typename GetCharType<S>::Result CharType; + assert_static(IsStringLike<T>::value); + typedef typename GetCharType<S>::Type CharType; const CharType* const strFirst = strBegin(str); const CharType* const chFirst = strBegin(ch); @@ -220,8 +216,8 @@ S beforeFirst(const S& str, const T& ch) template <class S, class T> inline std::vector<S> split(const S& str, const T& delimiter) { - assert_static(IsStringLike<T>::result); - typedef typename GetCharType<S>::Result CharType; + assert_static(IsStringLike<T>::value); + typedef typename GetCharType<S>::Type CharType; std::vector<S> output; @@ -252,34 +248,25 @@ std::vector<S> split(const S& str, const T& delimiter) } -template <class S> inline -void truncate(S& str, size_t newLen) -{ - if (newLen < str.length()) - str.resize(newLen); -} - - namespace implementation { ZEN_INIT_DETECT_MEMBER(append); //either call operator+=(S(str, len)) or append(str, len) template <class S, class Char> inline -typename EnableIf<HasMember_append<S>::result>::Result stringAppend(S& str, const Char* other, size_t len) { str.append(other, len); } +typename EnableIf<HasMember_append<S>::value>::Type stringAppend(S& str, const Char* other, size_t len) { str.append(other, len); } template <class S, class Char> inline -typename EnableIf<!HasMember_append<S>::result>::Result stringAppend(S& str, const Char* other, size_t len) { str += S(other, len); } +typename EnableIf<!HasMember_append<S>::value>::Type stringAppend(S& str, const Char* other, size_t len) { str += S(other, len); } } template <class S, class T, class U> inline S replaceCpy(const S& str, const T& oldOne, const U& newOne, bool replaceAll) { - assert_static(IsStringLike<T>::result); - assert_static(IsStringLike<U>::result); + assert_static(IsStringLike<T>::value && IsStringLike<U>::value); - typedef typename GetCharType<S>::Result CharType; + typedef typename GetCharType<S>::Type CharType; const size_t oldLen = strLength(oldOne); const size_t newLen = strLength(newOne); @@ -324,29 +311,24 @@ template <class S> inline void trim(S& str, bool fromLeft, bool fromRight) { assert(fromLeft || fromRight); - - typedef typename GetCharType<S>::Result CharType; //don't use value_type! (wxString, Glib::ustring) + typedef typename GetCharType<S>::Type CharType; //don't use value_type! (wxString, Glib::ustring) const CharType* const oldBegin = str.c_str(); const CharType* newBegin = oldBegin; const CharType* newEnd = oldBegin + str.length(); if (fromRight) - while (newBegin != newEnd && cStringIsWhiteSpace(newEnd[-1])) + while (newBegin != newEnd && isWhiteSpace(newEnd[-1])) --newEnd; if (fromLeft) - while (newBegin != newEnd && cStringIsWhiteSpace(*newBegin)) + while (newBegin != newEnd && isWhiteSpace(*newBegin)) ++newBegin; - const size_t newLength = newEnd - newBegin; - if (newLength != str.length()) - { - if (newBegin != oldBegin) - str = S(newBegin, newLength); //minor inefficiency: in case "str" is not shared, we could save an allocation and do a memory move only - else - str.resize(newLength); - } + if (newBegin != oldBegin) + str = S(newBegin, newEnd - newBegin); //minor inefficiency: in case "str" is not shared, we could save an allocation and do a memory move only + else + str.resize(newEnd - newBegin); } @@ -374,8 +356,8 @@ namespace implementation template <class Num> inline int saferPrintf(char* buffer, size_t bufferSize, const char* format, const Num& number) //there is no such thing as a "safe" printf ;) { -#ifdef _MSC_VER - return ::_snprintf(buffer, bufferSize, format, number); //VS2010 doesn't respect ISO C +#if defined _MSC_VER || defined __MINGW32__ + return ::_snprintf(buffer, bufferSize, format, number); //by factor 10 faster than "std::snprintf" on Mingw and on par with std::sprintf()!!! #else return std::snprintf(buffer, bufferSize, format, number); //C99 #endif @@ -385,7 +367,7 @@ template <class Num> inline int saferPrintf(wchar_t* buffer, size_t bufferSize, const wchar_t* format, const Num& number) { #ifdef __MINGW32__ - return ::snwprintf(buffer, bufferSize, format, number); //MinGW doesn't respect ISO C + return ::_snwprintf(buffer, bufferSize, format, number); //MinGW doesn't respect ISO C #else return std::swprintf(buffer, bufferSize, format, number); //C99 #endif @@ -395,12 +377,12 @@ int saferPrintf(wchar_t* buffer, size_t bufferSize, const wchar_t* format, const template <class S, class T, class Num> inline S printNumber(const T& format, const Num& number) //format a single number using ::sprintf { - assert_static(IsStringLike<T>::result); + assert_static(IsStringLike<T>::value); assert_static((IsSameType< - typename GetCharType<S>::Result, - typename GetCharType<T>::Result>::result)); + typename GetCharType<S>::Type, + typename GetCharType<T>::Type>::value)); - typedef typename GetCharType<S>::Result CharType; + typedef typename GetCharType<S>::Type CharType; const int BUFFER_SIZE = 128; CharType buffer[BUFFER_SIZE]; @@ -422,9 +404,9 @@ enum NumberType template <class S, class Num> inline -S toString(const Num& number, Int2Type<NUM_TYPE_OTHER>) //default number to string conversion using streams: convenient, but SLOW, SLOW, SLOW!!!! (~ factor of 20) +S numberTo(const Num& number, Int2Type<NUM_TYPE_OTHER>) //default number to string conversion using streams: convenient, but SLOW, SLOW, SLOW!!!! (~ factor of 20) { - typedef typename GetCharType<S>::Result CharType; + typedef typename GetCharType<S>::Type CharType; std::basic_ostringstream<CharType> ss; ss << number; @@ -436,9 +418,9 @@ template <class S, class Num> inline S floatToString(const Num& number, char ) template <class S, class Num> inline S floatToString(const Num& number, wchar_t) { return printNumber<S>(L"%g", static_cast<double>(number)); } template <class S, class Num> inline -S toString(const Num& number, Int2Type<NUM_TYPE_FLOATING_POINT>) +S numberTo(const Num& number, Int2Type<NUM_TYPE_FLOATING_POINT>) { - return floatToString<S>(number, typename GetCharType<S>::Result()); + return floatToString<S>(number, typename GetCharType<S>::Type()); } @@ -452,32 +434,37 @@ perf: integer to string: (executed 10 mio. times) template <class S, class Num> inline S formatInteger(Num n, bool hasMinus) { - typedef typename GetCharType<S>::Result CharType; - assert(n >= 0); - S output; + typedef typename GetCharType<S>::Type CharType; + + const size_t bufferSize = 100; //sufficient for signed 256-bit numbers + CharType buffer[bufferSize]; //it's generally faster to use a buffer than to rely on String::operator+=() (in)efficiency + assert_static(2 + 5 * sizeof(n) / 2 <= bufferSize); + //minimum required chars (+ sign char): 1 + ceil(ln_10 (256^sizeof(n))) =~ 1 + ceil(sizeof(n) * 2.4082) <= 2 + floor(sizeof(n) * 2.5) + + size_t startPos = bufferSize; do { - output += static_cast<CharType>('0' + n % 10); + buffer[--startPos] = static_cast<char>('0' + n % 10); n /= 10; } while (n != 0); + if (hasMinus) - output += static_cast<CharType>('-'); + buffer[--startPos] = static_cast<CharType>('-'); - std::reverse(output.begin(), output.end()); - return output; + return S(buffer + startPos, bufferSize - startPos); } template <class S, class Num> inline -S toString(const Num& number, Int2Type<NUM_TYPE_SIGNED_INT>) +S numberTo(const Num& number, Int2Type<NUM_TYPE_SIGNED_INT>) { return formatInteger<S>(number < 0 ? -number : number, number < 0); } template <class S, class Num> inline -S toString(const Num& number, Int2Type<NUM_TYPE_UNSIGNED_INT>) +S numberTo(const Num& number, Int2Type<NUM_TYPE_UNSIGNED_INT>) { return formatInteger<S>(number, false); } @@ -486,20 +473,20 @@ S toString(const Num& number, Int2Type<NUM_TYPE_UNSIGNED_INT>) template <class Num, class S> inline -Num toNumber(const S& str, Int2Type<NUM_TYPE_OTHER>) //default string to number conversion using streams: convenient, but SLOW +Num stringTo(const S& str, Int2Type<NUM_TYPE_OTHER>) //default string to number conversion using streams: convenient, but SLOW { - typedef typename GetCharType<S>::Result CharType; + typedef typename GetCharType<S>::Type CharType; Num number = 0; std::basic_istringstream<CharType>(copyStringTo<std::basic_string<CharType> >(str)) >> number; return number; } -template <class Num> inline Num stringToFloat(const char* str) { return std::strtod(str, NULL); } -template <class Num> inline Num stringToFloat(const wchar_t* str) { return std::wcstod(str, NULL); } +template <class Num> inline Num stringToFloat(const char* str) { return std::strtod(str, nullptr); } +template <class Num> inline Num stringToFloat(const wchar_t* str) { return std::wcstod(str, nullptr); } template <class Num, class S> inline -Num toNumber(const S& str, Int2Type<NUM_TYPE_FLOATING_POINT>) +Num stringTo(const S& str, Int2Type<NUM_TYPE_FLOATING_POINT>) { return stringToFloat<Num>(strBegin(str)); } @@ -507,12 +494,12 @@ Num toNumber(const S& str, Int2Type<NUM_TYPE_FLOATING_POINT>) template <class Num, class S> Num extractInteger(const S& str, bool& hasMinusSign) //very fast conversion to integers: slightly faster than std::atoi, but more importantly: generic { - typedef typename GetCharType<S>::Result CharType; + typedef typename GetCharType<S>::Type CharType; const CharType* first = strBegin(str); const CharType* last = first + strLength(str); - while (first != last && cStringIsWhiteSpace(*first)) //skip leading whitespace + while (first != last && isWhiteSpace(*first)) //skip leading whitespace ++first; //handle minus sign @@ -540,7 +527,7 @@ Num extractInteger(const S& str, bool& hasMinusSign) //very fast conversion to i else { //rest of string should contain whitespace only - //assert(std::find_if(iter, last, std::not1(std::ptr_fun(&cStringIsWhiteSpace<CharType>))) == last); -> this is NO assert situation + //assert(std::all_of(iter, last, &isWhiteSpace<CharType>)); -> this is NO assert situation break; } } @@ -549,7 +536,7 @@ Num extractInteger(const S& str, bool& hasMinusSign) //very fast conversion to i template <class Num, class S> inline -Num toNumber(const S& str, Int2Type<NUM_TYPE_SIGNED_INT>) +Num stringTo(const S& str, Int2Type<NUM_TYPE_SIGNED_INT>) { bool hasMinusSign = false; //handle minus sign const Num number = extractInteger<Num>(str, hasMinusSign); @@ -558,7 +545,7 @@ Num toNumber(const S& str, Int2Type<NUM_TYPE_SIGNED_INT>) template <class Num, class S> inline -Num toNumber(const S& str, Int2Type<NUM_TYPE_UNSIGNED_INT>) //very fast conversion to integers: slightly faster than std::atoi, but more importantly: generic +Num stringTo(const S& str, Int2Type<NUM_TYPE_UNSIGNED_INT>) //very fast conversion to integers: slightly faster than std::atoi, but more importantly: generic { bool hasMinusSign = false; //handle minus sign const Num number = extractInteger<Num>(str, hasMinusSign); @@ -573,28 +560,28 @@ Num toNumber(const S& str, Int2Type<NUM_TYPE_UNSIGNED_INT>) //very fast conversi template <class S, class Num> inline -S toString(const Num& number) //convert number to string the C++ way +S numberTo(const Num& number) { typedef Int2Type< - IsSignedInt <Num>::result ? implementation::NUM_TYPE_SIGNED_INT : - IsUnsignedInt<Num>::result ? implementation::NUM_TYPE_UNSIGNED_INT : - IsFloat <Num>::result ? implementation::NUM_TYPE_FLOATING_POINT : + IsSignedInt <Num>::value ? implementation::NUM_TYPE_SIGNED_INT : + IsUnsignedInt<Num>::value ? implementation::NUM_TYPE_UNSIGNED_INT : + IsFloat <Num>::value ? implementation::NUM_TYPE_FLOATING_POINT : implementation::NUM_TYPE_OTHER> TypeTag; - return implementation::toString<S>(number, TypeTag()); + return implementation::numberTo<S>(number, TypeTag()); } template <class Num, class S> inline -Num toNumber(const S& str) //convert string to number the C++ way +Num stringTo(const S& str) { typedef Int2Type< - IsSignedInt <Num>::result ? implementation::NUM_TYPE_SIGNED_INT : - IsUnsignedInt<Num>::result ? implementation::NUM_TYPE_UNSIGNED_INT : - IsFloat <Num>::result ? implementation::NUM_TYPE_FLOATING_POINT : + IsSignedInt <Num>::value ? implementation::NUM_TYPE_SIGNED_INT : + IsUnsignedInt<Num>::value ? implementation::NUM_TYPE_UNSIGNED_INT : + IsFloat <Num>::value ? implementation::NUM_TYPE_FLOATING_POINT : implementation::NUM_TYPE_OTHER> TypeTag; - return implementation::toNumber<Num>(str, TypeTag()); + return implementation::stringTo<Num>(str, TypeTag()); } } diff --git a/zen/string_traits.h b/zen/string_traits.h index c06aa6e3..cfcf78bb 100644 --- a/zen/string_traits.h +++ b/zen/string_traits.h @@ -9,7 +9,6 @@ #define STRING_TRAITS_HEADER_813274321443234 #include "type_tools.h" -#include "type_traits.h" #include "assert_static.h" @@ -17,13 +16,13 @@ namespace zen { /* -IsStringLike<>::result: - IsStringLike<const wchar_t*>::result; //equals "true" - IsStringLike<const int*> ::result; //equals "false" +IsStringLike<>::value: + IsStringLike<const wchar_t*>::value; //equals "true" + IsStringLike<const int*> ::value; //equals "false" -GetCharType<>::Result: - GetCharType<std::wstring>::Result //equals wchar_t - GetCharType<wchar_t[5]> ::Result //equals wchar_t +GetCharType<>::Type: + GetCharType<std::wstring>::Type //equals wchar_t + GetCharType<wchar_t[5]> ::Type //equals wchar_t strBegin(): std::wstring str(L"dummy"); @@ -67,21 +66,6 @@ private: //---------------------- implementation ---------------------- namespace implementation { -ZEN_INIT_DETECT_MEMBER(c_str) //we don't know the exact declaration of the member attribute and it may be in a base class! -ZEN_INIT_DETECT_MEMBER(length) // - -template<typename T, bool isClassType> -struct HasStringMembers { enum { result = false }; }; - -template<typename T> -struct HasStringMembers<T, true> //Note: we can apply non-typed member-check on class types only! -{ - enum { result = HasMember_c_str <T>::result && - HasMember_length<T>::result - }; -}; - - template<class S, class Char> //test if result of S::c_str() can convert to const Char* class HasConversion { @@ -91,63 +75,69 @@ class HasConversion static Yes& hasConversion(const Char*); static No& hasConversion(...); - static S createInstance(); + static S& createInstance(); public: - enum { result = sizeof(hasConversion(createInstance().c_str())) == sizeof(Yes) }; + enum { value = sizeof(hasConversion(createInstance().c_str())) == sizeof(Yes) }; }; -template <class S, bool isStringClass> struct GetCharTypeImpl { typedef EmptyType Result; }; -template <class S> struct GetCharTypeImpl<S, true > +template <class S, bool isStringClass> struct GetCharTypeImpl : ResultType<NullType> {}; +template <class S> +struct GetCharTypeImpl<S, true> : + ResultType< + typename SelectIf<HasConversion<S, wchar_t>::value, wchar_t, + typename SelectIf<HasConversion<S, char >::value, char, NullType>::Type + >::Type> { - //typedef typename S::value_type Result; + //typedef typename S::value_type Type; /*DON'T use S::value_type: 1. support Glib::ustring: value_type is "unsigned int" but c_str() returns "const char*" 2. wxString, wxWidgets v2.9, has some questionable string design: wxString::c_str() returns a proxy (wxCStrData) which is implicitly convertible to *both* "const char*" and "const wchar_t*" while wxString::value_type is a wrapper around an unsigned int */ - typedef typename SelectIf<HasConversion<S, wchar_t>::result, wchar_t, - typename SelectIf<HasConversion<S, char>::result, char, EmptyType>::Result - >::Result Result; }; - -template <> struct GetCharTypeImpl<char, false> { typedef char Result; }; -template <> struct GetCharTypeImpl<wchar_t, false> { typedef wchar_t Result; }; +template <> struct GetCharTypeImpl<char, false> : ResultType<char > {}; +template <> struct GetCharTypeImpl<wchar_t, false> : ResultType<wchar_t> {}; ZEN_INIT_DETECT_MEMBER_TYPE(value_type); +ZEN_INIT_DETECT_MEMBER(c_str); //we don't know the exact declaration of the member attribute and it may be in a base class! +ZEN_INIT_DETECT_MEMBER(length); // template <class S> class StringTraits { - typedef typename RemoveRef <S >::Result NonRefType; - typedef typename RemoveConst <NonRefType >::Result NonConstType; - typedef typename RemoveArray <NonConstType>::Result NonArrayType; - typedef typename RemovePointer<NonArrayType>::Result NonPtrType; - typedef typename RemoveConst <NonPtrType >::Result UndecoratedType; //handle "const char* const" + typedef typename RemoveRef <S >::Type NonRefType; + typedef typename RemoveConst <NonRefType >::Type NonConstType; + typedef typename RemoveArray <NonConstType>::Type NonArrayType; + typedef typename RemovePointer<NonArrayType>::Type NonPtrType; + typedef typename RemoveConst <NonPtrType >::Type UndecoratedType; //handle "const char* const" public: enum { - isStringClass = HasStringMembers<NonConstType, HasMemberType_value_type<NonConstType>::result>::result + isStringClass = HasMemberType_value_type<NonConstType>::value && + HasMember_c_str <NonConstType>::value && + HasMember_length <NonConstType>::value }; - typedef typename GetCharTypeImpl<UndecoratedType, isStringClass>::Result CharType; + typedef typename GetCharTypeImpl<UndecoratedType, isStringClass>::Type CharType; enum { - isStringLike = IsSameType<CharType, char>::result || - IsSameType<CharType, wchar_t>::result + isStringLike = + IsSameType<CharType, char >::value || + IsSameType<CharType, wchar_t>::value }; }; } template <class T> -struct IsStringLike { enum { result = implementation::StringTraits<T>::isStringLike }; }; +struct IsStringLike : StaticBool<implementation::StringTraits<T>::isStringLike> {}; template <class T> -struct GetCharType { typedef typename implementation::StringTraits<T>::CharType Result; }; +struct GetCharType : ResultType<typename implementation::StringTraits<T>::CharType> {}; namespace implementation @@ -155,7 +145,7 @@ namespace implementation template <class C> inline size_t cStringLength(const C* str) //strlen() { - assert_static((IsSameType<C, char>::result || IsSameType<C, wchar_t>::result)); + assert_static((IsSameType<C, char>::value || IsSameType<C, wchar_t>::value)); size_t len = 0; while (*str++ != 0) ++len; @@ -165,7 +155,7 @@ size_t cStringLength(const C* str) //strlen() template <class S> inline -const typename GetCharType<S>::Result* strBegin(const S& str, typename EnableIf<implementation::StringTraits<S>::isStringClass>::Result* = NULL) //SFINAE: T must be a "string" +const typename GetCharType<S>::Type* strBegin(const S& str, typename EnableIf<implementation::StringTraits<S>::isStringClass>::Type* = nullptr) //SFINAE: T must be a "string" { return str.c_str(); } @@ -177,7 +167,7 @@ inline const wchar_t* strBegin(const wchar_t& ch) { return &ch; } template <class S> inline -size_t strLength(const S& str, typename EnableIf<implementation::StringTraits<S>::isStringClass>::Result* = NULL) //SFINAE: T must be a "string" +size_t strLength(const S& str, typename EnableIf<implementation::StringTraits<S>::isStringClass>::Type* = nullptr) //SFINAE: T must be a "string" { return str.length(); } diff --git a/zen/symlink_target.h b/zen/symlink_target.h index 20433b43..006e4ea0 100644 --- a/zen/symlink_target.h +++ b/zen/symlink_target.h @@ -76,10 +76,10 @@ Zstring getSymlinkRawTargetString(const Zstring& linkPath) //throw FileError 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, - NULL); + nullptr); if (hLink == INVALID_HANDLE_VALUE) throw FileError(_("Error resolving symbolic link:") + L"\n\"" + linkPath + L"\"" + L"\n\n" + getLastErrorFormatted()); - ZEN_ON_BLOCK_EXIT(::CloseHandle(hLink)); + ZEN_ON_SCOPE_EXIT(::CloseHandle(hLink)); //respect alignment issues... const DWORD bufferSize = REPARSE_DATA_BUFFER_HEADER_SIZE + MAXIMUM_REPARSE_DATA_BUFFER_SIZE; @@ -88,12 +88,12 @@ Zstring getSymlinkRawTargetString(const Zstring& linkPath) //throw FileError DWORD bytesReturned; //dummy value required by FSCTL_GET_REPARSE_POINT! if (!::DeviceIoControl(hLink, //__in HANDLE hDevice, FSCTL_GET_REPARSE_POINT, //__in DWORD dwIoControlCode, - NULL, //__in_opt LPVOID lpInBuffer, + nullptr, //__in_opt LPVOID lpInBuffer, 0, //__in DWORD nInBufferSize, &buffer[0], //__out_opt LPVOID lpOutBuffer, bufferSize, //__in DWORD nOutBufferSize, &bytesReturned, //__out_opt LPDWORD lpBytesReturned, - NULL)) //__inout_opt LPOVERLAPPED lpOverlapped + nullptr)) //__inout_opt LPOVERLAPPED lpOverlapped throw FileError(_("Error resolving symbolic link:") + L"\n\"" + linkPath + L"\"" + L"\n\n" + getLastErrorFormatted()); REPARSE_DATA_BUFFER& reparseData = *reinterpret_cast<REPARSE_DATA_BUFFER*>(&buffer[0]); //REPARSE_DATA_BUFFER needs to be artificially enlarged! @@ -25,16 +25,16 @@ struct TimeComp //replaces "struct std::tm" and SYSTEMTIME int second; //0-61 }; -TimeComp localTime (time_t utc = std::time(NULL)); //convert time_t (UTC) to local time components +TimeComp localTime (time_t utc = std::time(nullptr)); //convert time_t (UTC) to local time components time_t localToTimeT(const TimeComp& comp); //convert local time components to time_t (UTC), returns -1 on error //---------------------------------------------------------------------------------------------------------------------------------- /* format (current) date and time; example: - formatTime<std::wstring>(L"%Y*%m*%d"); -> "2011*10*29" - formatTime<std::wstring>(FORMAT_DATE); -> "2011-10-29" - formatTime<std::wstring>(FORMAT_TIME); -> "17:55:34" + formatTime<std::wstring>(L"%Y*%m*%d"); -> "2011*10*29" + formatTime<std::wstring>(FORMAT_DATE); -> "2011-10-29" + formatTime<std::wstring>(FORMAT_TIME); -> "17:55:34" */ template <class String, class String2> String formatTime(const String2& format, const TimeComp& comp = localTime()); //format as specified by "std::strftime", returns empty string on failure @@ -82,6 +82,12 @@ namespace implementation inline struct std::tm toClibTimeComponents(const TimeComp& comp) { + assert(1 <= comp.month && comp.month <= 12 && + 1 <= comp.day && comp.day <= 31 && + 0 <= comp.hour && comp.hour <= 23 && + 0 <= comp.minute && comp.minute <= 59 && + 0 <= comp.second && comp.second <= 61); + struct std::tm ctc = {}; ctc.tm_year = comp.year - 1900; //years since 1900 ctc.tm_mon = comp.month - 1; //0-11 @@ -90,6 +96,7 @@ struct std::tm toClibTimeComponents(const TimeComp& comp) ctc.tm_min = comp.minute; //0-59 ctc.tm_sec = comp.second; //0-61 ctc.tm_isdst = -1; //> 0 if DST is active, == 0 if DST is not active, < 0 if the information is not available + return ctc; } @@ -132,14 +139,14 @@ struct GetFormat<FormatDateTimeTag> //%c - locale dependent date and time: }; template <> -struct GetFormat<FormatIsoDateTag> //%Y-%m-%d - e.g. 2001-08-23 +struct GetFormat<FormatIsoDateTag> //%Y-%m-%d - e.g. 2001-08-23 { const char* format(char) const { return "%Y-%m-%d"; } const wchar_t* format(wchar_t) const { return L"%Y-%m-%d"; } }; template <> -struct GetFormat<FormatIsoTimeTag> //%H:%M:%S - e.g. 14:55:02 +struct GetFormat<FormatIsoTimeTag> //%H:%M:%S - e.g. 14:55:02 { const char* format(char) const { return "%H:%M:%S"; } const wchar_t* format(wchar_t) const { return L"%H:%M:%S"; } @@ -173,10 +180,10 @@ struct PredefinedFormatTag {}; template <class String, class String2> inline String formatTime(const String2& format, const TimeComp& comp, UserDefinedFormatTag) //format as specified by "std::strftime", returns empty string on failure { - typedef typename GetCharType<String>::Result CharType; + typedef typename GetCharType<String>::Type CharType; struct std::tm ctc = toClibTimeComponents(comp); - std::mktime (&ctc); // unfortunately std::strftime() needs all elements of "struct tm" filled, e.g. tm_wday, tm_yday + std::mktime(&ctc); // unfortunately std::strftime() needs all elements of "struct tm" filled, e.g. tm_wday, tm_yday //note: although std::mktime() explicitly expects "local time", calculating weekday and day of year *should* be time-zone and DST independent CharType buffer[256]; @@ -187,7 +194,7 @@ String formatTime(const String2& format, const TimeComp& comp, UserDefinedFormat template <class String, class FormatType> inline String formatTime(FormatType, const TimeComp& comp, PredefinedFormatTag) { - typedef typename GetCharType<String>::Result CharType; + typedef typename GetCharType<String>::Type CharType; return formatTime<String>(GetFormat<FormatType>().format(CharType()), comp, UserDefinedFormatTag()); } } @@ -196,7 +203,14 @@ String formatTime(FormatType, const TimeComp& comp, PredefinedFormatTag) inline TimeComp localTime(time_t utc) { - return implementation::toZenTimeComponents(*std::localtime (&utc)); +#ifdef _MSC_VER + struct tm lt = {}; + /*errno_t rv = */ + ::localtime_s(<, &utc); //more secure? + return implementation::toZenTimeComponents(lt); +#else + return implementation::toZenTimeComponents(*std::localtime(&utc)); +#endif } @@ -212,12 +226,12 @@ template <class String, class String2> inline String formatTime(const String2& format, const TimeComp& comp) { typedef typename SelectIf< - IsSameType<String2, FormatDateTag >::result || - IsSameType<String2, FormatTimeTag >::result || - IsSameType<String2, FormatDateTimeTag >::result || - IsSameType<String2, FormatIsoDateTag >::result || - IsSameType<String2, FormatIsoTimeTag >::result || - IsSameType<String2, FormatIsoDateTimeTag>::result, implementation::PredefinedFormatTag, implementation::UserDefinedFormatTag>::Result FormatTag; + IsSameType<String2, FormatDateTag >::value || + IsSameType<String2, FormatTimeTag >::value || + IsSameType<String2, FormatDateTimeTag >::value || + IsSameType<String2, FormatIsoDateTag >::value || + IsSameType<String2, FormatIsoTimeTag >::value || + IsSameType<String2, FormatIsoDateTimeTag>::value, implementation::PredefinedFormatTag, implementation::UserDefinedFormatTag>::Type FormatTag; return implementation::formatTime<String>(format, comp, FormatTag()); } @@ -226,7 +240,7 @@ String formatTime(const String2& format, const TimeComp& comp) template <class String> bool parseTime(const String& format, const String& str, TimeComp& comp) //return true on success { - typedef typename GetCharType<String>::Result CharType; + typedef typename GetCharType<String>::Type CharType; const CharType* iterFmt = strBegin(format); const CharType* const fmtLast = iterFmt + strLength(format); @@ -239,10 +253,10 @@ bool parseTime(const String& format, const String& str, TimeComp& comp) //return if (strLast - iterStr < digitCount) return false; - if (std::find_if(iterStr, iterStr + digitCount, [](CharType c) { return !cStringIsDigit(c); }) != str.end()) + if (std::any_of(iterStr, iterStr + digitCount, [](CharType c) { return !isDigit(c); })) return false; - result = zen::toNumber<int>(StringProxy<CharType>(iterStr, digitCount)); + result = zen::stringTo<int>(StringProxy<CharType>(iterStr, digitCount)); iterStr += digitCount; return true; }; @@ -287,9 +301,9 @@ bool parseTime(const String& format, const String& str, TimeComp& comp) //return return false; } } - else if (cStringIsWhiteSpace(fmt)) //single whitespace in format => skip 0..n whitespace chars + else if (isWhiteSpace(fmt)) //single whitespace in format => skip 0..n whitespace chars { - while (iterStr != strLast && cStringIsWhiteSpace(*iterStr)) + while (iterStr != strLast && isWhiteSpace(*iterStr)) ++iterStr; } else diff --git a/zen/type_tools.h b/zen/type_tools.h index 03105ac8..b221954c 100644 --- a/zen/type_tools.h +++ b/zen/type_tools.h @@ -8,11 +8,12 @@ #ifndef TYPE_TOOLS_HEADER_45237590734254545 #define TYPE_TOOLS_HEADER_45237590734254545 +#include "type_traits.h" + namespace zen { //########## Strawman Classes ########################## -struct EmptyType {}; -struct NullType {}; +struct NullType {}; //:= no type here //########## Type Mapping ############################## template <int n> @@ -23,61 +24,47 @@ struct Type2Type {}; //########## Control Structures ######################## template <bool flag, class T, class U> -struct SelectIf -{ - typedef T Result; -}; +struct SelectIf : ResultType<T> {}; + template <class T, class U> -struct SelectIf<false, T, U> -{ - typedef U Result; -}; +struct SelectIf<false, T, U> : ResultType<U> {}; //------------------------------------------------------ template <class T, class U> -struct IsSameType -{ - enum { result = false }; -}; +struct IsSameType : StaticBool<false> {}; template <class T> -struct IsSameType<T, T> -{ - enum { result = true }; -}; +struct IsSameType<T, T> : StaticBool<true> {}; //------------------------------------------------------ template <bool, class T = void> struct EnableIf {}; -template <class T> -struct EnableIf<true, T> -{ - typedef T Result; -}; +template <class T> +struct EnableIf<true, T> : ResultType<T> {}; //########## Type Cleanup ############################## template <class T> -struct RemoveRef { typedef T Result; }; +struct RemoveRef : ResultType<T> {}; template <class T> -struct RemoveRef<T&> { typedef T Result; }; +struct RemoveRef<T&> : ResultType<T> {}; //------------------------------------------------------ template <class T> -struct RemoveConst { typedef T Result; }; +struct RemoveConst : ResultType<T> {}; template <class T> -struct RemoveConst<const T> { typedef T Result; }; +struct RemoveConst<const T> : ResultType<T> {}; //------------------------------------------------------ template <class T> -struct RemovePointer { typedef T Result; }; +struct RemovePointer : ResultType<T> {}; template <class T> -struct RemovePointer<T*> { typedef T Result; }; +struct RemovePointer<T*> : ResultType<T> {}; //------------------------------------------------------ template <class T> -struct RemoveArray { typedef T Result; }; +struct RemoveArray : ResultType<T> {}; template <class T, int N> -struct RemoveArray<T[N]> { typedef T Result; }; +struct RemoveArray<T[N]> : ResultType<T> {}; //########## Sorting ############################## /* diff --git a/zen/type_traits.h b/zen/type_traits.h index d9b28525..0b15eef1 100644 --- a/zen/type_traits.h +++ b/zen/type_traits.h @@ -8,10 +8,34 @@ #ifndef TYPE_TRAITS_HEADER_3425628658765467 #define TYPE_TRAITS_HEADER_3425628658765467 +#include <type_traits> //all we need is std::is_class!! + namespace zen { +//################# TMP compile time return values: "inherit to return compile-time result" ############## +template <int i> +struct StaticInt +{ + enum { value = i }; +}; + +template <bool b> +struct StaticBool : StaticInt<b> {}; + +template <class EnumType, EnumType val> +struct StaticEnum +{ + static const EnumType value = val; +}; +//--------------------------------------------------------- +template <class T> +struct ResultType +{ + typedef T Type; +}; + //################# Built-in Types ######################## -//Example: "IsSignedInt<int>::result" evaluates to "true" +//Example: "IsSignedInt<int>::value" evaluates to "true" template <class T> struct IsUnsignedInt; template <class T> struct IsSignedInt; @@ -22,27 +46,25 @@ template <class T> struct IsArithmetic; //IsInteger or IsFloat //remaining non-arithmetic types: bool, char, wchar_t //optional: specialize new types like: -//template <> struct IsUnsignedInt<UInt64> { enum { result = true }; }; +//template <> struct IsUnsignedInt<UInt64> : StaticBool<true> {}; //################# Class Members ######################## /* Detect data or function members of a class by name: ZEN_INIT_DETECT_MEMBER + HasMember_ - !!! Note: this may ONLY be used for class types: fails to compile for non-class types !!! - Example: 1. ZEN_INIT_DETECT_MEMBER(c_str); - 2. HasMember_c_str<T>::result -> use as boolean + 2. HasMember_c_str<T>::value -> use as boolean */ -/* Detect data or function members of a class by name and type: ZEN_INIT_DETECT_MEMBER2 + HasMember_ +/* Detect data or function members of a class by name *and* type: ZEN_INIT_DETECT_MEMBER2 + HasMember_ Example: 1. ZEN_INIT_DETECT_MEMBER2(size, size_t (T::*)() const); - 2. HasMember_size<T>::result -> use as boolean + 2. HasMember_size<T>::value -> use as boolean */ /* Detect member type of a class: ZEN_INIT_DETECT_MEMBER_TYPE + HasMemberType_ Example: 1. ZEN_INIT_DETECT_MEMBER_TYPE(value_type); - 2. HasMemberType_value_type<T>::result -> use as boolean + 2. HasMemberType_value_type<T>::value -> use as boolean */ @@ -65,10 +87,10 @@ template <class T> struct IsArithmetic; //IsInteger or IsFloat //################ implementation ###################### -#define ZEN_SPECIALIZE_TRAIT(X, Y) template <> struct X<Y> { enum { result = true }; }; +#define ZEN_SPECIALIZE_TRAIT(X, Y) template <> struct X<Y> : StaticBool<true> {}; template <class T> -struct IsUnsignedInt { enum { result = false }; }; +struct IsUnsignedInt : StaticBool<false> {}; ZEN_SPECIALIZE_TRAIT(IsUnsignedInt, unsigned char); ZEN_SPECIALIZE_TRAIT(IsUnsignedInt, unsigned short int); @@ -78,7 +100,7 @@ ZEN_SPECIALIZE_TRAIT(IsUnsignedInt, unsigned long long int); //new with C++11 - //------------------------------------------------------ template <class T> -struct IsSignedInt { enum { result = false }; }; +struct IsSignedInt : StaticBool<false> {}; ZEN_SPECIALIZE_TRAIT(IsSignedInt, signed char); ZEN_SPECIALIZE_TRAIT(IsSignedInt, short int); @@ -88,7 +110,7 @@ ZEN_SPECIALIZE_TRAIT(IsSignedInt, long long int); //new with C++11 - same type a //------------------------------------------------------ template <class T> -struct IsFloat { enum { result = false }; }; +struct IsFloat : StaticBool<false> {}; ZEN_SPECIALIZE_TRAIT(IsFloat, float); ZEN_SPECIALIZE_TRAIT(IsFloat, double); @@ -98,31 +120,40 @@ ZEN_SPECIALIZE_TRAIT(IsFloat, long double); #undef ZEN_SPECIALIZE_TRAIT template <class T> -struct IsInteger { enum { result = IsUnsignedInt<T>::result || IsSignedInt<T>::result }; }; +struct IsInteger : StaticBool<IsUnsignedInt<T>::value || IsSignedInt<T>::value> {}; template <class T> -struct IsArithmetic { enum { result = IsInteger<T>::result || IsFloat<T>::result }; }; +struct IsArithmetic : StaticBool<IsInteger<T>::value || IsFloat<T>::value> {}; //#################################################################### #define ZEN_INIT_DETECT_MEMBER(NAME) \ \ - template<typename T> \ - class HasMember_##NAME \ - { \ + template<bool isClass, class T> \ + struct HasMemberImpl_##NAME \ + { \ + private: \ typedef char Yes[1]; \ typedef char No [2]; \ \ - template <typename U, U t> class Helper {}; \ - struct Fallback { int NAME; }; \ + template <typename U, U t> \ + class Helper {}; \ + struct Fallback { int NAME; }; \ \ - template <class U> \ - struct Helper2 : public U, public Fallback {}; \ + template <class U> \ + struct Helper2 : public U, public Fallback {}; /*this works only for class types!!!*/ \ \ template <class U> static No& hasMember(Helper<int Fallback::*, &Helper2<U>::NAME>*); \ template <class U> static Yes& hasMember(...); \ public: \ - enum { result = sizeof(hasMember<T>(NULL)) == sizeof(Yes) }; \ - }; + enum { value = sizeof(hasMember<T>(nullptr)) == sizeof(Yes) }; \ + }; \ + \ + template<class T> \ + struct HasMemberImpl_##NAME<false, T> : StaticBool<false> {}; \ + \ + template<typename T> \ + struct HasMember_##NAME : StaticBool<HasMemberImpl_##NAME<std::is_class<T>::value, T>::value> {}; + //#################################################################### #define ZEN_INIT_DETECT_MEMBER2(NAME, TYPE) \ @@ -138,7 +169,7 @@ struct IsArithmetic { enum { result = IsInteger<T>::result || IsFloat<T>::result template <class T> static Yes& hasMember(Helper<TYPE, &T::NAME>*); \ template <class T> static No& hasMember(...); \ public: \ - enum { result = sizeof(hasMember<U>(NULL)) == sizeof(Yes) }; \ + enum { value = sizeof(hasMember<U>(nullptr)) == sizeof(Yes) }; \ }; //#################################################################### @@ -155,7 +186,7 @@ struct IsArithmetic { enum { result = IsInteger<T>::result || IsFloat<T>::result template <class U> static Yes& hasMemberType(Helper<typename U::TYPENAME>*); \ template <class U> static No& hasMemberType(...); \ public: \ - enum { result = sizeof(hasMemberType<T>(NULL)) == sizeof(Yes) }; \ + enum { value = sizeof(hasMemberType<T>(nullptr)) == sizeof(Yes) }; \ }; } @@ -8,13 +8,15 @@ #ifndef STRING_UTF8_HEADER_01832479146991573473545 #define STRING_UTF8_HEADER_01832479146991573473545 +#include <cstdint> #include <iterator> #include "string_tools.h" //copyStringTo namespace zen { //convert any(!) "string-like" object into target string by applying a UTF8 conversion (but only if necessary!) -template <class TargetString, class SourceString> TargetString utf8CvrtTo(const SourceString& str); +template <class TargetString, class SourceString> +TargetString utf8CvrtTo(const SourceString& str); //convert wide to utf8 string; example: std::string tmp = toUtf8<std::string>(L"abc"); template <class CharString, class WideString> @@ -62,7 +64,9 @@ const char BYTE_ORDER_MARK_UTF8[] = "\xEF\xBB\xBF"; //----------------------- implementation ---------------------------------- namespace implementation { -typedef unsigned int CodePoint; //must be at least four bytes +typedef std::uint_fast32_t CodePoint; //must be at least four bytes +typedef std::uint_fast16_t Char16; //we need an unsigned type +typedef unsigned char Char8; const CodePoint CODE_POINT_MAX = 0x10ffff; @@ -73,31 +77,28 @@ const CodePoint LOW_SURROGATE = 0xdc00; const CodePoint LOW_SURROGATE_MAX = 0xdfff; -template <class OutputIterator> inline -OutputIterator codePointToUtf16(CodePoint cp, OutputIterator result) //http://en.wikipedia.org/wiki/UTF-16 +template <class Function> inline +void codePointToUtf16(CodePoint cp, Function writeOutput) //"writeOutput" is a unary function taking a Char16 { - typedef unsigned short Char16; //this isn't necessarily 16 bit, but all we need is an unsigned type - + //http://en.wikipedia.org/wiki/UTF-16 assert(cp < HIGH_SURROGATE || LOW_SURROGATE_MAX < cp); //code points [0xd800, 0xdfff] are not allowed for UTF-16 assert(cp <= CODE_POINT_MAX); if (cp < 0x10000) - *result++ = static_cast<Char16>(cp); + writeOutput(static_cast<Char16>(cp)); else { cp -= 0x10000; - *result++ = static_cast<Char16>((cp >> 10) + HIGH_SURROGATE); - *result++ = static_cast<Char16>((cp & 0x3ff) + LOW_SURROGATE); + writeOutput(static_cast<Char16>((cp >> 10) + HIGH_SURROGATE)); + writeOutput(static_cast<Char16>((cp & 0x3ff) + LOW_SURROGATE)); } - return result; } template <class CharIterator, class Function> inline -Function utf16ToCodePoint(CharIterator first, CharIterator last, Function f) //f is a unary function taking a CodePoint as single parameter +void utf16ToCodePoint(CharIterator first, CharIterator last, Function writeOutput) //"writeOutput" is a unary function taking a CodePoint { assert_static(sizeof(typename std::iterator_traits<CharIterator>::value_type) == 2); - typedef unsigned short Char16; //this isn't necessarily 16 bit, but all we need is an unsigned type for ( ; first != last; ++first) { @@ -107,7 +108,7 @@ Function utf16ToCodePoint(CharIterator first, CharIterator last, Function f) //f if (++first == last) { assert(false); //low surrogate expected - break; + return; } assert(LOW_SURROGATE <= static_cast<Char16>(*first) && static_cast<Char16>(*first) <= LOW_SURROGATE_MAX); //low surrogate expected cp = ((cp - HIGH_SURROGATE) << 10) + static_cast<Char16>(*first) - LOW_SURROGATE + 0x10000; @@ -115,40 +116,37 @@ Function utf16ToCodePoint(CharIterator first, CharIterator last, Function f) //f else assert(cp < LOW_SURROGATE || LOW_SURROGATE_MAX < cp); //NO low surrogate expected - f(cp); + writeOutput(cp); } - return f; } -template <class OutputIterator> inline -OutputIterator codePointToUtf8(CodePoint cp, OutputIterator result) //http://en.wikipedia.org/wiki/UTF-8 +template <class Function> inline +void codePointToUtf8(CodePoint cp, Function writeOutput) //"writeOutput" is a unary function taking a Char8 { - typedef unsigned char Char8; - - assert(cp <= CODE_POINT_MAX); + //http://en.wikipedia.org/wiki/UTF-8 if (cp < 0x80) - *result++ = static_cast<Char8>(cp); + writeOutput(static_cast<Char8>(cp)); else if (cp < 0x800) { - *result++ = static_cast<Char8>((cp >> 6 ) | 0xc0); - *result++ = static_cast<Char8>((cp & 0x3f) | 0x80); + writeOutput(static_cast<Char8>((cp >> 6 ) | 0xc0)); + writeOutput(static_cast<Char8>((cp & 0x3f) | 0x80)); } else if (cp < 0x10000) { - *result++ = static_cast<Char8>((cp >> 12 ) | 0xe0); - *result++ = static_cast<Char8>(((cp >> 6) & 0x3f) | 0x80); - *result++ = static_cast<Char8>((cp & 0x3f ) | 0x80); + writeOutput(static_cast<Char8>((cp >> 12 ) | 0xe0)); + writeOutput(static_cast<Char8>(((cp >> 6) & 0x3f) | 0x80)); + writeOutput(static_cast<Char8>((cp & 0x3f ) | 0x80)); } else { - *result++ = static_cast<Char8>((cp >> 18 ) | 0xf0); - *result++ = static_cast<Char8>(((cp >> 12) & 0x3f) | 0x80); - *result++ = static_cast<Char8>(((cp >> 6) & 0x3f) | 0x80); - *result++ = static_cast<Char8>((cp & 0x3f ) | 0x80); + assert(cp <= CODE_POINT_MAX); + writeOutput(static_cast<Char8>((cp >> 18 ) | 0xf0)); + writeOutput(static_cast<Char8>(((cp >> 12) & 0x3f) | 0x80)); + writeOutput(static_cast<Char8>(((cp >> 6) & 0x3f) | 0x80)); + writeOutput(static_cast<Char8>((cp & 0x3f ) | 0x80)); } - return result; } @@ -170,14 +168,13 @@ size_t getUtf8Len(unsigned char ch) template <class CharIterator, class Function> inline -Function utf8ToCodePoint(CharIterator first, CharIterator last, Function f) //f is a unary function taking a CodePoint as single parameter +void utf8ToCodePoint(CharIterator first, CharIterator last, Function writeOutput) //"writeOutput" is a unary function taking a CodePoint { assert_static(sizeof(typename std::iterator_traits<CharIterator>::value_type) == 1); - typedef unsigned char Char8; for ( ; first != last; ++first) { - auto getChar = [&](Char8 & ch) -> bool + auto getChar = [&](Char8& ch) -> bool { if (++first == last) { @@ -189,71 +186,55 @@ Function utf8ToCodePoint(CharIterator first, CharIterator last, Function f) //f return true; }; - CodePoint cp = static_cast<Char8>(*first); - switch (getUtf8Len(static_cast<Char8>(cp))) + Char8 ch = static_cast<Char8>(*first); + switch (getUtf8Len(ch)) { case 1: + writeOutput(ch); break; case 2: { - cp = (cp & 0x1f) << 6; - Char8 ch; - if (!getChar(ch)) continue; + CodePoint cp = (ch & 0x1f) << 6; + if (!getChar(ch)) return; cp += ch & 0x3f; + writeOutput(cp); } break; case 3: { - cp = (cp & 0xf) << 12; - Char8 ch; - if (!getChar(ch)) continue; + CodePoint cp = (ch & 0xf) << 12; + if (!getChar(ch)) return; cp += (ch & 0x3f) << 6; - if (!getChar(ch)) continue; + if (!getChar(ch)) return; cp += ch & 0x3f; - + writeOutput(cp); } break; case 4: { - cp = (cp & 0x7) << 18; - Char8 ch; - if (!getChar(ch)) continue; + CodePoint cp = (ch & 0x7) << 18; + if (!getChar(ch)) return; cp += (ch & 0x3f) << 12; - if (!getChar(ch)) continue; + if (!getChar(ch)) return; cp += (ch & 0x3f) << 6; - if (!getChar(ch)) continue; + if (!getChar(ch)) return; cp += ch & 0x3f; + writeOutput(cp); } break; default: assert(false); } - f(cp); } - return f; } -template <class String> -class AppendStringIterator: public std::iterator<std::output_iterator_tag, void, void, void, void> -{ -public: - explicit AppendStringIterator (String& x) : str(&x) {} - AppendStringIterator& operator= (typename String::value_type value) { *str += value; return *this; } - AppendStringIterator& operator* () { return *this; } - AppendStringIterator& operator++ () { return *this; } - AppendStringIterator operator++ (int) { return *this; } -private: - String* str; -}; - - template <class WideString, class CharString> inline WideString utf8ToWide(const CharString& str, Int2Type<2>) //windows: convert utf8 to utf16 wchar_t { WideString output; utf8ToCodePoint(strBegin(str), strBegin(str) + strLength(str), - [&](CodePoint cp) { codePointToUtf16(cp, AppendStringIterator<WideString>(output)); }); + [&](CodePoint cp) { codePointToUtf16(cp, [&](Char16 c) { output += static_cast<wchar_t>(c); }); }); return output; } @@ -273,7 +254,7 @@ CharString wideToUtf8(const WideString& str, Int2Type<2>) //windows: convert utf { CharString output; utf16ToCodePoint(strBegin(str), strBegin(str) + strLength(str), - [&](CodePoint cp) { codePointToUtf8(cp, AppendStringIterator<CharString>(output)); }); + [&](CodePoint cp) { codePointToUtf8(cp, [&](char c) { output += c; }); }); return output; } @@ -283,7 +264,7 @@ CharString wideToUtf8(const WideString& str, Int2Type<4>) //other OS: convert ut { CharString output; std::for_each(strBegin(str), strBegin(str) + strLength(str), - [&](CodePoint cp) { codePointToUtf8(cp, AppendStringIterator<CharString>(output)); }); + [&](CodePoint cp) { codePointToUtf8(cp, [&](char c) { output += c; }); }); return output; } } @@ -292,8 +273,8 @@ CharString wideToUtf8(const WideString& str, Int2Type<4>) //other OS: convert ut template <class WideString, class CharString> inline WideString utf8ToWide(const CharString& str) { - assert_static((IsSameType<typename GetCharType<CharString>::Result, char >::result)); - assert_static((IsSameType<typename GetCharType<WideString>::Result, wchar_t>::result)); + assert_static((IsSameType<typename GetCharType<CharString>::Type, char >::value)); + assert_static((IsSameType<typename GetCharType<WideString>::Type, wchar_t>::value)); return implementation::utf8ToWide<WideString>(str, Int2Type<sizeof(wchar_t)>()); } @@ -302,8 +283,8 @@ WideString utf8ToWide(const CharString& str) template <class CharString, class WideString> inline CharString wideToUtf8(const WideString& str) { - assert_static((IsSameType<typename GetCharType<CharString>::Result, char >::result)); - assert_static((IsSameType<typename GetCharType<WideString>::Result, wchar_t>::result)); + assert_static((IsSameType<typename GetCharType<CharString>::Type, char >::value)); + assert_static((IsSameType<typename GetCharType<WideString>::Type, wchar_t>::value)); return implementation::wideToUtf8<CharString>(str, Int2Type<sizeof(wchar_t)>()); } @@ -326,8 +307,8 @@ template <class TargetString, class SourceString> inline TargetString utf8CvrtTo(const SourceString& str) { return utf8CvrtTo<TargetString>(str, - typename GetCharType<SourceString>::Result(), - typename GetCharType<TargetString>::Result()); + typename GetCharType<SourceString>::Type(), + typename GetCharType<TargetString>::Type()); } } diff --git a/zen/zstring.cpp b/zen/zstring.cpp index d17e860c..d37fa522 100644 --- a/zen/zstring.cpp +++ b/zen/zstring.cpp @@ -35,7 +35,7 @@ LeakChecker::~LeakChecker() const std::string message = std::string("Memory leak detected!") + "\n\n" + "Candidates:\n" + leakingStrings; #ifdef FFS_WIN - MessageBoxA(NULL, message.c_str(), "Error", 0); + MessageBoxA(nullptr, message.c_str(), "Error", 0); #else std::cerr << message; std::abort(); @@ -70,7 +70,7 @@ std::string LeakChecker::rawMemToString(const void* ptr, size_t size) void LeakChecker::reportProblem(const std::string& message) //throw (std::logic_error) { #ifdef FFS_WIN - ::MessageBoxA(NULL, message.c_str(), "Error", 0); + ::MessageBoxA(nullptr, message.c_str(), "Error", 0); #else std::cerr << message; #endif @@ -100,20 +100,20 @@ typedef int (WINAPI* CompareStringOrdinalFunc)(LPCWSTR lpString1, LPCWSTR lpString2, int cchCount2, BOOL bIgnoreCase); -const SysDllFun<CompareStringOrdinalFunc> ordinalCompare = SysDllFun<CompareStringOrdinalFunc>(L"kernel32.dll", "CompareStringOrdinal"); +const SysDllFun<CompareStringOrdinalFunc> compareStringOrdinal = SysDllFun<CompareStringOrdinalFunc>(L"kernel32.dll", "CompareStringOrdinal"); } -int z_impl::compareFilenamesWin(const wchar_t* a, const wchar_t* b, size_t sizeA, size_t sizeB) +int z_impl::compareFilenamesWin(const wchar_t* lhs, const wchar_t* rhs, size_t sizeLhs, size_t sizeRhs) { //caveat: function scope static initialization is not thread-safe in VS 2010! - if (ordinalCompare) //this additional test has no noticeable performance impact + if (compareStringOrdinal) //this additional test has no noticeable performance impact { - const int rv = ordinalCompare(a, //pointer to first string - static_cast<int>(sizeA), //size, in bytes or characters, of first string - b, //pointer to second string - static_cast<int>(sizeB), //size, in bytes or characters, of second string - true); //ignore case + const int rv = compareStringOrdinal(lhs, //__in LPCWSTR lpString1, + static_cast<int>(sizeLhs), //__in int cchCount1, + rhs, //__in LPCWSTR lpString2, + static_cast<int>(sizeRhs), //__in int cchCount2, + true); //__in BOOL bIgnoreCase if (rv == 0) throw std::runtime_error("Error comparing strings (ordinal)!"); else @@ -124,26 +124,26 @@ int z_impl::compareFilenamesWin(const wchar_t* a, const wchar_t* b, size_t sizeA //do NOT use "CompareString"; this function is NOT accurate (even with LOCALE_INVARIANT and SORT_STRINGSORT): for example "weiß" == "weiss"!!! //the only reliable way to compare filenames (with XP) is to call "CharUpper" or "LCMapString": - const int minSize = std::min<int>(sizeA, sizeB); + const auto minSize = static_cast<unsigned int>(std::min(sizeLhs, sizeRhs)); int rv = 0; - if (minSize != 0) //LCMapString does not allow input sizes of 0! + if (minSize >= 0) //LCMapString does not allow input sizes of 0! { - if (minSize <= 5000) //performance optimization: stack + if (minSize <= MAX_PATH) //performance optimization: stack { - wchar_t bufferA[5000]; - wchar_t bufferB[5000]; + wchar_t bufferA[MAX_PATH]; + wchar_t bufferB[MAX_PATH]; //faster than CharUpperBuff + wmemcpy or CharUpper + wmemcpy and same speed like ::CompareString() if (::LCMapString(ZSTRING_INVARIANT_LOCALE, //__in LCID Locale, LCMAP_UPPERCASE, //__in DWORD dwMapFlags, - a, //__in LPCTSTR lpSrcStr, + lhs, //__in LPCTSTR lpSrcStr, minSize, //__in int cchSrc, bufferA, //__out LPTSTR lpDestStr, - 5000) == 0) //__in int cchDest + MAX_PATH) == 0) //__in int cchDest throw std::runtime_error("Error comparing strings! (LCMapString)"); - if (::LCMapString(ZSTRING_INVARIANT_LOCALE, LCMAP_UPPERCASE, b, minSize, bufferB, 5000) == 0) + if (::LCMapString(ZSTRING_INVARIANT_LOCALE, LCMAP_UPPERCASE, rhs, minSize, bufferB, MAX_PATH) == 0) throw std::runtime_error("Error comparing strings! (LCMapString)"); rv = ::wmemcmp(bufferA, bufferB, minSize); @@ -153,10 +153,10 @@ int z_impl::compareFilenamesWin(const wchar_t* a, const wchar_t* b, size_t sizeA std::vector<wchar_t> bufferA(minSize); std::vector<wchar_t> bufferB(minSize); - if (::LCMapString(ZSTRING_INVARIANT_LOCALE, LCMAP_UPPERCASE, a, minSize, &bufferA[0], minSize) == 0) + if (::LCMapString(ZSTRING_INVARIANT_LOCALE, LCMAP_UPPERCASE, lhs, minSize, &bufferA[0], minSize) == 0) throw std::runtime_error("Error comparing strings! (LCMapString: FS)"); - if (::LCMapString(ZSTRING_INVARIANT_LOCALE, LCMAP_UPPERCASE, b, minSize, &bufferB[0], minSize) == 0) + if (::LCMapString(ZSTRING_INVARIANT_LOCALE, LCMAP_UPPERCASE, rhs, minSize, &bufferB[0], minSize) == 0) throw std::runtime_error("Error comparing strings! (LCMapString: FS)"); rv = ::wmemcmp(&bufferA[0], &bufferB[0], minSize); @@ -164,7 +164,7 @@ int z_impl::compareFilenamesWin(const wchar_t* a, const wchar_t* b, size_t sizeA } return rv == 0 ? - static_cast<int>(sizeA) - static_cast<int>(sizeB) : + static_cast<int>(sizeLhs) - static_cast<int>(sizeRhs) : rv; } diff --git a/zen/zstring.h b/zen/zstring.h index a53c1bb0..cb6974e5 100644 --- a/zen/zstring.h +++ b/zen/zstring.h @@ -151,7 +151,7 @@ typedef zen::Zbase<Zchar, zen::StorageRefCountThreadSafe, AllocatorFreeStoreChec #if defined(FFS_WIN) || defined(FFS_LINUX) namespace z_impl { -int compareFilenamesWin(const wchar_t* a, const wchar_t* b, size_t sizeA, size_t sizeB); +int compareFilenamesWin(const wchar_t* lhs, const wchar_t* rhs, size_t sizeLhs, size_t sizeRhs); void makeUpperCaseWin(wchar_t* str, size_t size); } |