diff options
130 files changed, 8490 insertions, 7505 deletions
diff --git a/Application.cpp b/Application.cpp index 54258cd9..6581ba25 100644 --- a/Application.cpp +++ b/Application.cpp @@ -28,9 +28,6 @@ #elif defined ZEN_LINUX #include <gtk/gtk.h> - -#elif defined ZEN_MAC -#include <ApplicationServices/ApplicationServices.h> #endif using namespace zen; @@ -135,18 +132,13 @@ bool Application::OnInit() #elif defined ZEN_LINUX ::gtk_init(nullptr, nullptr); ::gtk_rc_parse((getResourceDir() + "styles.gtk_rc").c_str()); //remove inner border from bitmap buttons - -#elif defined ZEN_MAC - ProcessSerialNumber psn = { 0, kCurrentProcess }; - ::TransformProcessType(&psn, kProcessTransformToForegroundApplication); //behave like an application bundle, even when the app is not packaged (yet) #endif -#if wxCHECK_VERSION(2, 9, 1) #ifdef ZEN_WIN wxToolTip::SetMaxWidth(-1); //disable tooltip wrapping -> Windows only #endif - wxToolTip::SetAutoPop(7000); //tooltip visibilty in ms, 5s is default for Windows: http://msdn.microsoft.com/en-us/library/windows/desktop/aa511495.aspx -#endif + //Windows User Experience Interaction Guidelines: tool tips should have 5s timeout, info tips no timeout => compromise: + wxToolTip::SetAutoPop(7000); //http://msdn.microsoft.com/en-us/library/windows/desktop/aa511495.aspx SetAppName(L"FreeFileSync"); //if not set, the default is the executable's name! @@ -180,12 +172,10 @@ void Application::onEnterEventLoop(wxEvent& event) launch(commandArgs); } -warn_static("finish") - #ifdef ZEN_MAC /* -Initialization call sequences on OS X -------------------------------------- +wxWidgets initialization sequence on OS X is a mess: +---------------------------------------------------- 1. double click FFS app bundle or execute from command line without arguments OnInit() OnRun() @@ -204,27 +194,9 @@ Initialization call sequences on OS X MacOpenFiles() -> WTF!? onEnterEventLoop() MacNewFile() -> yes, wxWidgets screws up once again: http://trac.wxwidgets.org/ticket/14558 -*/ -void Application::MacOpenFiles(const wxArrayString& filenames) -{ - - // long wxExecute(const wxString& command, int sync = wxEXEC_ASYNC, wxProcess *callback = NULL) - // std::vector<wxString>(filenames.begin(), filenames.end()) - // startApplication(commandArgs); - - //if (!fileNames.empty()) - // wxMessageBox(fileNames[0]); - wxApp::MacOpenFiles(filenames); -} - - -void Application::MacNewFile() -{ - wxApp::MacNewFile(); -} - -//virtual void wxApp::MacReopenApp ( ) +=> solution: map Apple events to regular command line via launcher +*/ #endif @@ -286,6 +258,11 @@ void Application::launch(const std::vector<Zstring>& commandArgs) } catch (const FileError&) { assert(false); } //no messagebox: consider batch job! + auto notifyError = [&](const std::wstring& msg, const std::wstring& header) + { + wxMessageBox(msg.c_str(), L"FreeFileSync - " + header, wxOK | wxICON_ERROR); + raiseReturnCode(returnCode, FFS_RC_ABORTED); + }; //parse command line arguments std::vector<Zstring> leftDirs; @@ -311,7 +288,7 @@ void Application::launch(const std::vector<Zstring>& commandArgs) { if (++it == commandArgs.end()) { - wxMessageBox(replaceCpy(_("A directory path is expected after %x."), L"%x", utfCvrtTo<std::wstring>(optionLeftDir)), L"FreeFileSync - " + _("Syntax error"), wxOK | wxICON_ERROR); + notifyError(replaceCpy(_("A directory path is expected after %x."), L"%x", utfCvrtTo<std::wstring>(optionLeftDir)), _("Syntax error")); return; } leftDirs.push_back(*it); @@ -320,7 +297,7 @@ void Application::launch(const std::vector<Zstring>& commandArgs) { if (++it == commandArgs.end()) { - wxMessageBox(replaceCpy(_("A directory path is expected after %x."), L"%x", utfCvrtTo<std::wstring>(optionRightDir)), L"FreeFileSync - " + _("Syntax error"), wxOK | wxICON_ERROR); + notifyError(replaceCpy(_("A directory path is expected after %x."), L"%x", utfCvrtTo<std::wstring>(optionRightDir)), _("Syntax error")); return; } rightDirs.push_back(*it); @@ -336,7 +313,7 @@ void Application::launch(const std::vector<Zstring>& commandArgs) filename += Zstr(".ffs_gui"); else { - wxMessageBox(replaceCpy(_("Cannot open file %x."), L"%x", fmtFileName(filename)), L"FreeFileSync - " + _("Error"), wxOK | wxICON_ERROR); + notifyError(replaceCpy(_("Cannot open file %x."), L"%x", fmtFileName(filename)), _("Error")); return; } } @@ -345,7 +322,7 @@ void Application::launch(const std::vector<Zstring>& commandArgs) { case XML_TYPE_GLOBAL: case XML_TYPE_OTHER: - wxMessageBox(replaceCpy(_("File %x does not contain a valid configuration."), L"%x", fmtFileName(filename)), L"FreeFileSync - " + _("Error"), wxOK | wxICON_ERROR); + notifyError(replaceCpy(_("File %x does not contain a valid configuration."), L"%x", fmtFileName(filename)), _("Error")); return; case XML_TYPE_GUI: @@ -360,7 +337,7 @@ void Application::launch(const std::vector<Zstring>& commandArgs) if (leftDirs.size() != rightDirs.size()) { - wxMessageBox(_("Unequal number of left and right directories specified."), L"FreeFileSync - " + _("Syntax error"), wxOK | wxICON_ERROR); + notifyError(_("Unequal number of left and right directories specified."), _("Syntax error")); return; } @@ -378,7 +355,7 @@ void Application::launch(const std::vector<Zstring>& commandArgs) //check if config at folder-pair level is present: this probably doesn't make sense when replacing/adding the user-specified directories if (hasNonDefaultConfig(mainCfg.firstPair) || std::any_of(mainCfg.additionalPairs.begin(), mainCfg.additionalPairs.end(), hasNonDefaultConfig)) { - wxMessageBox(_("The config file must not contain settings at directory pair level when directories are set via command line."), L"FreeFileSync - " + _("Syntax error"), wxOK | wxICON_ERROR); + notifyError(_("The config file must not contain settings at directory pair level when directories are set via command line."), _("Syntax error")); return false; } @@ -428,8 +405,8 @@ void Application::launch(const std::vector<Zstring>& commandArgs) } catch (const xmlAccess::FfsXmlError& e) { - wxMessageBox(e.toString(), L"FreeFileSync - " + _("Error"), wxOK | wxICON_ERROR); //batch mode: break on errors AND even warnings! - raiseReturnCode(returnCode, FFS_RC_ABORTED); + //batch mode: break on errors AND even warnings! + notifyError(e.toString(), _("Error")); return; } if (!replaceDirectories(batchCfg.mainCfg)) return; @@ -450,7 +427,7 @@ void Application::launch(const std::vector<Zstring>& commandArgs) //what about simulating changed config on parsing errors???? else { - wxMessageBox(e.toString(), L"FreeFileSync - " + _("Error"), wxOK | wxICON_ERROR); + notifyError(e.toString(), _("Error")); return; } } @@ -466,7 +443,7 @@ void Application::launch(const std::vector<Zstring>& commandArgs) { if (!leftDirs.empty()) { - wxMessageBox(_("Directories cannot be set for more than one configuration file."), L"FreeFileSync - " + _("Syntax error"), wxOK | wxICON_ERROR); + notifyError(_("Directories cannot be set for more than one configuration file."), _("Syntax error")); return; } @@ -486,7 +463,7 @@ void Application::launch(const std::vector<Zstring>& commandArgs) //what about simulating changed config on parsing errors???? else { - wxMessageBox(e.toString(), L"FreeFileSync - " + _("Error"), wxOK | wxICON_ERROR); + notifyError(e.toString(), _("Error")); return; } } @@ -521,14 +498,14 @@ void showSyntaxHelp() void runBatchMode(const XmlBatchConfig& batchCfg, const Zstring& referenceFile, FfsReturnCode& returnCode) { - auto notifyError = [&](const std::wstring& msg) + auto notifyError = [&](const std::wstring& msg, FfsReturnCode rc) { if (batchCfg.handleError == ON_ERROR_POPUP) wxMessageBox(msg.c_str(), L"FreeFileSync - " + _("Error"), wxOK | wxICON_ERROR); else //"exit" or "ignore" logError(utfCvrtTo<std::string>(msg)); - raiseReturnCode(returnCode, FFS_RC_FINISHED_WITH_ERRORS); + raiseReturnCode(returnCode, rc); }; XmlGlobalSettings globalCfg; @@ -542,7 +519,7 @@ void runBatchMode(const XmlBatchConfig& batchCfg, const Zstring& referenceFile, { assert(false); if (e.getSeverity() != FfsXmlError::WARNING) //ignore parsing errors: should be migration problems only *cross-fingers* - return notifyError(e.toString()); //abort sync! + return notifyError(e.toString(), FFS_RC_ABORTED); //abort sync! } try @@ -551,7 +528,7 @@ void runBatchMode(const XmlBatchConfig& batchCfg, const Zstring& referenceFile, } catch (const FileError& e) { - notifyError(e.toString()); + notifyError(e.toString(), FFS_RC_FINISHED_WITH_WARNINGS); //continue! } @@ -590,7 +567,7 @@ void runBatchMode(const XmlBatchConfig& batchCfg, const Zstring& referenceFile, allowPwPrompt = true; break; case ON_ERROR_IGNORE: - case ON_ERROR_EXIT: + case ON_ERROR_ABORT: break; } @@ -633,6 +610,6 @@ void runBatchMode(const XmlBatchConfig& batchCfg, const Zstring& referenceFile, } catch (const xmlAccess::FfsXmlError& e) { - notifyError(e.toString()); + notifyError(e.toString(), FFS_RC_FINISHED_WITH_WARNINGS); } } diff --git a/Application.h b/Application.h index d915934b..b621a1a3 100644 --- a/Application.h +++ b/Application.h @@ -25,11 +25,6 @@ private: virtual int OnRun(); virtual bool OnExceptionInMainLoop() { throw; } //just re-throw and avoid display of additional messagebox: it will be caught in OnRun() -#ifdef ZEN_MAC - virtual void MacOpenFiles(const wxArrayString& filenames); - virtual void MacNewFile(); -#endif - void onEnterEventLoop(wxEvent& event); void onQueryEndSession(wxEvent& event); void launch(const std::vector<Zstring>& commandArgs); diff --git a/BUILD/Changelog.txt b/BUILD/Changelog.txt index d267dca0..8582e2b4 100644 --- a/BUILD/Changelog.txt +++ b/BUILD/Changelog.txt @@ -1,3 +1,30 @@ +FreeFileSync 5.21 +----------------- +Detect moved/renamed files in mirror and custom variants +New database format for two way variant: old database files are converted automatically +Support double-clicking ffs_gui/ffs_batch files (OS X) +Integrated search panel (Ctrl + F, F3) into main dialog +Merged variant names into top button labels +Hide dock icon while minimized to notification area (OS X) +New keyboard shortcuts: F5, F6, F7, F8, F9, F10 +Further reduced size of database files by 10% +Fixed Outlook *.ost files found missing on VSS snapshot volumes +Added include filter context menu option +Correctly scroll to search hits on different grid +Always remove .ffs_tmp files permanently +Fixed layout for buttons with text and graphics for RTL languages (Arabic, Hebrew) +Revised file filter parser: new syntax for excluding items in subdirectories +Improved configuration merge algorithm +Fixed crash when showing help due to wxWigets 64-bit bug in help component (Windows 8) +Avoid progress dialog graph flicker during resize when too few samples are available +Progress status when deleting files not greyed out anymore +Increased time-out to 20 seconds when checking for directory existence +Exclude broken symlinks via filter before showing error message +Follow symlinks when checking file/directory existence (Linux) +Consistently set batch error codes during startup phase +Updated translation files + + FreeFileSync 5.20 ----------------- Fixed crash on startup due to wxWigets 64-bit bug in font enumeration (Windows 8) diff --git a/BUILD/FreeFileSync.chm b/BUILD/FreeFileSync.chm Binary files differindex d6009619..5519353b 100644 --- a/BUILD/FreeFileSync.chm +++ b/BUILD/FreeFileSync.chm diff --git a/BUILD/Help/html/Exclude Items.html b/BUILD/Help/html/Exclude Items.html index 4ac0afaf..22d46b78 100644 --- a/BUILD/Help/html/Exclude Items.html +++ b/BUILD/Help/html/Exclude Items.html @@ -105,38 +105,39 @@ include list and <B>none</B> of the entries in the exclude list:</FONT></P> </TD> </TR> <TR> - <TD WIDTH=65% STYLE="border: none; padding: 0cm"> - <P ALIGN=LEFT STYLE="margin-left: 0.79cm"><FONT FACE="Tahoma, sans-serif">Multiple entries - separated by semicolon</FONT></P> + <TD WIDTH=65% STYLE="border-bottom: 1px solid #000000; padding: 0cm"> + <P ALIGN=LEFT STYLE="margin-left: 0.79cm"><FONT FACE="Tahoma, sans-serif">Multiple entries separated by semicolon</FONT></P> </TD> - <TD WIDTH=35% STYLE="border-top: none; border-bottom: none; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0cm; padding-left: 0.05cm; padding-right: 0cm"> + <TD WIDTH=35% STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0cm; padding-left: 0.05cm; padding-right: 0cm"> <P ALIGN=LEFT STYLE="margin-left: 0.79cm"><FONT FACE="Courier New, monospace">*.tmp; *.doc; *.bak</FONT></P> </TD> </TR> + + <TR> + <TD WIDTH=65% STYLE="border-bottom: 1px solid #000000; padding: 0cm"> + <P ALIGN=LEFT STYLE="margin-left: 0.79cm"><FONT FACE="Tahoma, sans-serif">Exclude all files and folders located in subdirectories of base directories</FONT></P> + </TD> + <TD WIDTH=35% STYLE="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0cm; padding-left: 0.05cm; padding-right: 0cm"> + <P ALIGN=LEFT STYLE="margin-left: 0.79cm"><FONT FACE="Courier New, monospace">\*\*</FONT></P> + </TD> + </TR> + <TR> + <TD WIDTH=65% STYLE="border: none; padding: 0cm"> + <P ALIGN=LEFT STYLE="margin-left: 0.79cm"><FONT FACE="Tahoma, sans-serif">Exclude only *.txt files +located in subdirectories of base directories</FONT></P> + </TD> + <TD WIDTH=35% STYLE="border-top: none; border-bottom: none; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0cm; padding-left: 0.05cm; padding-right: 0cm"> + <P ALIGN=LEFT STYLE="margin-left: 0.79cm"><FONT FACE="Courier New, monospace">\*\*.txt</FONT></P> + </TD> + </TR> + + </TABLE> </SPAN><BR CLEAR=LEFT><BR> </P> -<P STYLE="margin-bottom: 0cm"><BR> -</P> -<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Example:</B> -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%; border: none; padding: 0cm; background: #e6e6e6"> - <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-bottom: 0cm"> - <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"><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%; border: none; padding: 0cm; background: #e6e6e6"> - <P ALIGN=LEFT STYLE="margin-left: 0.79cm; 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"><BR> -</P> + + <P STYLE="margin-left: 1.32cm; margin-bottom: 0cm"><SPAN ID="Rahmen4" DIR="LTR" STYLE="float: left; width: 80%; border: 1px solid #000080; padding: 0.05cm; background: #ccccff"> <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Note</B></FONT></P> <LI><P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">For diff --git a/BUILD/Languages/arabic.lng b/BUILD/Languages/arabic.lng index 4d5bf07b..c97b927d 100644 --- a/BUILD/Languages/arabic.lng +++ b/BUILD/Languages/arabic.lng @@ -7,6 +7,171 @@ <plural_definition>n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5</plural_definition> </header> +<source>Unable to move %x to the recycle bin.</source> +<target></target> + +<source> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> +</source> +<target> +</target> + +<source>Log</source> +<target></target> + +<source>&Continue</source> +<target></target> + +<source>&Don't show this warning again</source> +<target></target> + +<source>&Ignore subsequent errors</source> +<target></target> + +<source>Comma-separated values</source> +<target></target> + +<source>Never save &changes</source> +<target></target> + +<source>Include via filter:</source> +<target></target> + +<source>&Execute</source> +<target></target> + +<source>Confirm</source> +<target></target> + +<source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +</target> + +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target></target> + +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target></target> + +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target></target> + +<source> +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. +</source> +<target></target> + +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target></target> + +<source>Move files to a user-defined folder</source> +<target></target> + +<source>Back up deleted and overwritten files in the recycle bin</source> +<target></target> + +<source>Recycle bin</source> +<target></target> + +<source>Requires database files. Not supported by all file systems.</source> +<target></target> + +<source>Detect moved files</source> +<target></target> + +<source>&Don't show this dialog again</source> +<target></target> + +<source>Minimize to notification area</source> +<target></target> + +<source>Retrying operation after error:</source> +<target></target> + +<source>job name</source> +<target></target> + +<source>Creating a Volume Shadow Copy for %x...</source> +<target></target> + +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target></target> + +<source>&Show error</source> +<target></target> + +<source>Waiting until all directories are available...</source> +<target></target> + +<source>Directory monitoring active</source> +<target></target> + +<source>Volume name %x is not part of file path %y.</source> +<target></target> + +<source>Cannot access the Volume Shadow Copy Service.</source> +<target></target> + +<source>%x items</source> +<target></target> + +<source> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> +</source> +<target> +</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target></target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target></target> + +<source>directory</source> +<target></target> + +<source>config files</source> +<target></target> + +<source>Syntax:</source> +<target></target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target></target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target></target> + +<source>Unequal number of left and right directories specified.</source> +<target></target> + +<source>Cannot open file %x.</source> +<target></target> + +<source>Syntax error</source> +<target></target> + +<source>A directory path is expected after %x.</source> +<target></target> + +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target></target> + +<source>Moving symbolic link %x to the recycle bin</source> +<target></target> + +<source>Moving folder %x to the recycle bin</source> +<target></target> + +<source>Moving file %x to the recycle bin</source> +<target></target> + <source>Both sides have changed since last synchronization.</source> <target>كلا الجانبين قد تغير منذ المزامنة الأخيرة.</target> @@ -25,15 +190,6 @@ <source>Checking recycle bin availability for folder %x...</source> <target>التØقق من تواÙر سلة المØذوÙات من أجل المجلد %x...</target> -<source>Moving file %x to recycle bin</source> -<target>نقل المل٠%x إلى سلة المØذوÙات</target> - -<source>Moving folder %x to recycle bin</source> -<target>نقل المجلد %x إلى سلة المØذوÙات</target> - -<source>Moving symbolic link %x to recycle bin</source> -<target>نقل الارتباط الرمزي %x إلى سلة المØذوÙات</target> - <source>Deleting file %x</source> <target>Øذ٠المل٠%x</target> @@ -43,21 +199,21 @@ <source>Deleting symbolic link %x</source> <target>Øذ٠الارتباط الرمزي %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>سلة المØذوÙات غير متاØØ© لهذه المجلدات. سيتم بدلاً عن ذلك Øذ٠الملÙات بشكل نهائي</target> - <source>An exception occurred</source> <target>Øدث استثناء</target> -<source>Cannot find file %x.</source> -<target>لا يمكن العثور على المل٠%x.</target> - <source>Error</source> <target>خطأ</target> <source>File %x does not contain a valid configuration.</source> <target>لا ÙŠØتوي المل٠%x تكويناً صØÙŠØاً.</target> +<source>Warning</source> +<target>تØذير</target> + +<source>Command line</source> +<target>سطر الأوامر</target> + <source>A folder input field is empty.</source> <target>Øقل إدخال خاص بمجلد Ùارغ.</target> @@ -218,19 +374,6 @@ <source>Total time:</source> <target>مجموع الوقت:</target> -<source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> -</source> -<target> -<pluralform>0 Bytes</pluralform> -<pluralform>1 Byte</pluralform> -<pluralform>2 Bytes</pluralform> -<pluralform>%x Bytes</pluralform> -<pluralform>%x Bytes</pluralform> -<pluralform>%x Bytes</pluralform> -</target> - <source>%x MB</source> <target>%x MB</target> @@ -280,9 +423,6 @@ <source>Browse directory</source> <target>تصÙØ Ø§Ù„Ù…Ø³Ø§Ø±</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>لا يمكن الوصول إلى خدمة "نسخ الظل لوØدة التخزين".</target> - <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>الرجاء استخدام إصدار الـ 64-bit للبرنامج لإنشاء ملÙات الظل الاØتياطية على هذا النظام.</target> @@ -292,9 +432,6 @@ <source>Cannot determine volume name for %x.</source> <target>تعذر تØديد اسم الوسط %x</target> -<source>Volume name %x not part of file name %y.</source> -<target>اسم ÙˆØدة التخزين %x ليس جزءا٠من اسم المل٠%y.</target> - <source>Abort requested: Waiting for current operation to finish...</source> <target>طلب Ø¥Øباط المهمة: ÙÙŠ انتظار انتهاء المهمة الØالية...</target> @@ -361,9 +498,6 @@ <source>Idle time between last detected change and execution of command</source> <target>وقت الخمول بين آخر تغيير تم الكش٠عنه وتنÙيذ الأوامر</target> -<source>Command line</source> -<target>سطر الأوامر</target> - <source> The command is triggered if: - files or subfolders change @@ -387,9 +521,6 @@ The command is triggered if: <source>RealtimeSync - Automated Synchronization</source> <target>المزامنة اللØظية - المزمنة التلقائية</target> -<source>Warning</source> -<target>تØذير</target> - <source>Build: %x</source> <target>بناء: %x</target> @@ -405,9 +536,6 @@ The command is triggered if: <source>&Exit</source> <target>&خروج</target> -<source>Waiting for missing directories...</source> -<target>ÙÙŠ انتظار المسارات المÙقود...</target> - <source>Invalid command line:</source> <target>سطر الأوامر غير صالØ:</target> @@ -417,14 +545,14 @@ The command is triggered if: <source>File time and size</source> <target>تاريخ المل٠و Øجمه</target> -<source> Two way </source> -<target> بالاتجاهين </target> +<source>Two way</source> +<target>بالاتجاهين</target> <source>Mirror</source> -<target>انعكاس </target> +<target>انعكاس</target> <source>Update</source> -<target>تØديث </target> +<target>تØديث</target> <source>Custom</source> <target>مخصص</target> @@ -480,12 +608,6 @@ The command is triggered if: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>العناصر التالية لم تØÙ„ اختلاÙاتها، Ùˆ لن يتم مزامنتها:</target> -<source>Significant difference detected:</source> -<target>تم الكش٠عن Ùرق كبير:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>أكثر من 50% من إجمالي عدد الملÙات سيتم نسخها أو ØØ°Ùها.</target> - <source>Not enough free disk space available in:</source> <target>المساØØ© الØرة المتوÙرة على القرص غير كاÙية:</target> @@ -504,9 +626,6 @@ The command is triggered if: <source>Generating database...</source> <target>إنشاء قاعدة بيانات...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>جاري إنشاء نسخة ظلية لـ %x...</target> - <source>Data verification error: %x and %y have different content.</source> <target>خطأ ÙÙŠ التØقق من البيانات: ÙŠØتوي %x Ùˆ %y بيانات مختلÙØ©.</target> @@ -657,8 +776,8 @@ The command is triggered if: <source>&Export file list...</source> <target>&تصدير قائمة الملÙات...</target> -<source>&Global settings...</source> -<target>&الإعدادات العامة...</target> +<source>&Global settings</source> +<target>&الإعدادات العامة</target> <source>&Tools</source> <target>&أدوات</target> @@ -738,6 +857,12 @@ The command is triggered if: <source>&Pause</source> <target>&إيقا٠مؤقت</target> +<source>Variant</source> +<target>المتغير</target> + +<source>Statistics</source> +<target>Ø¥Øصائيات</target> + <source>Select a variant</source> <target>اختيار بديل</target> @@ -810,27 +935,15 @@ is the same <source>Delete or overwrite files permanently</source> <target>Øذ٠أو الكتابة Ùوق الملÙات بشكل دائم</target> -<source>Recycle Bin</source> -<target>سلة المØذوÙات</target> - -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>استخدام سلة المØذوÙات للملÙات المØذوÙØ© Ùˆ الكتابة Ùوق الملÙات</target> - <source>Versioning</source> <target>الوسم برقم الإصدار</target> -<source>Move files to user-defined folder</source> -<target>نقل الملÙات إلى مجلد ÙŠØدده المستخدم</target> - <source>Naming convention:</source> <target>Ø§ØµØ·Ù„Ø§Ø Ø§Ù„ØªØ³Ù…ÙŠØ©:</target> <source>Batch job</source> <target>مهمة دÙعية</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>إنشاء مل٠دÙعي لتØويل المزامنةإلى تلقائية. بالنقر المزدوج على المل٠أو جدولته ضمن task planner الخاص بالنظام: FreeFileSync.exe <job name>.ffs_batch</target> - <source>Exit</source> <target>خروج</target> @@ -882,15 +995,6 @@ is the same <source>Delete on both sides even if the file is selected on one side only</source> <target>Øذ٠المل٠ÙÙŠ كلا الجانبين Øتى إذا كان المل٠مØدداً على جانب واØد Ùقط</target> -<source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. -</source> -<target> -سو٠تتم متزامنة Ùقط الملÙات التي تطابق كاÙØ© إعدادات عامل التصÙية. -ملاØظة: يجب أن تكون أسماء الملÙات منسوبة إلى بنية المسارات. -</target> - <source>Include</source> <target>شمول</target> @@ -918,21 +1022,12 @@ Note: File names must be relative to base directories. <source>Fail-safe file copy</source> <target>نسخ ملÙات آمن من الÙشل</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>الكتابة إلى مل٠مؤقت (*.ffs_tmp) أولاً، ثم إعادة تسميته. وهذا يضمن Øالة متناسقة Øتى ÙÙŠ Øالة Øدوث خطأ ÙادØ.</target> - <source>Copy locked files</source> <target>نسخ الملÙات المقÙلة</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>نسخ الملÙات المشاركة أو المقÙلة باستخدام "خدمة النسخ الاØتياطي لوØدة التخزين" (بØاجة لصلاØيات المدير)</target> - <source>Copy file access permissions</source> <target>نسخ أذونات الوصول إلى الملÙ</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>نقل أذونات الوصول إلى الملÙات Ùˆ المجلدات (بØاجة لصلاØيات المدير)</target> - <source>Restore hidden dialogs</source> <target>استعادة نواÙØ° الØوار المخÙية</target> @@ -945,15 +1040,6 @@ Note: File names must be relative to base directories. <source>&Default</source> <target>&الاÙتراضي</target> -<source>Variant</source> -<target>المتغير</target> - -<source>Statistics</source> -<target>Ø¥Øصائيات</target> - -<source>Don't show this dialog again</source> -<target>عدم إظهار ناÙذة الØوار هذه مرة أخرى</target> - <source>Find what:</source> <target>بØØ« عن:</target> @@ -963,15 +1049,15 @@ Note: File names must be relative to base directories. <source>&Find next</source> <target>&بØØ« عن التالي</target> +<source>Start synchronization</source> +<target>بدء المزامنة</target> + <source>Delete</source> <target>ØØ°Ù</target> <source>Configure filter</source> <target>ضبط عامل التصÙية</target> -<source>Start synchronization</source> -<target>بدء المزامنة</target> - <source>Find</source> <target>بØØ«</target> @@ -1053,12 +1139,12 @@ Note: File names must be relative to base directories. <source>Include temporarily</source> <target>شمول مؤقتاً</target> -<source>Exclude via filter:</source> -<target>استبعاد باستخدام عامل التصÙية:</target> - <source>multiple selection</source> <target>تØديد متعدد</target> +<source>Exclude via filter:</source> +<target>استبعاد باستخدام عامل التصÙية:</target> + <source>Include all</source> <target>شمول الكل</target> @@ -1104,9 +1190,6 @@ Note: File names must be relative to base directories. <source>Do&n't save</source> <target>&لا تØÙظ</target> -<source>Never save changes</source> -<target>لا تØÙظ التغييرات أبداً</target> - <source>Show files that exist on left side only</source> <target>إظهار الملÙات الموجودة ÙÙŠ الجانب الأيمن Ùقط</target> @@ -1158,27 +1241,18 @@ Note: File names must be relative to base directories. <source>All folders are in sync</source> <target>جميع المجلدات متزامنة</target> -<source>Comma separated list</source> -<target>قائمة Ù…Ùصولة بÙواصل</target> - <source>File list exported</source> <target>تم تصدير قائمة الملÙات</target> <source>Searching for program updates...</source> <target>جاري البØØ« عن تØديثات للبرنامج...</target> -<source>Ignore further errors</source> -<target>تجاهل أي أخطاء أخرى</target> - <source>&Ignore</source> <target>&تجاهل</target> <source>Fatal Error</source> <target>خطأ ÙادØ</target> -<source>Don't show this warning again</source> -<target>لا تظهر هذا التنبيه ثانية</target> - <source>&Switch</source> <target>&تبديل</target> @@ -1212,15 +1286,6 @@ Note: File names must be relative to base directories. <source>Completed</source> <target>تم الإنتهاء</target> -<source>Continue</source> -<target>مواصلة</target> - -<source>Pause</source> -<target>إيقا٠مؤقت</target> - -<source>Logging</source> -<target>التسجيل</target> - <source>Cannot find %x</source> <target>لا يمكن العثور على %x</target> @@ -1255,19 +1320,6 @@ Note: File names must be relative to base directories. <target>عامل التصÙية</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> -</source> -<target> -<pluralform>هل تريد Øقاً نقل 0 مل٠التالي إلى سلة المهملات ØŸ</pluralform> -<pluralform>هل تريد Øقاً نقل المل٠1 التالي إلى سلة المهملات ØŸ</pluralform> -<pluralform>هل تريد Øقاً نقل الملÙين 2 التاليين إلى سلة المهملات ØŸ</pluralform> -<pluralform>هل تريد Øقاً نقل الـ %x ملÙات التالية إلى سلة المهملات ØŸ</pluralform> -<pluralform>هل تريد Øقاً نقل الـ %x ملÙاً التالية إلى سلة المهملات ØŸ</pluralform> -<pluralform>هل تريد Øقاً نقل الـ %x مل٠التالية إلى سلة المهملات ØŸ</pluralform> -</target> - -<source> <pluralform>Do you really want to delete the following item?</pluralform> <pluralform>Do you really want to delete the following %x items?</pluralform> </source> @@ -1322,9 +1374,6 @@ Note: File names must be relative to base directories. <source>Append a timestamp to each file name</source> <target>إلØاق طابع زمني اسم كل ملÙ</target> -<source>Folder</source> -<target>مجلد</target> - <source>File</source> <target>ملÙ</target> @@ -1457,9 +1506,6 @@ Note: File names must be relative to base directories. <source>Cannot change process I/O priorities.</source> <target>تعذر تغيير أولويات I/O للعملية</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>تعذر نقل %x إلى سلة المØذوÙات.</target> - <source>Cannot determine final path for %x.</source> <target>تعذر تØديد المسار النهائي لـ %x.</target> diff --git a/BUILD/Languages/chinese_simple.lng b/BUILD/Languages/chinese_simple.lng index 754d0ca3..98c55320 100644 --- a/BUILD/Languages/chinese_simple.lng +++ b/BUILD/Languages/chinese_simple.lng @@ -25,14 +25,14 @@ <source>Checking recycle bin availability for folder %x...</source> <target>æ£åœ¨ä¸ºæ–‡ä»¶å¤¹ %x 检测回收站å¯ç”¨æ€§...</target> -<source>Moving file %x to recycle bin</source> -<target>æ£åœ¨ç§»åŠ¨æ–‡ä»¶ %x 到回收站</target> +<source>Moving file %x to the recycle bin</source> +<target>移动文件 %x 到回收站</target> -<source>Moving folder %x to recycle bin</source> -<target>æ£åœ¨ç§»åŠ¨æ–‡ä»¶å¤¹ %x 到回收站</target> +<source>Moving folder %x to the recycle bin</source> +<target>移动文件夹 %x 到回收站</target> -<source>Moving symbolic link %x to recycle bin</source> -<target>æ£åœ¨ç§»åŠ¨ç¬¦å·è¿žæŽ¥ %x 到回收站</target> +<source>Moving symbolic link %x to the recycle bin</source> +<target>移动符å·è¿žæŽ¥ %x 到回收站</target> <source>Deleting file %x</source> <target>æ£åˆ 除文件 %x</target> @@ -43,14 +43,20 @@ <source>Deleting symbolic link %x</source> <target>æ£åœ¨åˆ 除符å·è¿žæŽ¥ %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>å›žæ”¶ç«™å¯¹å¦‚ä¸‹æ–‡ä»¶å¤¹æ— æ•ˆ. æ–‡ä»¶å°†è¢«æ°¸ä¹…æ€§åˆ é™¤:</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>对于如下的文件夹回收站ä¸å¯ç”¨. æ–‡ä»¶å°†è¢«æ°¸ä¹…æ€§åˆ é™¤:</target> <source>An exception occurred</source> <target>å‘生异常</target> -<source>Cannot find file %x.</source> -<target>æ— æ³•æ‰¾åˆ°æ–‡ä»¶ %x .</target> +<source>A directory path is expected after %x.</source> +<target>在 %x 之åŽé¢„期是一个目录路径.</target> + +<source>Syntax error</source> +<target>è¯æ³•é”™è¯¯</target> + +<source>Cannot open file %x.</source> +<target>æ— æ³•æ‰“å¼€æ–‡ä»¶ %x.</target> <source>Error</source> <target>错误</target> @@ -58,6 +64,36 @@ <source>File %x does not contain a valid configuration.</source> <target>文件 %x 并未包å«åˆæ³•çš„é…ç½®.</target> +<source>Unequal number of left and right directories specified.</source> +<target>左边和å³è¾¹æŒ‡å®šäº†æ•°é‡ä¸ç›¸ç‰çš„目录.</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>当目录通过命令行设定时é…置文件必须ä¸åŒ…å«ç›®å½•å¯¹çº§åˆ«çš„设置.</target> + +<source>Warning</source> +<target>è¦å‘Š</target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target>æ— æ³•ä¸ºå¤šäºŽä¸€ä¸ªé…置文件设置目录.</target> + +<source>Syntax:</source> +<target>è¯æ³•:</target> + +<source>config files</source> +<target>é…置文件</target> + +<source>directory</source> +<target>目录</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>ä»»æ„æ•°é‡çš„ FreeFileSync .ffs_gui å’Œ/或 .ffs_batch é…置文件.</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>ä»»æ„æ•°é‡çš„替代目录ä¸è‡³å¤šæœ‰ä¸€ä¸ªé…置文件.</target> + +<source>Command line</source> +<target>命令行</target> + <source>A folder input field is empty.</source> <target>有一个文件夹输入框为空.</target> @@ -214,8 +250,8 @@ <target>总共时间:</target> <source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </source> <target> <pluralform>%x å—节</pluralform> @@ -240,11 +276,11 @@ <target>扫æä¸:</target> <source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </source> <target> -<pluralform>[%x 线程]</pluralform> +<pluralform>%x 线程</pluralform> </target> <source>Encoding extended time information: %x</source> @@ -253,6 +289,9 @@ <source>/sec</source> <target>/秒</target> +<source>%x items</source> +<target>%x 个项目</target> + <source>Configuration file %x loaded partially only.</source> <target>é…置文件 %x åªæ˜¯éƒ¨åˆ†è½½å…¥.</target> @@ -265,7 +304,7 @@ <source>Browse directory</source> <target>æµè§ˆç›®å½•</target> -<source>Cannot access Volume Shadow Copy Service.</source> +<source>Cannot access the Volume Shadow Copy Service.</source> <target>æ— æ³•è®¿é—®å·å½±å¤åˆ¶æœåŠ¡.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> @@ -277,8 +316,8 @@ <source>Cannot determine volume name for %x.</source> <target>æ— æ³•ä¸º %x 确定å·å.</target> -<source>Volume name %x not part of file name %y.</source> -<target>å·å %x 并éžæ–‡ä»¶å %y 的一部分.</target> +<source>Volume name %x is not part of file path %y.</source> +<target>å·å %x ä¸æ˜¯æ–‡ä»¶è·¯å¾„ %y 的一部分.</target> <source>Abort requested: Waiting for current operation to finish...</source> <target>请求ä¸æ¢: æ£åœ¨ç‰å¾…当å‰æ“作完æˆ...</target> @@ -346,9 +385,6 @@ <source>Idle time between last detected change and execution of command</source> <target>最åŽæ£€æµ‹åˆ°æ”¹å˜å’Œå‘½ä»¤æ‰§è¡Œä¹‹é—´çš„空闲时间</target> -<source>Command line</source> -<target>命令行</target> - <source> The command is triggered if: - files or subfolders change @@ -372,9 +408,6 @@ The command is triggered if: <source>RealtimeSync - Automated Synchronization</source> <target>实时åŒæ¥ - 自动åŒæ¥</target> -<source>Warning</source> -<target>è¦å‘Š</target> - <source>Build: %x</source> <target>Build: %x</target> @@ -384,15 +417,21 @@ The command is triggered if: <source>All files</source> <target>所有文件</target> +<source>Directory monitoring active</source> +<target>目录监视激活</target> + +<source>Waiting until all directories are available...</source> +<target>æ£åœ¨ç‰å¾…直到所有目录都å¯ç”¨...</target> + <source>&Restore</source> <target>æ¢å¤(&R)</target> +<source>&Show error</source> +<target>显示错误(&S)</target> + <source>&Exit</source> <target>退出(&E)</target> -<source>Waiting for missing directories...</source> -<target>æ£åœ¨ç‰å¾…丢失的目录...</target> - <source>Invalid command line:</source> <target>æ— æ•ˆçš„å‘½ä»¤è¡Œ:</target> @@ -402,14 +441,14 @@ The command is triggered if: <source>File time and size</source> <target>文件时间和大å°</target> -<source> Two way </source> +<source>Two way</source> <target>åŒå‘</target> <source>Mirror</source> -<target>é•œåƒ </target> +<target>é•œåƒ</target> <source>Update</source> -<target>æ›´æ–° </target> +<target>æ›´æ–°</target> <source>Custom</source> <target>自定义</target> @@ -465,11 +504,8 @@ The command is triggered if: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>å¦‚ä¸‹é¡¹ç›®æœ‰æ— æ³•è§£å†³çš„å†²çªå¹¶å°†ä¸ä¼šè¢«åŒæ¥:</target> -<source>Significant difference detected:</source> -<target>已侦测到显著ä¸åŒ:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>超过总数 50% 以上的文件è¦è¢«å¤åˆ¶æˆ–åˆ é™¤.</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>如下的文件夹有显著的ä¸åŒ. è¯·ç¡®è®¤ä½ ä¸ºåŒæ¥é…对了æ£ç¡®çš„文件夹.</target> <source>Not enough free disk space available in:</source> <target>没有足够的å¯ç”¨ç£ç›˜ç©ºé—´ç”¨äºŽ:</target> @@ -489,12 +525,15 @@ The command is triggered if: <source>Generating database...</source> <target>æ£åœ¨ç”Ÿæˆæ•°æ®åº“...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>æ£åœ¨ä¸º %x 创建å·å½±å“å¤åˆ¶...</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>为 %x 创建一个å·å½±å‰¯æœ¬...</target> <source>Data verification error: %x and %y have different content.</source> <target>æ•°æ®æ ¡éªŒé”™è¯¯: %x å’Œ %y 有ä¸åŒçš„内容.</target> +<source>job name</source> +<target>作业å称</target> + <source>Synchronization aborted</source> <target>åŒæ¥å·²è¢«ä¸æ¢</target> @@ -519,6 +558,9 @@ The command is triggered if: <source>Switching to FreeFileSync main dialog</source> <target>æ£åœ¨åˆ‡æ¢åˆ° FreeFileSync 主对è¯æ¡†</target> +<source>Retrying operation after error:</source> +<target>å‘生错误åŽé‡è¯•æ“作:</target> + <source>A new version of FreeFileSync is available:</source> <target>å·²ç»æœ‰æ–°ç‰ˆæœ¬çš„FreeFileSyncå¯ç”¨:</target> @@ -642,8 +684,8 @@ The command is triggered if: <source>&Export file list...</source> <target>导出文件列表(&E)...</target> -<source>&Global settings...</source> -<target>全局设置(&G)...</target> +<source>&Global settings</source> +<target>全局设置(&G)</target> <source>&Tools</source> <target>工具(&T)</target> @@ -714,6 +756,9 @@ The command is triggered if: <source>Synchronizing...</source> <target>åŒæ¥ä¸...</target> +<source>Minimize to notification area</source> +<target>最å°åŒ–到托盘</target> + <source>On completion</source> <target>在完æˆæ—¶</target> @@ -723,6 +768,15 @@ The command is triggered if: <source>&Pause</source> <target>æš‚åœ(&P)</target> +<source>Variant</source> +<target>å˜åŒ–</target> + +<source>Statistics</source> +<target>统计</target> + +<source>&Don't show this dialog again</source> +<target>ä¸è¦å†æ˜¾ç¤ºè¿™ä¸ªå¯¹è¯æ¡†(&D)</target> + <source>Select a variant</source> <target>选择一个å˜åŒ–</target> @@ -771,6 +825,12 @@ is the same <source>Configure your own synchronization rules.</source> <target>é…ç½®ä½ è‡ªå·±çš„åŒæ¥è§„则.</target> +<source>Detect moved files</source> +<target>检测被移动的文件</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>需è¦æ•°æ®åº“文件. ä¸æ˜¯æ‰€æœ‰æ–‡ä»¶ç³»ç»Ÿéƒ½æ”¯æŒ.</target> + <source>Error handling</source> <target>错误处ç†</target> @@ -795,17 +855,17 @@ is the same <source>Delete or overwrite files permanently</source> <target>æ°¸ä¹…æ€§åˆ é™¤æˆ–è¦†ç›–æ–‡ä»¶</target> -<source>Recycle Bin</source> +<source>Recycle bin</source> <target>回收站</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>å°†åˆ é™¤å’Œè¦†ç›–æ–‡ä»¶æ”¾åˆ°å›žæ”¶ç«™</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>å¤‡ä»½è¢«åˆ é™¤å’Œè¢«è¦†ç›–çš„æ–‡ä»¶åˆ°å›žæ”¶ç«™</target> <source>Versioning</source> <target>ä¿ç•™åŽ†å²ç‰ˆæœ¬</target> -<source>Move files to user-defined folder</source> -<target>移动文件至用户定义文件夹</target> +<source>Move files to a user-defined folder</source> +<target>移动文件到一个用户定义的文件夹</target> <source>Naming convention:</source> <target>命å规则:</target> @@ -813,8 +873,8 @@ is the same <source>Batch job</source> <target>批处ç†ä½œä¸š</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>创建一个用于自动åŒæ¥çš„批处ç†æ–‡ä»¶. åŒå‡»è¿™ä¸ªæ–‡ä»¶æˆ–è€…åœ¨ä½ çš„ç³»ç»Ÿçš„ä»»åŠ¡è®¡åˆ’ä¸å®šæ—¶æ‰§è¡Œ: FreeFileSync.exe <作业å>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>åˆ›å»ºä¸€ä¸ªç”¨äºŽæ— äººå€¼å®ˆåŒæ¥çš„批处ç†æ–‡ä»¶. è¦å¼€å§‹, åŒå‡»è¿™ä¸ªæ–‡ä»¶æˆ–任务计划器ä¸çš„计划调度: %x</target> <source>Exit</source> <target>退出</target> @@ -868,12 +928,12 @@ is the same <target>ä»Žä¸¤ä¾§åˆ é™¤(å³ä½¿ä»…在一侧选择文件)</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -åªæœ‰åŒ¹é…所有过滤器的文件会被åŒæ¥. -注:文件å必须是主目录的相对路径. +文件仅仅在它们通过了所有的过滤器规则时æ‰ä¼šè¢«åŒæ¥. +备注: 文件路径必须是主目录的相对路径. </target> <source>Include</source> @@ -903,20 +963,20 @@ Note: File names must be relative to base directories. <source>Fail-safe file copy</source> <target>æ— é£Žé™©çš„æ–‡ä»¶å¤åˆ¶</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>首先写入到一个临时文件(*.ffs_tmp)然åŽå†é‡å‘½å. è¿™æ ·å³ä½¿å‡ºçŽ°è‡´å‘½é”™è¯¯ä¹Ÿèƒ½ä¿æŒä¸€è‡´çš„状æ€.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>å…ˆå¤åˆ¶åˆ°ä¸€ä¸ªä¸´æ—¶æ–‡ä»¶(*.ffs_tmp)然åŽå†æ”¹å. è¿™ä¿è¯äº†å³ä½¿æ˜¯åœ¨å‘生致使错误的情况下也有一致的状æ€.</target> <source>Copy locked files</source> <target>å¤åˆ¶è¢«é”定的文件</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>通过å·å½±å¤åˆ¶æœåŠ¡å¤åˆ¶å…±äº«æˆ–é”定的文件(需è¦ç®¡ç†å‘˜æƒé™)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>使用å·å½±å¤åˆ¶æœåŠ¡æ¥å¤åˆ¶å·²å…±äº«æˆ–å·²é”定的文件(需è¦ç®¡ç†å‘˜æƒé™)</target> <source>Copy file access permissions</source> <target>å¤åˆ¶æ–‡ä»¶å˜å–æƒé™</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>ä¼ è¾“æ–‡ä»¶å’Œæ–‡ä»¶å¤¹çš„æƒé™(需è¦ç®¡ç†å‘˜æƒé™)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>ä¼ è¾“æ–‡ä»¶å’Œæ–‡ä»¶å¤¹æƒé™(需è¦ç®¡ç†å‘˜æƒé™)</target> <source>Restore hidden dialogs</source> <target>æ¢å¤è¢«éšè—的对è¯æ¡†</target> @@ -930,15 +990,6 @@ Note: File names must be relative to base directories. <source>&Default</source> <target>默认(&D)</target> -<source>Variant</source> -<target>å˜åŒ–</target> - -<source>Statistics</source> -<target>统计</target> - -<source>Don't show this dialog again</source> -<target>ä¸è¦å†æ˜¾ç¤ºè¿™ä¸ªå¯¹è¯æ¡†</target> - <source>Find what:</source> <target>è¦æŸ¥æ‰¾ä»€ä¹ˆ:</target> @@ -948,15 +999,15 @@ Note: File names must be relative to base directories. <source>&Find next</source> <target>查找下一个(&F)</target> +<source>Start synchronization</source> +<target>开始åŒæ¥</target> + <source>Delete</source> <target>åˆ é™¤</target> <source>Configure filter</source> <target>é…置过滤器</target> -<source>Start synchronization</source> -<target>开始åŒæ¥</target> - <source>Find</source> <target>查找</target> @@ -991,6 +1042,20 @@ Note: File names must be relative to base directories. <target>比较两侧</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>ä½ æ˜¯å¦çœŸçš„è¦å¯¹ %x 个项目执行命令 %y?</pluralform> +</target> + +<source>Confirm</source> +<target>确认</target> + +<source>&Execute</source> +<target>排除(&E)</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1023,12 +1088,15 @@ Note: File names must be relative to base directories. <source>Include temporarily</source> <target>暂时包括</target> -<source>Exclude via filter:</source> -<target>通过过滤器排除:</target> - <source>multiple selection</source> <target>多选</target> +<source>Include via filter:</source> +<target>通过过滤器包括:</target> + +<source>Exclude via filter:</source> +<target>通过过滤器排除:</target> + <source>Include all</source> <target>包括所有</target> @@ -1074,8 +1142,8 @@ Note: File names must be relative to base directories. <source>Do&n't save</source> <target>ä¸ä¿å˜(&N)</target> -<source>Never save changes</source> -<target>æ°¸ä¸ä¿å˜æ›´æ”¹</target> +<source>Never save &changes</source> +<target>ä¸å†ä¿å˜æ›´æ”¹(&C)</target> <source>Show files that exist on left side only</source> <target>显示仅å˜åœ¨å·¦ä¾§çš„文件</target> @@ -1128,8 +1196,8 @@ Note: File names must be relative to base directories. <source>All folders are in sync</source> <target>所有文件夹都是åŒæ¥çš„</target> -<source>Comma separated list</source> -<target>逗å·åˆ†éš”的列表</target> +<source>Comma-separated values</source> +<target>逗å·åˆ†å‰²çš„数值(CSV)</target> <source>File list exported</source> <target>文件清å•å·²ç»å¯¼å‡º</target> @@ -1137,8 +1205,8 @@ Note: File names must be relative to base directories. <source>Searching for program updates...</source> <target>æ£åœ¨æœç´¢ç¨‹åºçš„æ›´æ–°...</target> -<source>Ignore further errors</source> -<target>忽略之åŽå‡ºçŽ°çš„错误</target> +<source>&Ignore subsequent errors</source> +<target>忽略åŽç»çš„错误(&I)</target> <source>&Ignore</source> <target>忽略(&I)</target> @@ -1146,8 +1214,8 @@ Note: File names must be relative to base directories. <source>Fatal Error</source> <target>致命错误</target> -<source>Don't show this warning again</source> -<target>ä¸è¦å†æ˜¾ç¤ºè¿™ä¸ªè¦å‘Š</target> +<source>&Don't show this warning again</source> +<target>ä¸å†æ˜¾ç¤ºè¿™ä¸ªè¦å‘Š(&D)</target> <source>&Switch</source> <target>切æ¢(&S)</target> @@ -1182,14 +1250,11 @@ Note: File names must be relative to base directories. <source>Completed</source> <target>完æˆ</target> -<source>Continue</source> -<target>继ç»</target> +<source>&Continue</source> +<target>继ç»(&C)</target> -<source>Pause</source> -<target>æš‚åœ</target> - -<source>Logging</source> -<target>记录</target> +<source>Log</source> +<target>日志</target> <source>Cannot find %x</source> <target>找ä¸åˆ° %x</target> @@ -1225,11 +1290,11 @@ Note: File names must be relative to base directories. <target>过滤器</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>是å¦çœŸçš„è¦ç§»åŠ¨å¦‚下 %x 个项目到回收站?</pluralform> +<pluralform>ä½ æ˜¯å¦è¦å°†å¦‚下 %x 个项目移动到回收站?</pluralform> </target> <source> @@ -1282,9 +1347,6 @@ Note: File names must be relative to base directories. <source>Append a timestamp to each file name</source> <target>é™„åŠ æ—¶é—´æˆ³åˆ°æ¯ä¸€ä¸ªæ–‡ä»¶å</target> -<source>Folder</source> -<target>文件夹</target> - <source>File</source> <target>文件</target> @@ -1402,8 +1464,8 @@ Note: File names must be relative to base directories. <source>Cannot change process I/O priorities.</source> <target>æ— æ³•æ›´æ”¹è¿›ç¨‹çš„I/O优先级.</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>æ— æ³•ç§»åŠ¨ %x 到回收站.</target> +<source>Unable to move %x to the recycle bin.</source> +<target>æ— æ³•å°† %x 移动到回收站.</target> <source>Cannot determine final path for %x.</source> <target>æ— æ³•ç¡®å®š %x 的最终路径.</target> diff --git a/BUILD/Languages/chinese_traditional.lng b/BUILD/Languages/chinese_traditional.lng index f735db65..9b93446e 100644 --- a/BUILD/Languages/chinese_traditional.lng +++ b/BUILD/Languages/chinese_traditional.lng @@ -7,6 +7,9 @@ <plural_definition>0</plural_definition> </header> +<source>Close search bar</source> +<target></target> + <source>Both sides have changed since last synchronization.</source> <target>自上次åŒæ¥å¾Œï¼Œå…©é‚Šå‡å·²è®Šæ›´éŽã€‚</target> @@ -25,13 +28,13 @@ <source>Checking recycle bin availability for folder %x...</source> <target>æ£åœ¨æª¢æŸ¥è³‡æºå›žæ”¶ç’çš„å¯ç”¨æ€§è³‡æ–™å¤¾ %x...</target> -<source>Moving file %x to recycle bin</source> +<source>Moving file %x to the recycle bin</source> <target>æ£åœ¨ç§»å‹•æª”案 %x 到資æºå›žæ”¶ç’</target> -<source>Moving folder %x to recycle bin</source> +<source>Moving folder %x to the recycle bin</source> <target>æ£åœ¨ç§»å‹•è³‡æ–™å¤¾ %x 到資æºå›žæ”¶ç’</target> -<source>Moving symbolic link %x to recycle bin</source> +<source>Moving symbolic link %x to the recycle bin</source> <target>æ£åœ¨ç§»å‹•ç¬¦è™Ÿé€£çµ %x 到資æºå›žæ”¶ç’</target> <source>Deleting file %x</source> @@ -43,14 +46,20 @@ <source>Deleting symbolic link %x</source> <target>æ£åœ¨åˆªé™¤ç¬¦è™Ÿé€£çµ %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>資æºå›žæ”¶ç’ä¸å¯ç”¨æ–¼ä»¥ä¸‹è³‡æ–™å¤¾ï¼å¦å‰‡æª”案將改為永久被刪除:</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>資æºå›žæ”¶ç’ä¸å¯ç”¨æ–¼ä»¥ä¸‹è³‡æ–™å¤¾ã€‚檔案將被永久刪除替代:</target> <source>An exception occurred</source> <target>發生異常</target> -<source>Cannot find file %x.</source> -<target>找ä¸åˆ°æª”案 %x。</target> +<source>A directory path is expected after %x.</source> +<target>%x 後é 期的目錄路徑。</target> + +<source>Syntax error</source> +<target>語法錯誤</target> + +<source>Cannot open file %x.</source> +<target>無法開啟檔案 %x。</target> <source>Error</source> <target>錯誤</target> @@ -58,6 +67,36 @@ <source>File %x does not contain a valid configuration.</source> <target>檔案 %x ä¸åŒ…å«ä¸€å€‹æœ‰æ•ˆçš„é…置。</target> +<source>Unequal number of left and right directories specified.</source> +<target>左邊和å³é‚ŠæŒ‡å®šçš„目錄數ä¸ç›¸ç‰ã€‚</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>目錄è¨å®šé€éŽå‘½ä»¤åˆ—時,該è¨å®šæª”å¿…é ˆä¸åŒ…å«é…å°ç›®éŒ„級別的è¨å®šã€‚</target> + +<source>Warning</source> +<target>è¦å‘Š</target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target>目錄無法è¨å®šå¤šå€‹é…置檔。</target> + +<source>Syntax:</source> +<target>語法:</target> + +<source>config files</source> +<target>é…置檔案</target> + +<source>directory</source> +<target>目錄</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>FreeFileSync .ffs_guiå’Œ/或.ffs_batché…置檔案的任æ„數é‡ã€‚</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>替代目錄的任æ„數é‡ä¸æœ€å¤šæœ‰ä¸€å€‹é…置文件。</target> + +<source>Command line</source> +<target>命令列</target> + <source>A folder input field is empty.</source> <target>資料夾輸入欄ä½æ˜¯ç©ºçš„。</target> @@ -214,11 +253,11 @@ <target>全部時間:</target> <source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </source> <target> -<pluralform>%x ä½å…ƒçµ„</pluralform> +<pluralform>%x 個ä½å…ƒçµ„</pluralform> </target> <source>%x MB</source> @@ -240,11 +279,11 @@ <target>æ£åœ¨æŽƒçž„:</target> <source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </source> <target> -<pluralform>[%x 個執行緒]</pluralform> +<pluralform>%x 個執行緒</pluralform> </target> <source>Encoding extended time information: %x</source> @@ -253,6 +292,9 @@ <source>/sec</source> <target>/秒</target> +<source>%x items</source> +<target>%x é …ç›®</target> + <source>Configuration file %x loaded partially only.</source> <target>åªè¼‰å…¥è¨å®šæª” %x 的一部份。</target> @@ -265,7 +307,7 @@ <source>Browse directory</source> <target>ç€è¦½ç›®éŒ„</target> -<source>Cannot access Volume Shadow Copy Service.</source> +<source>Cannot access the Volume Shadow Copy Service.</source> <target>無法讀å–å·å½±è¤‡è£½æœå‹™ã€‚</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> @@ -277,8 +319,8 @@ <source>Cannot determine volume name for %x.</source> <target>無法確定å·å為 %x。</target> -<source>Volume name %x not part of file name %y.</source> -<target>å·å %x 並éžæª”å %y 的一部份。</target> +<source>Volume name %x is not part of file path %y.</source> +<target>å·å %x ä¸æ˜¯æª”案路徑 %y 的一部分。</target> <source>Abort requested: Waiting for current operation to finish...</source> <target>ä¸æ¢è«‹æ±‚:æ£åœ¨ç‰å¾…ç›®å‰æ“作完æˆ...</target> @@ -346,9 +388,6 @@ <source>Idle time between last detected change and execution of command</source> <target>最後檢測到變更和執行命令之間的閒置時間</target> -<source>Command line</source> -<target>命令列</target> - <source> The command is triggered if: - files or subfolders change @@ -372,9 +411,6 @@ The command is triggered if: <source>RealtimeSync - Automated Synchronization</source> <target>å³æ™‚åŒæ¥ - 自動åŒæ¥</target> -<source>Warning</source> -<target>è¦å‘Š</target> - <source>Build: %x</source> <target>建立:%x</target> @@ -384,15 +420,21 @@ The command is triggered if: <source>All files</source> <target>所有檔案</target> +<source>Directory monitoring active</source> +<target>目錄監測啟動</target> + +<source>Waiting until all directories are available...</source> +<target>ç‰åˆ°æ‰€æœ‰ç›®éŒ„å¯ç”¨...</target> + <source>&Restore</source> <target>還原(&R)</target> +<source>&Show error</source> +<target>顯示錯誤(&S)</target> + <source>&Exit</source> <target>çµæŸ(&E)</target> -<source>Waiting for missing directories...</source> -<target>ç‰å¾…缺少的目錄...</target> - <source>Invalid command line:</source> <target>無效的命令列:</target> @@ -402,14 +444,14 @@ The command is triggered if: <source>File time and size</source> <target>檔案大å°å’Œæ—¥æœŸ</target> -<source> Two way </source> -<target> é›™å‘ </target> +<source>Two way</source> +<target>é›™å‘</target> <source>Mirror</source> -<target>é¡åƒ </target> +<target>é¡åƒ</target> <source>Update</source> -<target>æ›´æ–° </target> +<target>æ›´æ–°</target> <source>Custom</source> <target>自訂</target> @@ -465,11 +507,8 @@ The command is triggered if: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>ä¸‹åˆ—é …ç›®æœ‰æœªè§£æ±ºçš„è¡çªï¼Œå°‡ä¸æœƒåŒæ¥ï¼š</target> -<source>Significant difference detected:</source> -<target>檢測到顯著的差異:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>超éŽç¸½æ•¸ 50% 以上的檔案會被複製或刪除。</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>下列資料夾明顯ä¸åŒã€‚請確定è¦é€²è¡ŒåŒæ¥çš„資料夾匹é…æ£ç¢ºã€‚</target> <source>Not enough free disk space available in:</source> <target>æ²’æœ‰è¶³å¤ çš„å¯ç”¨ç©ºé–“:</target> @@ -489,12 +528,15 @@ The command is triggered if: <source>Generating database...</source> <target>æ£åœ¨ç”¢ç”Ÿè³‡æ–™åº«...</target> -<source>Creating Volume Shadow Copy for %x...</source> +<source>Creating a Volume Shadow Copy for %x...</source> <target>æ£åœ¨æ–°å»ºå·å½±è¤‡è£½ç‚º %x...</target> <source>Data verification error: %x and %y have different content.</source> <target>資料驗è‰éŒ¯èª¤ï¼š%x å’Œ %y 內容ä¸åŒï¼</target> +<source>job name</source> +<target>作æ¥å稱</target> + <source>Synchronization aborted</source> <target>åŒæ¥å·²ä¸æ¢</target> @@ -519,6 +561,9 @@ The command is triggered if: <source>Switching to FreeFileSync main dialog</source> <target>切æ›åˆ°FreeFileSync主å°è©±æ¡†</target> +<source>Retrying operation after error:</source> +<target>錯誤後é‡è©¦æ“作:</target> + <source>A new version of FreeFileSync is available:</source> <target>FreeFileSync有新版本å¯ç”¨ï¼š</target> @@ -642,8 +687,8 @@ The command is triggered if: <source>&Export file list...</source> <target>匯出檔案清單(&E)...</target> -<source>&Global settings...</source> -<target>æ•´é«”è¨å®š(&G)...</target> +<source>&Global settings</source> +<target>æ•´é«”è¨å®š(&G)</target> <source>&Tools</source> <target>工具(&T)</target> @@ -660,12 +705,6 @@ The command is triggered if: <source>Compare</source> <target>比å°</target> -<source>Comparison settings</source> -<target>比å°è¨å®š</target> - -<source>Synchronization settings</source> -<target>åŒæ¥è¨å®š</target> - <source>Synchronize</source> <target>åŒæ¥</target> @@ -678,6 +717,12 @@ The command is triggered if: <source>Swap sides</source> <target>兩邊交æ›</target> +<source>Find what:</source> +<target>尋找內容:</target> + +<source>Match case</source> +<target>å€åˆ†å¤§å°å¯«</target> + <source>Save as batch job</source> <target>å¦å˜ç‚ºæ‰¹æ¬¡è™•ç†ä½œæ¥</target> @@ -714,6 +759,9 @@ The command is triggered if: <source>Synchronizing...</source> <target>æ£åœ¨åŒæ¥...</target> +<source>Minimize to notification area</source> +<target>最å°åŒ–到通知å€åŸŸ</target> + <source>On completion</source> <target>完æˆå¾Œ</target> @@ -723,6 +771,15 @@ The command is triggered if: <source>&Pause</source> <target>æš«åœ(&P)</target> +<source>Variant</source> +<target>變數</target> + +<source>Statistics</source> +<target>統計</target> + +<source>&Don't show this dialog again</source> +<target>ä¸è¦å†é¡¯ç¤ºæ¤å°è©±æ¡†(&D)</target> + <source>Select a variant</source> <target>é¸æ“‡ä¸€å€‹è®Šæ•¸</target> @@ -762,6 +819,12 @@ is the same <source>Configure your own synchronization rules.</source> <target>é…ç½®ä½ è‡ªå·±çš„åŒæ¥è¦å‰‡ã€‚</target> +<source>Detect moved files</source> +<target>檢測被移動的檔案</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>需è¦è³‡æ–™åº«æª”案。ä¸æ”¯æ´æ‰€æœ‰æª”案系統。</target> + <source>Error handling</source> <target>錯誤處ç†</target> @@ -786,17 +849,17 @@ is the same <source>Delete or overwrite files permanently</source> <target>永久刪除或覆蓋檔案</target> -<source>Recycle Bin</source> +<source>Recycle bin</source> <target>資æºå›žæ”¶ç’</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>將刪除和覆蓋的檔案移動到資æºå›žæ”¶ç’</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>在資æºå›žæ”¶ç’ä¸åˆªé™¤å‚™ä»½å’Œè¦†è“‹æª”案</target> <source>Versioning</source> <target>版本控制</target> -<source>Move files to user-defined folder</source> -<target>將檔案移動到使用者自訂的資料夾</target> +<source>Move files to a user-defined folder</source> +<target>將檔案移動到一個使用者定義的資料夾</target> <source>Naming convention:</source> <target>命å慣例:</target> @@ -804,8 +867,8 @@ is the same <source>Batch job</source> <target>批次處ç†ä½œæ¥</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>新建一個批次檔來自動執行åŒæ¥ã€‚按兩下æ¤æª”案或安排在您的系統任務計畫表:FreeFileSync.exe <工作å稱>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>新建一個批次處ç†æª”,用於無人值守åŒæ¥ã€‚開始,點兩下æ¤æª”案,或安排在任務è¦åŠƒä¸ï¼š%x</target> <source>Exit</source> <target>çµæŸ</target> @@ -828,30 +891,6 @@ is the same <source>Limit maximum number of log files</source> <target>é™åˆ¶æ—¥èªŒæª”的最大數é‡</target> -<source>Source code written in C++ using:</source> -<target>使用C++編寫的原始碼</target> - -<source>If you like FreeFileSync</source> -<target>å¦‚æžœä½ å–œæ¡FreeFileSync</target> - -<source>Donate with PayPal</source> -<target>使用PayPalæ款</target> - -<source>Many thanks for localization:</source> -<target>éžå¸¸æ„Ÿè¬æœ¬åœ°åŒ–語系翻è¯å·¥ä½œäººå“¡ï¼š</target> - -<source>Feedback and suggestions are welcome</source> -<target>æ¡è¿Žå饋æ„見和建è°</target> - -<source>Homepage</source> -<target>首é </target> - -<source>Email</source> -<target>ä¿¡ç®±</target> - -<source>Published under the GNU General Public License</source> -<target>在GNU通用公共許å¯è‰ä¸‹ç™¼ä½ˆ</target> - <source>Delete on both sides</source> <target>兩邊都刪除</target> @@ -859,12 +898,12 @@ is the same <target>å³ä½¿åªåœ¨ä¸€é‚Šä¸é¸å¥½æª”案,還是會刪除兩邊檔案。</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -åªæœ‰ç¬¦åˆæ‰€æœ‰ç¯©é¸å™¨è¨å®šçš„檔案æ‰æœƒè¢«åŒæ¥ã€‚ -注æ„:檔åå¿…é ˆç›¸å°åˆ°åŸºæœ¬ç›®éŒ„。 +如果他們通éŽæ‰€æœ‰çš„éŽæ¿¾è¦å‰‡ï¼Œå°‡åªæœƒåŒæ¥æª”案。 +注æ„ï¼šæª”æ¡ˆè·¯å¾‘å¿…é ˆæ˜¯ç›¸å°æ–¼åŸºæœ¬ç›®éŒ„。 </target> <source>Include</source> @@ -894,20 +933,20 @@ Note: File names must be relative to base directories. <source>Fail-safe file copy</source> <target>æ•…éšœä¿è·æª”案複製</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>第一次將檔寫入到一個暫å˜(*.ffs_tmp)ï¼Œé †ä¾¿å°‡å®ƒå€‘é‡æ–°å‘½å。å³ä½¿åœ¨åš´é‡éŒ¯èª¤çš„情æ³ä¸‹ï¼Œé‚„å¯ç¢ºä¿ä¸€è‡´çš„狀態。</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>先複製到一個臨時檔案(*.ffs_tmp)然後將其é‡æ–°å‘½å。å³ä½¿ç™¼ç”Ÿè‡´å‘½éŒ¯èª¤æ™‚,還能確ä¿ä¸€è‡´çš„狀態。</target> <source>Copy locked files</source> <target>複製被鎖定的檔案</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>複製共用或鎖定檔案使用使用å·å½±è¤‡è£½æœå‹™(需è¦ç®¡ç†å“¡æ¬Šé™)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>共用的副本或鎖定的檔案使用å·å½±è¤‡è£½æœå‹™(需è¦ç®¡ç†å“¡æ¬Šé™)</target> <source>Copy file access permissions</source> <target>複製檔案系統權é™</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>傳輸檔案和資料夾權é™(需è¦ç®¡ç†å“¡æ¬Šé™)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>傳輸檔案和資料夾的權é™(需è¦ç®¡ç†å“¡æ¬Šé™)</target> <source>Restore hidden dialogs</source> <target>還原隱è—çš„å°è©±æ¡†</target> @@ -921,35 +960,44 @@ Note: File names must be relative to base directories. <source>&Default</source> <target>é è¨(&D)</target> -<source>Variant</source> -<target>變數</target> +<source>Source code written in C++ using:</source> +<target>使用C++編寫的原始碼</target> -<source>Statistics</source> -<target>統計</target> +<source>If you like FreeFileSync</source> +<target>å¦‚æžœä½ å–œæ¡FreeFileSync</target> -<source>Don't show this dialog again</source> -<target>ä¸å†é¡¯ç¤ºæ¤å°è©±æ¡†</target> +<source>Donate with PayPal</source> +<target>使用PayPalæ款</target> -<source>Find what:</source> -<target>尋找內容:</target> +<source>Feedback and suggestions are welcome</source> +<target>æ¡è¿Žå饋æ„見和建è°</target> -<source>Match case</source> -<target>å€åˆ†å¤§å°å¯«</target> +<source>Homepage</source> +<target>首é </target> -<source>&Find next</source> -<target>找下一個(&F)</target> +<source>Email</source> +<target>ä¿¡ç®±</target> -<source>Delete</source> -<target>刪除</target> +<source>Published under the GNU General Public License</source> +<target>在GNU通用公共許å¯è‰ä¸‹ç™¼ä½ˆ</target> -<source>Configure filter</source> -<target>é…置篩é¸</target> +<source>Many thanks for localization:</source> +<target>éžå¸¸æ„Ÿè¬æœ¬åœ°åŒ–語系翻è¯å·¥ä½œäººå“¡ï¼š</target> <source>Start synchronization</source> <target>開始åŒæ¥</target> -<source>Find</source> -<target>尋找</target> +<source>Comparison settings</source> +<target>比å°è¨å®š</target> + +<source>Synchronization settings</source> +<target>åŒæ¥è¨å®š</target> + +<source>Delete</source> +<target>刪除</target> + +<source>Configure filter</source> +<target>é…置篩é¸</target> <source>Select time span</source> <target>é¸æ“‡æ™‚é–“é–“éš”</target> @@ -957,6 +1005,9 @@ Note: File names must be relative to base directories. <source>Folder pairs</source> <target>é…å°è³‡æ–™å¤¾</target> +<source>Find</source> +<target>尋找</target> + <source>Overview</source> <target>摘è¦</target> @@ -982,6 +1033,20 @@ Note: File names must be relative to base directories. <target>比å°å…©é‚Š</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>ä½ çœŸçš„è¦åŸ·è¡Œ %x é …ç›®çš„å‘½ä»¤ %y 嗎?</pluralform> +</target> + +<source>Confirm</source> +<target>確èª</target> + +<source>&Execute</source> +<target>執行(&E)</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1008,17 +1073,20 @@ Note: File names must be relative to base directories. <source>Set direction:</source> <target>è¨å®šæ–¹å‘:</target> -<source>Exclude temporarily</source> -<target>暫時排除</target> +<source>multiple selection</source> +<target>多é‡é¸æ“‡</target> -<source>Include temporarily</source> -<target>暫時包括</target> +<source>Include via filter:</source> +<target>包括é€éŽç¯©é¸å™¨ï¼š</target> <source>Exclude via filter:</source> <target>使用篩é¸å™¨æŽ’除:</target> -<source>multiple selection</source> -<target>多é‡é¸æ“‡</target> +<source>Exclude temporarily</source> +<target>暫時排除</target> + +<source>Include temporarily</source> +<target>暫時包括</target> <source>Include all</source> <target>包括所有</target> @@ -1065,8 +1133,8 @@ Note: File names must be relative to base directories. <source>Do&n't save</source> <target>ä¸å„²å˜(&N)</target> -<source>Never save changes</source> -<target>ä¸è¦å„²å˜è®Šæ›´</target> +<source>Never save &changes</source> +<target>從ä¸ä¿å˜æ›´æ”¹(&c)</target> <source>Show files that exist on left side only</source> <target>顯示åªå˜åœ¨æ–¼å·¦é‚Šçš„檔案</target> @@ -1119,8 +1187,11 @@ Note: File names must be relative to base directories. <source>All folders are in sync</source> <target>所有資料夾都是åŒæ¥çš„</target> -<source>Comma separated list</source> -<target>逗號分隔清單</target> +<source>Cannot find %x</source> +<target>找ä¸åˆ° %x</target> + +<source>Comma-separated values</source> +<target>以逗號分隔值</target> <source>File list exported</source> <target>檔案清單已匯出</target> @@ -1128,8 +1199,8 @@ Note: File names must be relative to base directories. <source>Searching for program updates...</source> <target>æ£åœ¨æœå°‹ç¨‹å¼æ›´æ–°...</target> -<source>Ignore further errors</source> -<target>忽略進一æ¥éŒ¯èª¤</target> +<source>&Ignore subsequent errors</source> +<target>忽略後續的錯誤(&I)</target> <source>&Ignore</source> <target>忽略(&I)</target> @@ -1137,8 +1208,8 @@ Note: File names must be relative to base directories. <source>Fatal Error</source> <target>åš´é‡éŒ¯èª¤</target> -<source>Don't show this warning again</source> -<target>ä¸å†é¡¯ç¤ºæ¤è¦å‘Š</target> +<source>&Don't show this warning again</source> +<target>ä¸è¦å†é¡¯ç¤ºæ¤è¦å‘Š(&D)</target> <source>&Switch</source> <target>切æ›(&S)</target> @@ -1173,17 +1244,11 @@ Note: File names must be relative to base directories. <source>Completed</source> <target>已完æˆ</target> -<source>Continue</source> -<target>繼續</target> - -<source>Pause</source> -<target>æš«åœ</target> +<source>&Continue</source> +<target>繼續(&C)</target> -<source>Logging</source> -<target>日誌記錄</target> - -<source>Cannot find %x</source> -<target>找ä¸åˆ° %x</target> +<source>Log</source> +<target>日誌</target> <source>Inactive</source> <target>åœç”¨</target> @@ -1216,11 +1281,11 @@ Note: File names must be relative to base directories. <target>篩é¸å™¨</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>您確定è¦å°‡ä¸‹åˆ— %x é …ç›®ç§»å‹•åˆ°è³‡æºå›žæ”¶ç’嗎?</pluralform> +<pluralform>ä½ çœŸçš„è¦å°‡ä»¥ä¸‹é …ç›® %x 移動到資æºå›žæ”¶ç’嗎?</pluralform> </target> <source> @@ -1228,7 +1293,7 @@ Note: File names must be relative to base directories. <pluralform>Do you really want to delete the following %x items?</pluralform> </source> <target> -<pluralform>您確定è¦å°‡ä¸‹åˆ— %x é …ç›®åˆªé™¤å—Žï¼Ÿ</pluralform> +<pluralform>您真的è¦å°‡ä¸‹åˆ— %x é …ç›®åˆªé™¤å—Žï¼Ÿ</pluralform> </target> <source>Direct</source> @@ -1273,9 +1338,6 @@ Note: File names must be relative to base directories. <source>Append a timestamp to each file name</source> <target>å°‡æ™‚é–“æˆ³è¨˜é™„åŠ åˆ°æ¯å€‹æª”案å稱上</target> -<source>Folder</source> -<target>資料夾</target> - <source>File</source> <target>檔案</target> @@ -1393,7 +1455,7 @@ Note: File names must be relative to base directories. <source>Cannot change process I/O priorities.</source> <target>無法更改I/O處ç†å„ªå…ˆé †åºã€‚</target> -<source>Unable to move %x to the Recycle Bin.</source> +<source>Unable to move %x to the recycle bin.</source> <target>無法將 %x 移動到資æºå›žæ”¶ç’。</target> <source>Cannot determine final path for %x.</source> diff --git a/BUILD/Languages/croatian.lng b/BUILD/Languages/croatian.lng index 8407fe7f..1db53365 100644 --- a/BUILD/Languages/croatian.lng +++ b/BUILD/Languages/croatian.lng @@ -7,6 +7,9 @@ <plural_definition>n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2</plural_definition> </header> +<source>Close search bar</source> +<target></target> + <source>Both sides have changed since last synchronization.</source> <target>Obje su strane promjenjene od posljednje sinkronizacije.</target> @@ -25,14 +28,14 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Provjeravam dosupnost koÅ¡a za smeće za mapu %x...</target> -<source>Moving file %x to recycle bin</source> -<target>PremjeÅ¡tam datoteku %x u KoÅ¡ za smeće</target> +<source>Moving file %x to the recycle bin</source> +<target>PremjeÅ¡tam datoteku %x u koÅ¡</target> -<source>Moving folder %x to recycle bin</source> -<target>PremjeÅ¡tam mapu %x u KoÅ¡ za smeće</target> +<source>Moving folder %x to the recycle bin</source> +<target>PremjeÅ¡tam datoteku %x u koÅ¡</target> -<source>Moving symbolic link %x to recycle bin</source> -<target>PremjeÅ¡tam simboliÄnu poveznicu %x u KoÅ¡ za smeće</target> +<source>Moving symbolic link %x to the recycle bin</source> +<target>PremjeÅ¡tam simobliÄnu opveznicu %x u koÅ¡</target> <source>Deleting file %x</source> <target>Brisanje datoteke %x</target> @@ -43,8 +46,8 @@ <source>Deleting symbolic link %x</source> <target>Brisanje simboliÄnih poveznica %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>KoÅ¡ nije dostupan za sljedeće mape. Datoteke će biti nepovratno izbrisane:</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>KoÅ¡ nije dosuutpan za sljedeće mape. Zbog toga će datoteke biti trajno obrisane:</target> <source>An exception occurred</source> <target>Dogodilo se izuzeće</target> @@ -310,8 +313,8 @@ <source>Browse directory</source> <target>Odaberi direktorij</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Ne mogu pristupiti Volume Shadow Copy Servisu</target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target>Ne mogu pristupiti Voulme Shadow Copy servisu.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>Molimo koristite FreeFileSync 64-bitnu verziju za izradu shadow kopija na ovom sustavu</target> @@ -531,12 +534,15 @@ Naredba će biti pokrenuta ako se: <source>Generating database...</source> <target>IzraÄ‘ujem bazu podataka...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>IzraÄ‘ujem Volume Shadow Kopiju za %x...</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>Lreiram Volume Shadow Copy za %x...</target> <source>Data verification error: %x and %y have different content.</source> <target>GreÅ¡ka pri provjeri podataka: %x i %y imaju razliÄit sadržaj.</target> +<source>job name</source> +<target>Ime zadatka</target> + <source>Synchronization aborted</source> <target>Sinkronizacija prekinuta</target> @@ -687,8 +693,8 @@ Naredba će biti pokrenuta ako se: <source>&Export file list...</source> <target>&Izvoz liste datoteka...</target> -<source>&Global settings...</source> -<target>&Globalne postavke...</target> +<source>&Global settings</source> +<target>&Globalne postavke</target> <source>&Tools</source> <target>&Alati</target> @@ -705,12 +711,6 @@ Naredba će biti pokrenuta ako se: <source>Compare</source> <target>Usporedi</target> -<source>Comparison settings</source> -<target>Postavke usporedbe</target> - -<source>Synchronization settings</source> -<target>Postavke sinkronizacije</target> - <source>Synchronize</source> <target>Sinkroniziraj</target> @@ -723,6 +723,12 @@ Naredba će biti pokrenuta ako se: <source>Swap sides</source> <target>Zamjeni strane</target> +<source>Find what:</source> +<target>NaÄ‘i Å¡to:</target> + +<source>Match case</source> +<target>Poklopi se</target> + <source>Save as batch job</source> <target>Spremi kao slijedni zadatak</target> @@ -777,8 +783,8 @@ Naredba će biti pokrenuta ako se: <source>Statistics</source> <target>Statistika</target> -<source>Don't show this dialog again</source> -<target>Ne prikazuj ovaj prozor ponovno</target> +<source>&Don't show this dialog again</source> +<target>&Nemoj viÅ¡e prikazivati ovaj dijaloÅ¡ki prozor</target> <source>Select a variant</source> <target>Odaberite varijantu</target> @@ -828,6 +834,12 @@ jednak <source>Configure your own synchronization rules.</source> <target>Konfigurirajte vaÅ¡a vlastita sinkronizacijska pravila.</target> +<source>Detect moved files</source> +<target>ProaÄ‘ene preseljene datoteke</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Zahtjevaju se datoteke baze. Nisu podržai svi datoteÄni sustavi.</target> + <source>Error handling</source> <target>GreÅ¡ka pri obradi</target> @@ -852,17 +864,17 @@ jednak <source>Delete or overwrite files permanently</source> <target>Trajno izbriÅ¡i ili prepiÅ¡i datoteke</target> -<source>Recycle Bin</source> -<target>KoÅ¡ za smeće</target> +<source>Recycle bin</source> +<target>KoÅ¡</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Koristi Smeće za izbrisane i prepisane datoteke</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Spremi obrisae ili prepisane datoteke u koÅ¡</target> <source>Versioning</source> <target>OznaÄi</target> -<source>Move files to user-defined folder</source> -<target>Premjesti datoteke u odreÄ‘enu mapu</target> +<source>Move files to a user-defined folder</source> +<target>Premjesti datoteke u mapu odreÄ‘enu od korsnika</target> <source>Naming convention:</source> <target>Pravilo imena:</target> @@ -870,8 +882,8 @@ jednak <source>Batch job</source> <target>Slijedni zadatak</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Izradite slijednu datoteku za automatizirati sinkronizaciju. Dvostruki klik na ovu datoteku ili dodajte obvezu u vaÅ¡em sistemskom planeru: FreeFileSync.exe <naziv zadatka>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Stvaranje batch datoteka za sinkronizaciju bez nadzora. Za poÄetak, dvaput kliknite na ovu datoteku ili planirajte u planeru zadataka: %x</target> <source>Exit</source> <target>IzaÄ‘i</target> @@ -894,30 +906,6 @@ jednak <source>Limit maximum number of log files</source> <target>OgraniÄi maksimalan broj izvješća</target> -<source>Source code written in C++ using:</source> -<target>Izvorni kod napisan u C++ uz koriÅ¡tenje:</target> - -<source>If you like FreeFileSync</source> -<target>Ako volite FreeFileSync</target> - -<source>Donate with PayPal</source> -<target>Doniraj s PayPal</target> - -<source>Many thanks for localization:</source> -<target>Velike zahvale idu:</target> - -<source>Feedback and suggestions are welcome</source> -<target>Povratne informacije i prijedlozi su dobrodoÅ¡li</target> - -<source>Homepage</source> -<target>PoÄetna stranica</target> - -<source>Email</source> -<target>Email</target> - -<source>Published under the GNU General Public License</source> -<target>Objavljeno pod licencom GNU General Public</target> - <source>Delete on both sides</source> <target>IzbriÅ¡i na obje strane</target> @@ -925,12 +913,12 @@ jednak <target>IzbriÅ¡i na obje strane iako je oznaÄena datoteka samo na jednoj strani</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -Samo datoteke koje odgovaraju svim filterskim postavkama će biti sinkronizirane. -Napomena: Imena datoteka moraju biti srodni s glavnim mapama. +Datoteke će biti kopirane ukoliko zadovolje sve zahtjeve filtera. +Pažnja: Putanje datoteka moraju biti relativne na ishodni direktorij. </target> <source>Include</source> @@ -960,20 +948,20 @@ Napomena: Imena datoteka moraju biti srodni s glavnim mapama. <source>Fail-safe file copy</source> <target>Kopiranje zaÅ¡tićeno od greÅ¡aka</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>ZapiÅ¡i u privremenu datoteku (*.ffs_tmp) najprije a onda ju preimenuj. Ovo garantira nepromjenjivost Äak u sluÄaju kritiÄne greÅ¡ke.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>Prvo kopiraj u privremenu datoteku (*ffs_tmp) zatim promijeni ime. Ovo osigurava dosljedno stanje Äak i kod fatalne greÅ¡ke.</target> <source>Copy locked files</source> <target>Kopiraj zakljuÄane datoteke</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Kopiraj zajedniÄke ili zakljuÄane datoteke koristeći Volume Shadow Copy Servis(Zahtjeva Administratorske ovlasti)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>Kopiraj dijeljene ili zakljuÄane datoteke koristeći Volume Shadow Copy servis (potrebna su administratorska ovlaÅ¡tenja)</target> <source>Copy file access permissions</source> <target>Kopiraj datoteÄna dopuÅ¡tenja</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Premjesti datoteÄna dopuÅ¡tenja (Zahtjeva administratorska prava)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>Prenesi dozvole za mape i datoteke (potrebna su administratorska ovlaÅ¡tenja)</target> <source>Restore hidden dialogs</source> <target>Prikaži skrivene prozore</target> @@ -987,33 +975,54 @@ Napomena: Imena datoteka moraju biti srodni s glavnim mapama. <source>&Default</source> <target>&Zadano</target> -<source>Find what:</source> -<target>NaÄ‘i Å¡to:</target> +<source>Source code written in C++ using:</source> +<target>Izvorni kod napisan u C++ uz koriÅ¡tenje:</target> -<source>Match case</source> -<target>Poklopi se</target> +<source>If you like FreeFileSync</source> +<target>Ako volite FreeFileSync</target> -<source>&Find next</source> -<target>&NaÄ‘i slijedeće</target> +<source>Donate with PayPal</source> +<target>Doniraj s PayPal</target> + +<source>Feedback and suggestions are welcome</source> +<target>Povratne informacije i prijedlozi su dobrodoÅ¡li</target> + +<source>Homepage</source> +<target>PoÄetna stranica</target> + +<source>Email</source> +<target>Email</target> + +<source>Published under the GNU General Public License</source> +<target>Objavljeno pod licencom GNU General Public</target> + +<source>Many thanks for localization:</source> +<target>Velike zahvale idu:</target> <source>Start synchronization</source> <target>ZapoÄni sinkronizaciju</target> +<source>Comparison settings</source> +<target>Postavke usporedbe</target> + +<source>Synchronization settings</source> +<target>Postavke sinkronizacije</target> + <source>Delete</source> <target>IzbriÅ¡i</target> <source>Configure filter</source> <target>Konfiguriraj filter</target> -<source>Find</source> -<target>PronaÄ‘i</target> - <source>Select time span</source> <target>Izaberite mjerni raspon</target> <source>Folder pairs</source> <target>Par mape</target> +<source>Find</source> +<target>PronaÄ‘i</target> + <source>Overview</source> <target>Pregled</target> @@ -1054,9 +1063,6 @@ Napomena: Imena datoteka moraju biti srodni s glavnim mapama. <source>&Execute</source> <target>&IzvrÅ¡i</target> -<source>&Don't show this dialog again</source> -<target>&Nemoj viÅ¡e prikazivati ovaj dijaloÅ¡ki prozor</target> - <source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> @@ -1090,17 +1096,20 @@ Napomena: Imena datoteka moraju biti srodni s glavnim mapama. <source>Set direction:</source> <target>Odaberi smijer:</target> -<source>Exclude temporarily</source> -<target>Izuzmi privremeno</target> +<source>multiple selection</source> +<target>viÅ¡estruki odabir</target> -<source>Include temporarily</source> -<target>Trenutno ukljuÄi</target> +<source>Include via filter:</source> +<target>Pridruži preko filtera:</target> <source>Exclude via filter:</source> <target>IskljuÄi preko filtra:</target> -<source>multiple selection</source> -<target>viÅ¡estruki odabir</target> +<source>Exclude temporarily</source> +<target>Izuzmi privremeno</target> + +<source>Include temporarily</source> +<target>Trenutno ukljuÄi</target> <source>Include all</source> <target>UkljuÄi sve</target> @@ -1147,8 +1156,8 @@ Napomena: Imena datoteka moraju biti srodni s glavnim mapama. <source>Do&n't save</source> <target>&Nemoj spremiti</target> -<source>Never save changes</source> -<target>Nikad ne spremaj promjene</target> +<source>Never save &changes</source> +<target>Nikad ne spremaj &promjene</target> <source>Show files that exist on left side only</source> <target>Prikaži datoteke koje postoje samo na lijevoj strani</target> @@ -1201,6 +1210,9 @@ Napomena: Imena datoteka moraju biti srodni s glavnim mapama. <source>All folders are in sync</source> <target>Sve mape su u sinkronizaciji</target> +<source>Cannot find %x</source> +<target>Nemogu pronaći %x</target> + <source>Comma-separated values</source> <target>Zarezom odvojene vrijednosti</target> @@ -1210,8 +1222,8 @@ Napomena: Imena datoteka moraju biti srodni s glavnim mapama. <source>Searching for program updates...</source> <target>Pretražujem ažuriranja programa...</target> -<source>Ignore further errors</source> -<target>Zanemari buduće greÅ¡ke</target> +<source>&Ignore subsequent errors</source> +<target>&Zanemari naknadne pogreÅ¡ke</target> <source>&Ignore</source> <target>&Ignoriraj</target> @@ -1219,8 +1231,8 @@ Napomena: Imena datoteka moraju biti srodni s glavnim mapama. <source>Fatal Error</source> <target>KritiÄna greÅ¡ka</target> -<source>Don't show this warning again</source> -<target>Ne prikazuj ovo upozorenje ponovno</target> +<source>&Don't show this warning again</source> +<target>&Ne prikazuj viÅ¡e ovo upozorenje.</target> <source>&Switch</source> <target>&Zamjeni</target> @@ -1261,9 +1273,6 @@ Napomena: Imena datoteka moraju biti srodni s glavnim mapama. <source>Log</source> <target>Dnevnik</target> -<source>Cannot find %x</source> -<target>Nemogu pronaći %x</target> - <source>Inactive</source> <target>Neaktivno</target> @@ -1295,8 +1304,8 @@ Napomena: Imena datoteka moraju biti srodni s glavnim mapama. <target>Filtriranje</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> <pluralform>Dali stvarno želite premjestiti sljedeću %x stavku u koÅ¡?</pluralform> @@ -1479,8 +1488,8 @@ Napomena: Imena datoteka moraju biti srodni s glavnim mapama. <source>Cannot change process I/O priorities.</source> <target>Ne može se promjeniti proces I/O prioriteta</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>Nije moguće premjestiti %x u koÅ¡ za smeće.</target> +<source>Unable to move %x to the recycle bin.</source> +<target>Nije moguće prebaciti %x u koÅ¡ za smeće.</target> <source>Cannot determine final path for %x.</source> <target>Ne mogu odrediti zavrÅ¡nu putanju za %x.</target> diff --git a/BUILD/Languages/czech.lng b/BUILD/Languages/czech.lng index 0b77b086..9762fbb7 100644 --- a/BUILD/Languages/czech.lng +++ b/BUILD/Languages/czech.lng @@ -25,13 +25,13 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Kontrola KoÅ¡e na složku %x ...</target> -<source>Moving file %x to recycle bin</source> +<source>Moving file %x to the recycle bin</source> <target>PÅ™esouvánà souboru %x do KoÅ¡e</target> -<source>Moving folder %x to recycle bin</source> +<source>Moving folder %x to the recycle bin</source> <target>PÅ™esouvánà adresáře %x do KoÅ¡e</target> -<source>Moving symbolic link %x to recycle bin</source> +<source>Moving symbolic link %x to the recycle bin</source> <target>PÅ™esouvánà symbolického odkazu %x do KoÅ¡e</target> <source>Deleting file %x</source> @@ -43,14 +43,20 @@ <source>Deleting symbolic link %x</source> <target>Mazánà symbolického odkazu %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>Nelze použÃt KoÅ¡ pro následujÃcà složky (soubory budou odstranÄ›ny permanentnÄ›):</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>Nelze použÃt KoÅ¡ pro následujÃcà složky. Soubory tak budou odstranÄ›ny permanentnÄ›:</target> <source>An exception occurred</source> <target>Vyskytla se chyba</target> -<source>Cannot find file %x.</source> -<target>Nelze najÃt soubor %x.</target> +<source>A directory path is expected after %x.</source> +<target>OÄekávána adresářová cesta po %x.</target> + +<source>Syntax error</source> +<target>Chyba syntaxe</target> + +<source>Cannot open file %x.</source> +<target>Nelze otevÅ™Ãt soubor %x.</target> <source>Error</source> <target>Chyba</target> @@ -58,6 +64,36 @@ <source>File %x does not contain a valid configuration.</source> <target>Soubor %x neobsahuje platnou konfiguraci.</target> +<source>Unequal number of left and right directories specified.</source> +<target>ZjiÅ¡tÄ›n nestejný poÄet levých a pravých adresářů.</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>KonfiguraÄnà soubor nesmà obsahovat nastavenà na úrovni adresářových párů pokud je zadán pÅ™es pÅ™Ãkazovou řádku.</target> + +<source>Warning</source> +<target>VarovánÃ</target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target>Adresáře nemohou obsahovat vÃce než jeden konfiguraÄnà soubor.</target> + +<source>Syntax:</source> +<target>Syntaxe:</target> + +<source>config files</source> +<target>konfiguraÄnà soubory</target> + +<source>directory</source> +<target>adresář</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>Libovolný poÄet konfiguraÄnÃch souborů FreeFileSync typu .ffs_gui a/nebo .ffs_batch.</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>Libovolný poÄet alternativnÃch adresářů na alespoň jednu konfiguraci.</target> + +<source>Command line</source> +<target>PÅ™Ãkazová řádka</target> + <source>A folder input field is empty.</source> <target>Nenà zadána vstupnà složka.</target> @@ -216,8 +252,8 @@ <target>Celkový Äas:</target> <source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </source> <target> <pluralform>%x B</pluralform> @@ -244,13 +280,13 @@ <target>Zpracováváno:</target> <source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </source> <target> -<pluralform>[1 proces]</pluralform> -<pluralform>[%x procesy]</pluralform> -<pluralform>[%x procesů]</pluralform> +<pluralform>1 proces</pluralform> +<pluralform>%x procesy</pluralform> +<pluralform>%x procesů</pluralform> </target> <source>Encoding extended time information: %x</source> @@ -259,6 +295,9 @@ <source>/sec</source> <target>/s</target> +<source>%x items</source> +<target>%x položek</target> + <source>Configuration file %x loaded partially only.</source> <target>Konfigurace ze souboru %x byla naÄtena jen ÄásteÄnÄ›.</target> @@ -271,7 +310,7 @@ <source>Browse directory</source> <target>Procházet adresář</target> -<source>Cannot access Volume Shadow Copy Service.</source> +<source>Cannot access the Volume Shadow Copy Service.</source> <target>NepodaÅ™il se pÅ™Ãstup ke službÄ› StÃnové kopie.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> @@ -283,8 +322,8 @@ <source>Cannot determine volume name for %x.</source> <target>>Nelze zjistit jméno jednotky souboru %x.</target> -<source>Volume name %x not part of file name %y.</source> -<target>Disk %x nenà souÄástà jména souboru %y.</target> +<source>Volume name %x is not part of file path %y.</source> +<target>Název disku %x nenà souÄástà cesty souboru %y.</target> <source>Abort requested: Waiting for current operation to finish...</source> <target>Požadavek na pÅ™eruÅ¡enÃ: ÄŒekánà na ukonÄenà aktuálnà operace...</target> @@ -352,9 +391,6 @@ <source>Idle time between last detected change and execution of command</source> <target>Prodleva mezi zjiÅ¡tÄ›nÃm poslednà zmÄ›ny a spuÅ¡tÄ›nÃm pÅ™Ãkazu</target> -<source>Command line</source> -<target>PÅ™Ãkazová řádka</target> - <source> The command is triggered if: - files or subfolders change @@ -378,9 +414,6 @@ PÅ™Ãkaz je spuÅ¡tÄ›n když: <source>RealtimeSync - Automated Synchronization</source> <target>RealtimeSync - Automatická synchronizace</target> -<source>Warning</source> -<target>VarovánÃ</target> - <source>Build: %x</source> <target>Verze: %x</target> @@ -390,15 +423,21 @@ PÅ™Ãkaz je spuÅ¡tÄ›n když: <source>All files</source> <target>VÅ¡echny soubory</target> +<source>Directory monitoring active</source> +<target>Sledovánà adresářů je aktivnÃ</target> + +<source>Waiting until all directories are available...</source> +<target>ÄŒekánà na nedostupné adresáře...</target> + <source>&Restore</source> <target>&Obnovit</target> +<source>&Show error</source> +<target>&Zobrazit chybu</target> + <source>&Exit</source> <target>&Konec</target> -<source>Waiting for missing directories...</source> -<target>ÄŒekánà na nedostupné adresáře...</target> - <source>Invalid command line:</source> <target>Neplatný pÅ™Ãkaz:</target> @@ -408,14 +447,14 @@ PÅ™Ãkaz je spuÅ¡tÄ›n když: <source>File time and size</source> <target>Podle velikosti a data souboru</target> -<source> Two way </source> -<target> Databáze </target> +<source>Two way</source> +<target>Databáze</target> <source>Mirror</source> -<target>Zrcadlenà </target> +<target>ZrcadlenÃ</target> <source>Update</source> -<target>Aktualizace </target> +<target>Aktualizace</target> <source>Custom</source> <target>VlastnÃ</target> @@ -471,11 +510,8 @@ PÅ™Ãkaz je spuÅ¡tÄ›n když: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>NásledujÃcà položky jsou nevyÅ™eÅ¡ené konflikty a nebudou synchronizovány:</target> -<source>Significant difference detected:</source> -<target>Nalezeny významné zmÄ›ny:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>VÃce než polovina souborů má být zkopÃrována nebo smazána.</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>NsledujÃcà složky se významnÄ› liÅ¡Ã. Zkontrolujte zda porovnáváte správnou dvojici složek pro synchronizaci.</target> <source>Not enough free disk space available in:</source> <target>Nedostatek mÃsta na disku:</target> @@ -495,12 +531,15 @@ PÅ™Ãkaz je spuÅ¡tÄ›n když: <source>Generating database...</source> <target>Vytvářenà databáze...</target> -<source>Creating Volume Shadow Copy for %x...</source> +<source>Creating a Volume Shadow Copy for %x...</source> <target>Vytvářenà StÃnové kopie pro %x...</target> <source>Data verification error: %x and %y have different content.</source> <target>Chyba porovnánà dat: %x má jiný obsah než %y</target> +<source>job name</source> +<target>název úlohy</target> + <source>Synchronization aborted</source> <target>Synchronizace zruÅ¡ena</target> @@ -525,6 +564,9 @@ PÅ™Ãkaz je spuÅ¡tÄ›n když: <source>Switching to FreeFileSync main dialog</source> <target>PÅ™epÃnánà do hlavnÃho okna FreeFileSync</target> +<source>Retrying operation after error:</source> +<target>Opakovanà operace po chybÄ›:</target> + <source>A new version of FreeFileSync is available:</source> <target>Je dostupná novÄ›jÅ¡Ã verze FreeFileSync:</target> @@ -648,8 +690,8 @@ PÅ™Ãkaz je spuÅ¡tÄ›n když: <source>&Export file list...</source> <target>&Exportovat seznam souborů...</target> -<source>&Global settings...</source> -<target>&NastavenÃ...</target> +<source>&Global settings</source> +<target>&Nastavenà programu</target> <source>&Tools</source> <target>&UpÅ™esnit</target> @@ -666,12 +708,6 @@ PÅ™Ãkaz je spuÅ¡tÄ›n když: <source>Compare</source> <target>PorovnánÃ</target> -<source>Comparison settings</source> -<target>Nastavenà porovnánÃ</target> - -<source>Synchronization settings</source> -<target>Nastavenà synchronizace</target> - <source>Synchronize</source> <target>Synchronizace</target> @@ -720,6 +756,9 @@ PÅ™Ãkaz je spuÅ¡tÄ›n když: <source>Synchronizing...</source> <target>Synchronizuji...</target> +<source>Minimize to notification area</source> +<target>Minimalizovat do oznamovacà oblasti</target> + <source>On completion</source> <target>Po dokonÄenÃ</target> @@ -729,6 +768,15 @@ PÅ™Ãkaz je spuÅ¡tÄ›n když: <source>&Pause</source> <target>&Pauza</target> +<source>Variant</source> +<target>Varianta</target> + +<source>Statistics</source> +<target>Statistika</target> + +<source>&Don't show this dialog again</source> +<target>Tento dialog již &nezobrazovat</target> + <source>Select a variant</source> <target>VýbÄ›r možnosti</target> @@ -777,6 +825,12 @@ je stejný <source>Configure your own synchronization rules.</source> <target>Nastavenà vlastnÃch pravidel synchronizace.</target> +<source>Detect moved files</source> +<target>Detekce pÅ™esunutých souborů</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Je nutný soubor databáze. Toto nenà dostupné na vÅ¡ech systémech.</target> + <source>Error handling</source> <target>Zpracovánà chyb</target> @@ -801,16 +855,16 @@ je stejný <source>Delete or overwrite files permanently</source> <target>Smazat nebo pÅ™epsat soubory trvale</target> -<source>Recycle Bin</source> +<source>Recycle bin</source> <target>KoÅ¡</target> -<source>Use Recycle Bin for deleted and overwritten files</source> +<source>Back up deleted and overwritten files in the recycle bin</source> <target>PoužÃt KoÅ¡ pÅ™i mazánà nebo pÅ™episu souborů</target> <source>Versioning</source> <target>VerzovánÃ</target> -<source>Move files to user-defined folder</source> +<source>Move files to a user-defined folder</source> <target>PÅ™esunout soubory do uživatelského adresáře</target> <source>Naming convention:</source> @@ -819,8 +873,8 @@ je stejný <source>Batch job</source> <target>Dávkový soubor</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Vytvořà dávkový souboru pro automatickou synchronizaci. 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>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Vytvořà dávkový souboru pro automatickou synchronizaci. Ke spuÅ¡tÄ›nà dávky jednoduÅ¡e poklikejte na vytvoÅ™ený soubor nebo využijte plánovaÄ Ãºloh vaÅ¡eho systému: %x</target> <source>Exit</source> <target>Konec</target> @@ -852,9 +906,6 @@ je stejný <source>Donate with PayPal</source> <target>PÅ™ispÄ›t pomocà PayPal</target> -<source>Many thanks for localization:</source> -<target>PodÄ›kovánà za pÅ™eklad FreeFileSync:</target> - <source>Feedback and suggestions are welcome</source> <target>Komentáře a námÄ›ty jsou vždy vÃtány</target> @@ -867,6 +918,9 @@ je stejný <source>Published under the GNU General Public License</source> <target>Vydáno pod GNU General Public License (GPL)</target> +<source>Many thanks for localization:</source> +<target>PodÄ›kovánà za pÅ™eklad FreeFileSync:</target> + <source>Delete on both sides</source> <target>Smazat z obou stran</target> @@ -874,8 +928,8 @@ je stejný <target>Smazat na obou stranách i když je soubor vybrán pouze na jedné z nich</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> Pouze soubory odpovÃdajÃcà nastavenému filtru budou vybrány pro synchronizaci. @@ -909,19 +963,19 @@ Poznámka: Filtr je aplikován relativnÄ› k základnÃm adresářům. <source>Fail-safe file copy</source> <target>BezpeÄné kopÃrovánà souborů</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>KopÃruje data nejprve do pomocného souboru (*.ffs_tmp) a poté teprve soubor pÅ™ejmenuje. Tento postup zajiÅ¡Å¥uje bezpeÄné chovánà i v pÅ™ÃpadÄ› chyby bÄ›hem pÅ™enosu</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>KopÃrovat nejprve do pomocného souboru (*.ffs_tmp) a teprve poté soubor pÅ™ejmenovat. Tento postup zajiÅ¡Å¥uje bezpeÄné chovánà i v pÅ™ÃpadÄ› chyby bÄ›hem pÅ™enosu</target> <source>Copy locked files</source> <target>KopÃrovat zamÄené soubory</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> <target>KopÃrovat sdÃlené nebo zamÄené soubory pomocà služby StÃnové kopie (Vyžaduje administrátorské oprávnÄ›nÃ)</target> <source>Copy file access permissions</source> <target>KopÃrovat pÅ™Ãstupová oprávnÄ›nà k souborům</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> +<source>Transfer file and folder permissions (requires administrator rights)</source> <target>PÅ™enést pÅ™Ãstupová oprávnÄ›nà souborů a složek (Vyžaduje administrátorské oprávnÄ›nÃ)</target> <source>Restore hidden dialogs</source> @@ -936,15 +990,6 @@ Poznámka: Filtr je aplikován relativnÄ› k základnÃm adresářům. <source>&Default</source> <target>&PÅ™eddefinované</target> -<source>Variant</source> -<target>Varianta</target> - -<source>Statistics</source> -<target>Statistika</target> - -<source>Don't show this dialog again</source> -<target>Tento dialog již nezobrazovat</target> - <source>Find what:</source> <target>NajÃt:</target> @@ -954,15 +999,21 @@ Poznámka: Filtr je aplikován relativnÄ› k základnÃm adresářům. <source>&Find next</source> <target>&NajÃt dalÅ¡Ã</target> +<source>Start synchronization</source> +<target>Start synchronizace</target> + +<source>Comparison settings</source> +<target>Nastavenà porovnánÃ</target> + +<source>Synchronization settings</source> +<target>Nastavenà synchronizace</target> + <source>Delete</source> <target>Smazat</target> <source>Configure filter</source> <target>Nastavenà filtru</target> -<source>Start synchronization</source> -<target>Start synchronizace</target> - <source>Find</source> <target>NajÃt</target> @@ -997,6 +1048,22 @@ Poznámka: Filtr je aplikován relativnÄ› k základnÃm adresářům. <target>Porovnat obÄ› strany</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>Opravdu chcete provést pÅ™Ãkaz %y pro 1 položku?</pluralform> +<pluralform>Opravdu chcete provést pÅ™Ãkaz %y pro %x položky?</pluralform> +<pluralform>Opravdu chcete provést pÅ™Ãkaz %y pro %x položek?</pluralform> +</target> + +<source>Confirm</source> +<target>Potvrdit</target> + +<source>&Execute</source> +<target>&Spustit</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1035,12 +1102,15 @@ Poznámka: Filtr je aplikován relativnÄ› k základnÃm adresářům. <source>Include temporarily</source> <target>PÅ™idat doÄasnÄ›</target> -<source>Exclude via filter:</source> -<target>Vynechat pomocà filtru:</target> - <source>multiple selection</source> <target>vÃcenásobný výbÄ›r</target> +<source>Include via filter:</source> +<target>Zahrnout pomocà filtru:</target> + +<source>Exclude via filter:</source> +<target>Vynechat pomocà filtru:</target> + <source>Include all</source> <target>Zahrnout vÅ¡e</target> @@ -1086,8 +1156,8 @@ Poznámka: Filtr je aplikován relativnÄ› k základnÃm adresářům. <source>Do&n't save</source> <target>&Neukládat</target> -<source>Never save changes</source> -<target>Nikdy neukládat zmÄ›ny</target> +<source>Never save &changes</source> +<target>Nikdy &neukládat zmÄ›ny</target> <source>Show files that exist on left side only</source> <target>Zobrazit soubory existujÃcà pouze vlevo</target> @@ -1140,7 +1210,7 @@ Poznámka: Filtr je aplikován relativnÄ› k základnÃm adresářům. <source>All folders are in sync</source> <target>VÅ¡echny složky jsou synchronizovány</target> -<source>Comma separated list</source> +<source>Comma-separated values</source> <target>Text oddÄ›lený Äárkami</target> <source>File list exported</source> @@ -1149,8 +1219,8 @@ Poznámka: Filtr je aplikován relativnÄ› k základnÃm adresářům. <source>Searching for program updates...</source> <target>Hledánà aktualizacà programu ...</target> -<source>Ignore further errors</source> -<target>PÅ™eskoÄit dalÅ¡Ã chyby</target> +<source>&Ignore subsequent errors</source> +<target>PÅ™e&skoÄit dalÅ¡Ã chyby</target> <source>&Ignore</source> <target>&PokraÄovat</target> @@ -1158,8 +1228,8 @@ Poznámka: Filtr je aplikován relativnÄ› k základnÃm adresářům. <source>Fatal Error</source> <target>Závažná chyba</target> -<source>Don't show this warning again</source> -<target>Nezobrazovat již pÅ™ÃÅ¡tÄ› toto varovánÃ</target> +<source>&Don't show this warning again</source> +<target>&Nezobrazovat již pÅ™ÃÅ¡tÄ› toto varovánÃ</target> <source>&Switch</source> <target>&PÅ™epnout</target> @@ -1194,13 +1264,10 @@ Poznámka: Filtr je aplikován relativnÄ› k základnÃm adresářům. <source>Completed</source> <target>Hotovo</target> -<source>Continue</source> -<target>PokraÄovat</target> - -<source>Pause</source> -<target>Pauza</target> +<source>&Continue</source> +<target>&PokraÄovat</target> -<source>Logging</source> +<source>Log</source> <target>Záznam zpracovánÃ</target> <source>Cannot find %x</source> @@ -1237,8 +1304,8 @@ Poznámka: Filtr je aplikován relativnÄ› k základnÃm adresářům. <target>Filtr</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> <pluralform>Opravdu chcete pÅ™esunout následujÃcà položku do KoÅ¡e?</pluralform> @@ -1298,9 +1365,6 @@ Poznámka: Filtr je aplikován relativnÄ› k základnÃm adresářům. <source>Append a timestamp to each file name</source> <target>PÅ™idat Äasovou znaÄku ke jménu souboru</target> -<source>Folder</source> -<target>Složka</target> - <source>File</source> <target>Soubor</target> @@ -1424,7 +1488,7 @@ Poznámka: Filtr je aplikován relativnÄ› k základnÃm adresářům. <source>Cannot change process I/O priorities.</source> <target>Nelze nastavit priority procesu.</target> -<source>Unable to move %x to the Recycle Bin.</source> +<source>Unable to move %x to the recycle bin.</source> <target>Nenà možné pÅ™esunout %x do KoÅ¡e.</target> <source>Cannot determine final path for %x.</source> diff --git a/BUILD/Languages/danish.lng b/BUILD/Languages/danish.lng index bc01b271..a835f88c 100644 --- a/BUILD/Languages/danish.lng +++ b/BUILD/Languages/danish.lng @@ -25,14 +25,14 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Tjekker papirkurvs tilgængelighed for mappen %x...</target> -<source>Moving file %x to recycle bin</source> +<source>Moving file %x to the recycle bin</source> <target>Flytter filen %x til papirkurv</target> -<source>Moving folder %x to recycle bin</source> +<source>Moving folder %x to the recycle bin</source> <target>Flytter mappen %x til papirkurv</target> -<source>Moving symbolic link %x to recycle bin</source> -<target>Flytter symlink %x til papirkurv</target> +<source>Moving symbolic link %x to the recycle bin</source> +<target>Flytter symbolsk link %x til papirkurv</target> <source>Deleting file %x</source> <target>Sletter filen %x</target> @@ -43,20 +43,56 @@ <source>Deleting symbolic link %x</source> <target>Sletter symlink %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> <target>Papirkurven kan ikke bruges til følgende mapper. Filerne slettes permanent:</target> <source>An exception occurred</source> <target>Undtagelse opstod</target> -<source>Cannot find file %x.</source> -<target>Kan ikke finde filen %x.</target> +<source>A directory path is expected after %x.</source> +<target>Der forventes en mappestil efter %x.</target> + +<source>Syntax error</source> +<target>Syntaksfejl</target> + +<source>Cannot open file %x.</source> +<target>Filen %x kan ikke Ã¥bnes.</target> <source>Error</source> <target>Fejl</target> <source>File %x does not contain a valid configuration.</source> -<target>%x indeholder ikke gyldige indstillinger.</target> +<target>Filen %x indeholder ikke gyldige indstillinger.</target> + +<source>Unequal number of left and right directories specified.</source> +<target>Der er angivet et ulige antal højre og venstre mapper.</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>Indstillingsfilen mÃ¥ ikke indeholde indstillinger pÃ¥ mappepar niveau nÃ¥r mapper er sat via kommando.</target> + +<source>Warning</source> +<target>Advarsel</target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target>Mapper kan ikke sættes til mere end en indstillingsfil.</target> + +<source>Syntax:</source> +<target>Syntaks:</target> + +<source>config files</source> +<target>indstillingsfiler</target> + +<source>directory</source> +<target>mappe</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>VilkÃ¥rligt antal FreeFileSync .ffs_gui og/eller .ffs_batch indstillingsfiler.</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>VilkÃ¥rligt antal alternative mappe til højst en indstillingsfil</target> + +<source>Command line</source> +<target>Kommando</target> <source>A folder input field is empty.</source> <target>Der er ikke valgt nogen mapper.</target> @@ -215,8 +251,8 @@ <target>Samlet tid:</target> <source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </source> <target> <pluralform>1 byte</pluralform> @@ -242,12 +278,12 @@ <target>Skanner:</target> <source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </source> <target> -<pluralform>[1 trÃ¥d]</pluralform> -<pluralform>[%x trÃ¥de]</pluralform> +<pluralform>1 trÃ¥d</pluralform> +<pluralform>%x trÃ¥de</pluralform> </target> <source>Encoding extended time information: %x</source> @@ -256,6 +292,9 @@ <source>/sec</source> <target>/sek</target> +<source>%x items</source> +<target>%x emner</target> + <source>Configuration file %x loaded partially only.</source> <target>Indstillingsfilen %x er kun delvist indlæst.</target> @@ -268,8 +307,8 @@ <source>Browse directory</source> <target>Gennemse mappe</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Kan ikke opnÃ¥ adgang til VSS.</target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target>VSS tjenesten er ikke tilgængelig</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>Brug FreeFileSync 64-bit til at lave VSS kopier pÃ¥ dette system.</target> @@ -280,8 +319,8 @@ <source>Cannot determine volume name for %x.</source> <target>Kan ikke bestemme volumennavn for %x.</target> -<source>Volume name %x not part of file name %y.</source> -<target>Drevnavn %x findes ikke i filnavnet %y.</target> +<source>Volume name %x is not part of file path %y.</source> +<target>Volumennavnet %x er ikke del af filstien %y.</target> <source>Abort requested: Waiting for current operation to finish...</source> <target>Afbrydelse: Venter pÃ¥ aktuel opgave afsluttes...</target> @@ -349,9 +388,6 @@ <source>Idle time between last detected change and execution of command</source> <target>Tid imellem sidst fundne ændring og udførsel</target> -<source>Command line</source> -<target>Kommando</target> - <source> The command is triggered if: - files or subfolders change @@ -375,9 +411,6 @@ Kommandoen udføres hvis: <source>RealtimeSync - Automated Synchronization</source> <target>Realtids synk - automatisk synkronisering</target> -<source>Warning</source> -<target>Advarsel</target> - <source>Build: %x</source> <target>Udgivet: %x</target> @@ -387,15 +420,21 @@ Kommandoen udføres hvis: <source>All files</source> <target>Alle filer</target> +<source>Directory monitoring active</source> +<target>MappeovervÃ¥gning aktiv</target> + +<source>Waiting until all directories are available...</source> +<target>Venter til alle mapper er tilgængelige...</target> + <source>&Restore</source> <target>&Vis vindue</target> +<source>&Show error</source> +<target>Vi&s fejl</target> + <source>&Exit</source> <target>&Luk</target> -<source>Waiting for missing directories...</source> -<target>Venter pÃ¥ manglende mapper...</target> - <source>Invalid command line:</source> <target>Ugyldig kommando:</target> @@ -405,14 +444,14 @@ Kommandoen udføres hvis: <source>File time and size</source> <target>Størrelse og tid</target> -<source> Two way </source> -<target> Tovejs </target> +<source>Two way</source> +<target>Tovejs</target> <source>Mirror</source> -<target>Spejling </target> +<target>Spejling</target> <source>Update</source> -<target>Opdater </target> +<target>Opdater</target> <source>Custom</source> <target>Tilpasset</target> @@ -468,11 +507,8 @@ Kommandoen udføres hvis: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>Følgende emner har uløste konflikter og synkroniseres ikke:</target> -<source>Significant difference detected:</source> -<target>Markant forskel:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>Mere end 50% af af filerne kopieres eller slettes.</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>Følgende mapper har markante forskelle. Kontroller at du synkroniserer de rigtige mapper</target> <source>Not enough free disk space available in:</source> <target>Ikke nok ledig diskplads pÃ¥:</target> @@ -492,12 +528,15 @@ Kommandoen udføres hvis: <source>Generating database...</source> <target>Opretter database...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>Opretter VVS kopi for %x...</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>Oprette VSS kopi for %x...</target> <source>Data verification error: %x and %y have different content.</source> <target>Godkendelsesfejl: %x og %y har forskelligt indhold</target> +<source>job name</source> +<target>Jobnavn</target> + <source>Synchronization aborted</source> <target>Synkronisering afbrudt</target> @@ -522,6 +561,9 @@ Kommandoen udføres hvis: <source>Switching to FreeFileSync main dialog</source> <target>Skifter til hovedvinduet</target> +<source>Retrying operation after error:</source> +<target>Prøver igen efter fejl:</target> + <source>A new version of FreeFileSync is available:</source> <target>Opdatering tilgængelig:</target> @@ -645,8 +687,8 @@ Kommandoen udføres hvis: <source>&Export file list...</source> <target>&Eksporter filliste...</target> -<source>&Global settings...</source> -<target>&Programindstillinger...</target> +<source>&Global settings</source> +<target>&Programindstillinger</target> <source>&Tools</source> <target>&Værktøj</target> @@ -717,6 +759,9 @@ Kommandoen udføres hvis: <source>Synchronizing...</source> <target>Synkroniserer...</target> +<source>Minimize to notification area</source> +<target>Minimér til uret</target> + <source>On completion</source> <target>Ved gennemført</target> @@ -726,6 +771,15 @@ Kommandoen udføres hvis: <source>&Pause</source> <target>&Pause</target> +<source>Variant</source> +<target>Jobtype</target> + +<source>Statistics</source> +<target>Statistik</target> + +<source>&Don't show this dialog again</source> +<target>&Vis ikke igen</target> + <source>Select a variant</source> <target>Vælg metode</target> @@ -774,6 +828,12 @@ er identisk <source>Configure your own synchronization rules.</source> <target>Opret dine egne synkroniseringsregler.</target> +<source>Detect moved files</source> +<target>Genkend flyttede filer</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Kræver databasefiler. Ikke understøttet i alle filsystemer</target> + <source>Error handling</source> <target>FejlhÃ¥ndtering</target> @@ -798,17 +858,17 @@ er identisk <source>Delete or overwrite files permanently</source> <target>Slet eller overskriv filer permanent</target> -<source>Recycle Bin</source> +<source>Recycle bin</source> <target>Papirkurv</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Slettede og overskrevne filer flyttes til papirkurv</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Backup slettede og overskrevne filer i papirkurven</target> <source>Versioning</source> <target>Versionering</target> -<source>Move files to user-defined folder</source> -<target>Flyt filer til valgt mappe</target> +<source>Move files to a user-defined folder</source> +<target>Flyt filer til brugerdefineret mappe</target> <source>Naming convention:</source> <target>Navneregler:</target> @@ -816,8 +876,8 @@ er identisk <source>Batch job</source> <target>Batchfil</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Opret en batchfil til automatisk synkronisering. Dobbeltklik pÃ¥ filen eller brug systemets opgavestyring: FreeFileSync.exe <opgave navn>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Opret batchfil til automatisk synkronisering. Start ved at dobbeltklikke pÃ¥ filen eller planlæg via opgavestyring: %x</target> <source>Exit</source> <target>Luk</target> @@ -871,12 +931,12 @@ er identisk <target>Slet pÃ¥ begge sider selvom selvom filen kun er valgt pÃ¥ en side</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -Synkroniserer kun filer der opfylder alle betingelser. -Bemærk: Filnavne skal relatere til grundmapperne. +Filer synkroniseres kun hvis de opfyldet alle filterregler. +Bemærk: Filstier skal relatere til kildemappen. </target> <source>Include</source> @@ -906,20 +966,20 @@ Bemærk: Filnavne skal relatere til grundmapperne. <source>Fail-safe file copy</source> <target>Sikker filkopiering</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>Skriv først til en midlertidig fil (*.ffs_tmp) og omdøb derefter. Dette garanterer sikkerheden selv ved fatale fejl.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>Kopiér til midlertidig fil (*.ffs_tmp) før omdøbning. Sikrer processen ved alvorlige fejl.</target> <source>Copy locked files</source> <target>Kopier lÃ¥ste filer</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Kopier delte eller lÃ¥ste filer ved hjælp af VSS (kræver administrative rettigheder)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>Kopiér delte eller lÃ¥ste filer med VSS kopiering (administrator)</target> <source>Copy file access permissions</source> <target>Kopier adgangstilladelser</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Overfør fil- og mappetilladelser (kræver administrative rettigheder)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>Overfør fil og mappetilladelser (administrator)</target> <source>Restore hidden dialogs</source> <target>Gendan skjulte dialoger</target> @@ -933,15 +993,6 @@ Bemærk: Filnavne skal relatere til grundmapperne. <source>&Default</source> <target>S&tandard</target> -<source>Variant</source> -<target>Jobtype</target> - -<source>Statistics</source> -<target>Statistik</target> - -<source>Don't show this dialog again</source> -<target>Vis ikke igen</target> - <source>Find what:</source> <target>Søg efter:</target> @@ -951,15 +1002,15 @@ Bemærk: Filnavne skal relatere til grundmapperne. <source>&Find next</source> <target>&Find næste</target> +<source>Start synchronization</source> +<target>Start synkronisering</target> + <source>Delete</source> <target>Slet</target> <source>Configure filter</source> <target>Indstil filter</target> -<source>Start synchronization</source> -<target>Start synkronisering</target> - <source>Find</source> <target>Søg</target> @@ -994,6 +1045,21 @@ Bemærk: Filnavne skal relatere til grundmapperne. <target>Analyser begge sider</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>Vil du køre kommandoen %y for 1 emne?</pluralform> +<pluralform>Vil du køre kommandoen %y for %x emner?</pluralform> +</target> + +<source>Confirm</source> +<target>Bekræft</target> + +<source>&Execute</source> +<target>&Udfør</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1029,12 +1095,15 @@ Bemærk: Filnavne skal relatere til grundmapperne. <source>Include temporarily</source> <target>Inkluder midlertidigt</target> -<source>Exclude via filter:</source> -<target>Ekskluder m. filter:</target> - <source>multiple selection</source> <target>vælg flere</target> +<source>Include via filter:</source> +<target>Inkludér via filter:</target> + +<source>Exclude via filter:</source> +<target>Ekskluder m. filter:</target> + <source>Include all</source> <target>Vælg alle</target> @@ -1080,8 +1149,8 @@ Bemærk: Filnavne skal relatere til grundmapperne. <source>Do&n't save</source> <target>&Gem ikke</target> -<source>Never save changes</source> -<target>Gem aldrig</target> +<source>Never save &changes</source> +<target>Gem &aldrig ændringer</target> <source>Show files that exist on left side only</source> <target>Vis filer der kun findes pÃ¥ venstre side</target> @@ -1134,8 +1203,8 @@ Bemærk: Filnavne skal relatere til grundmapperne. <source>All folders are in sync</source> <target>Alle mapper er synkrone</target> -<source>Comma separated list</source> -<target>Kommaopdelt liste</target> +<source>Comma-separated values</source> +<target>Kommaopdelte værdier</target> <source>File list exported</source> <target>Fillisten blev eksporteret</target> @@ -1143,8 +1212,8 @@ Bemærk: Filnavne skal relatere til grundmapperne. <source>Searching for program updates...</source> <target>Søger efter opdatering...</target> -<source>Ignore further errors</source> -<target>Ignorer fremtidige fejl</target> +<source>&Ignore subsequent errors</source> +<target>&Ignorer efterfølgende fejl</target> <source>&Ignore</source> <target>&Ignorer</target> @@ -1152,8 +1221,8 @@ Bemærk: Filnavne skal relatere til grundmapperne. <source>Fatal Error</source> <target>Fatal fejl</target> -<source>Don't show this warning again</source> -<target>Vis ikke igen</target> +<source>&Don't show this warning again</source> +<target>&Vis ikke igen</target> <source>&Switch</source> <target>&Skift</target> @@ -1188,14 +1257,11 @@ Bemærk: Filnavne skal relatere til grundmapperne. <source>Completed</source> <target>Gennemført</target> -<source>Continue</source> -<target>Fortsæt</target> +<source>&Continue</source> +<target>&Fortsæt</target> -<source>Pause</source> -<target>Pause</target> - -<source>Logging</source> -<target>Rapporter</target> +<source>Log</source> +<target>Log</target> <source>Cannot find %x</source> <target>Kan ikke finde %x</target> @@ -1231,11 +1297,11 @@ Bemærk: Filnavne skal relatere til grundmapperne. <target>Filter</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>Vil du flytte emnet til papirkurven?</pluralform> +<pluralform>Vil du flytte følgende emne til papirkurven?</pluralform> <pluralform>Vil du flytte følgende %x emner til papirkurven?</pluralform> </target> @@ -1290,9 +1356,6 @@ Bemærk: Filnavne skal relatere til grundmapperne. <source>Append a timestamp to each file name</source> <target>Føj tidsstempel til hvert filnavn</target> -<source>Folder</source> -<target>Mappe</target> - <source>File</source> <target>Fil</target> @@ -1413,8 +1476,8 @@ Bemærk: Filnavne skal relatere til grundmapperne. <source>Cannot change process I/O priorities.</source> <target>Kan ikke ændre I/O prioriteter.</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>Kan ikke flytte %x til papirkurv.</target> +<source>Unable to move %x to the recycle bin.</source> +<target>Kunne ikke flytte %x til papirkurv.</target> <source>Cannot determine final path for %x.</source> <target>Kan ikke bestemme endelig sti for %x</target> diff --git a/BUILD/Languages/dutch.lng b/BUILD/Languages/dutch.lng index 911893b9..dca4af40 100644 --- a/BUILD/Languages/dutch.lng +++ b/BUILD/Languages/dutch.lng @@ -1,6 +1,6 @@ <header> <language>Nederlands</language> - <translator>Edwin Dierssen && Jochem Sparla</translator> + <translator>Edwin Dierssen</translator> <locale>nl_NL</locale> <flag_image>flag_holland.png</flag_image> <plural_form_count>2</plural_form_count> @@ -25,13 +25,13 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Prullebak beschikbaarheid voor map %x te controleren...</target> -<source>Moving file %x to recycle bin</source> +<source>Moving file %x to the recycle bin</source> <target>Bezig met verplaatsen van bestand %x naar de prullenbak</target> -<source>Moving folder %x to recycle bin</source> +<source>Moving folder %x to the recycle bin</source> <target>Bezig met verplaatsen van map %x naar de prullenbak</target> -<source>Moving symbolic link %x to recycle bin</source> +<source>Moving symbolic link %x to the recycle bin</source> <target>Bezig met verplaatsen van snelkoppeling %x naar de prullenbak</target> <source>Deleting file %x</source> @@ -43,8 +43,8 @@ <source>Deleting symbolic link %x</source> <target>Verwijderen van snelkoppeling %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>De Prullenbak is niet beschikbaar voor de volgende mappen. De bestanden zullen permanent worden verwijderd:</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>De prullenbak is niet beschikbaar voor de volgende mappen. Bestanden zullen permanent verwijderd worden:</target> <source>An exception occurred</source> <target>Er heeft een uitzondering plaatsgevonden</target> @@ -307,8 +307,8 @@ <source>Browse directory</source> <target>Verken map</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Kan de Volume Schaduwkopie Service niet benaderen.</target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target>Kan de Volume Shadow Copy Service niet benaderen.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>Gebruik alstublieft de FreeFileSync 64-bit versie om schaduwkopieën te maken op dit systeem.</target> @@ -528,12 +528,15 @@ De opdracht word geactiveerd als: <source>Generating database...</source> <target>Genereren van database...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>Bezig met Volume Schaduwkopie te maken voor %x...</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>Aanmaken van een Volume Shadow Copy voor %x...</target> <source>Data verification error: %x and %y have different content.</source> <target>Data verificatie fout: %x en %y hebben een verschillende inhoud.</target> +<source>job name</source> +<target>taaknaam</target> + <source>Synchronization aborted</source> <target>Synchronisatie afgebroken</target> @@ -684,8 +687,8 @@ De opdracht word geactiveerd als: <source>&Export file list...</source> <target>&Exporteer bestandslijst...</target> -<source>&Global settings...</source> -<target>&Algemene instellingen...</target> +<source>&Global settings</source> +<target>&Algemene instellingen</target> <source>&Tools</source> <target>&Gereedschap</target> @@ -774,8 +777,8 @@ De opdracht word geactiveerd als: <source>Statistics</source> <target>Statistieken</target> -<source>Don't show this dialog again</source> -<target>Laat deze dialoog niet meer zien</target> +<source>&Don't show this dialog again</source> +<target>Laat deze dialoog &niet meer zien</target> <source>Select a variant</source> <target>Selecteer een variant</target> @@ -825,6 +828,12 @@ overeenkomt <source>Configure your own synchronization rules.</source> <target>Configureer uw eigen synchronisatieregels.</target> +<source>Detect moved files</source> +<target>Detecteer verplaatste bestanden</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Heeft database bestanden nodig. Wordt niet ondersteund door alle bestandssystemen</target> + <source>Error handling</source> <target>Fout afhandeling</target> @@ -849,16 +858,16 @@ overeenkomt <source>Delete or overwrite files permanently</source> <target>Bestanden definitief verwijderen of overschrijven</target> -<source>Recycle Bin</source> +<source>Recycle bin</source> <target>Prullenbak</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Gebruik prullenbak voor verwijderde en overschreven bestanden</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Maak een backup van verwijderde en overschreven bestanden in de prullenbak</target> <source>Versioning</source> <target>Versiebeheer</target> -<source>Move files to user-defined folder</source> +<source>Move files to a user-defined folder</source> <target>Verplaats bestanden naar een gebruikers gedefineerde map</target> <source>Naming convention:</source> @@ -867,8 +876,8 @@ overeenkomt <source>Batch job</source> <target>Taaklijst</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Maak een taakbestand om synchronisatie te automatiseren. Dubbelklik op dit bestand of plan dit in de systeem taakplanner: FreeFileSync.exe <taaknaam>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Maak een batchbestand voor onbeheerde synchronisatie. Om te starten dubbelklikt u dit bestand of rooster in een taakplanner: %x</target> <source>Exit</source> <target>Sluiten</target> @@ -922,13 +931,10 @@ overeenkomt <target>Verwijder aan beide zijdes ook al is het bestand maar aan één zijde geselecteerd</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> -<target> -Alleen bestanden die met alle filter instellingen overeen komen worden gesynchroniseerd. -Opmerking: Bestandsnamen moeten relatief zijn aan de basis mappen. -</target> +<target>Bestanden zullen alleen gesynchroniseerd worden als ze aan alle filterregels voldoen.</target> <source>Include</source> <target>Opnemen</target> @@ -957,20 +963,20 @@ Opmerking: Bestandsnamen moeten relatief zijn aan de basis mappen. <source>Fail-safe file copy</source> <target>Fail-safe bestandskopie</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>Schrijf eerst naar een tijdelijk bestand (*.ffs_tmp) en hernoem daarna. Dit garandeert een consistente toestand, zelfs in het geval van een fatale fout.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>Kopiëer eerst naar een tijdelijk bestand (*.ffs_tmp) en hernoem het daarna. Dit garandeert consistentie, zelfs in het geval van een fatale fout.</target> <source>Copy locked files</source> <target>Kopiëer vergrendelde bestanden</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Kopiëer gedeelde of vergrendelde bestanden met Volume Shadow Copy Service (Vereist Administrator rechten)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>Kopiëer gedeelde of afgesloten bestanden met behulp van de Volume Shadow Copy Service (vereist administrator rechten)</target> <source>Copy file access permissions</source> <target>Kopiëer toegangsrechten van bestand.</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Overdragen van bestands- en mappermissies (Administrator rechten nodig)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>Verplaats bestands en map permissies (vereist administrator rechten)</target> <source>Restore hidden dialogs</source> <target>Herstel verborgen dialogen</target> @@ -1050,9 +1056,6 @@ Opmerking: Bestandsnamen moeten relatief zijn aan de basis mappen. <source>&Execute</source> <target>&Uitvoeren</target> -<source>&Don't show this dialog again</source> -<target>Laat deze dialoog &niet meer zien</target> - <source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> @@ -1089,12 +1092,15 @@ Opmerking: Bestandsnamen moeten relatief zijn aan de basis mappen. <source>Include temporarily</source> <target>Tijdelijk opnemen</target> -<source>Exclude via filter:</source> -<target>Sluit via filter uit:</target> - <source>multiple selection</source> <target>meervoudige selectie</target> +<source>Include via filter:</source> +<target>Invoegen via filter:</target> + +<source>Exclude via filter:</source> +<target>Sluit via filter uit:</target> + <source>Include all</source> <target>Alles opnemen</target> @@ -1140,8 +1146,8 @@ Opmerking: Bestandsnamen moeten relatief zijn aan de basis mappen. <source>Do&n't save</source> <target>&Niet opslaan</target> -<source>Never save changes</source> -<target>Wijzigingen nooit opslaan</target> +<source>Never save &changes</source> +<target>Sla &veranderingen nooit op</target> <source>Show files that exist on left side only</source> <target>Toon bestanden die alleen aan de linkerzijde bestaan</target> @@ -1203,8 +1209,8 @@ Opmerking: Bestandsnamen moeten relatief zijn aan de basis mappen. <source>Searching for program updates...</source> <target>Bezig met zoeken naar programma updates...</target> -<source>Ignore further errors</source> -<target>Negeer verdere foutmeldingen</target> +<source>&Ignore subsequent errors</source> +<target>&Negeer volgende foutmeldingen</target> <source>&Ignore</source> <target>&Negeren</target> @@ -1212,8 +1218,8 @@ Opmerking: Bestandsnamen moeten relatief zijn aan de basis mappen. <source>Fatal Error</source> <target>Kritieke fout</target> -<source>Don't show this warning again</source> -<target>Laat deze waarschuwing niet opnieuw zien</target> +<source>&Don't show this warning again</source> +<target>Laat deze &waarschuwing niet meer zien</target> <source>&Switch</source> <target>&Omschakelen</target> @@ -1288,12 +1294,12 @@ Opmerking: Bestandsnamen moeten relatief zijn aan de basis mappen. <target>Filter</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>Weet u zeker dat u het volgende item naar de Prullebak wilt verplaatsen?</pluralform> -<pluralform>Weet u zeker dat u de volgende %x items naar de Prullebak wilt verplaatsen?</pluralform> +<pluralform>Wilt u dit item echt naar de prullenbak verplaatsen?</pluralform> +<pluralform>Wilt u echt de volgende %x items naar de prullenbak verplaatsen?</pluralform> </target> <source> @@ -1467,8 +1473,8 @@ Opmerking: Bestandsnamen moeten relatief zijn aan de basis mappen. <source>Cannot change process I/O priorities.</source> <target>Kan de I/O prioriteiten niet aanpassen.</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>Niet mogelijk om %x naar de Prullenbak te verplaatsen.</target> +<source>Unable to move %x to the recycle bin.</source> +<target>Kan %x niet verplaatsen naar de prullenbak.</target> <source>Cannot determine final path for %x.</source> <target>Kan pad voor %x niet vaststellen.</target> diff --git a/BUILD/Languages/english_uk.lng b/BUILD/Languages/english_uk.lng index 753ccfd0..69642e78 100644 --- a/BUILD/Languages/english_uk.lng +++ b/BUILD/Languages/english_uk.lng @@ -7,6 +7,9 @@ <plural_definition>n == 1 ? 0 : 1</plural_definition> </header> +<source>Close search bar</source> +<target>Close search bar</target> + <source>Both sides have changed since last synchronization.</source> <target>Both sides have changed since last synchronisation.</target> @@ -25,14 +28,14 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Checking recycle bin availability for folder %x...</target> -<source>Moving file %x to recycle bin</source> -<target>Moving file %x to recycle bin</target> +<source>Moving file %x to the recycle bin</source> +<target>Moving file %x to the recycle bin</target> -<source>Moving folder %x to recycle bin</source> -<target>Moving folder %x to recycle bin</target> +<source>Moving folder %x to the recycle bin</source> +<target>Moving folder %x to the recycle bin</target> -<source>Moving symbolic link %x to recycle bin</source> -<target>Moving symbolic link %x to recycle bin</target> +<source>Moving symbolic link %x to the recycle bin</source> +<target>Moving symbolic link %x to the recycle bin</target> <source>Deleting file %x</source> <target>Deleting file %x</target> @@ -43,8 +46,8 @@ <source>Deleting symbolic link %x</source> <target>Deleting symbolic link %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</target> <source>An exception occurred</source> <target>An exception occurred</target> @@ -307,8 +310,8 @@ <source>Browse directory</source> <target>Browse directory</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Cannot access Volume Shadow Copy Service.</target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target>Cannot access the Volume Shadow Copy Service.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>Please use FreeFileSync 64-bit version to create shadow copies on this system.</target> @@ -528,12 +531,15 @@ The command is triggered if: <source>Generating database...</source> <target>Generating database...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>Creating Volume Shadow Copy for %x...</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>Creating a Volume Shadow Copy for %x...</target> <source>Data verification error: %x and %y have different content.</source> <target>Data verification error: %x and %y have different content.</target> +<source>job name</source> +<target>job name</target> + <source>Synchronization aborted</source> <target>Synchronisation aborted</target> @@ -684,8 +690,8 @@ The command is triggered if: <source>&Export file list...</source> <target>&Export file list...</target> -<source>&Global settings...</source> -<target>&Global settings...</target> +<source>&Global settings</source> +<target>&Global settings</target> <source>&Tools</source> <target>&Tools</target> @@ -702,12 +708,6 @@ The command is triggered if: <source>Compare</source> <target>Compare</target> -<source>Comparison settings</source> -<target>Comparison settings</target> - -<source>Synchronization settings</source> -<target>Synchronisation settings</target> - <source>Synchronize</source> <target>Synchronise</target> @@ -720,6 +720,12 @@ The command is triggered if: <source>Swap sides</source> <target>Swap sides</target> +<source>Find what:</source> +<target>Find what:</target> + +<source>Match case</source> +<target>Match case</target> + <source>Save as batch job</source> <target>Save as batch job</target> @@ -774,8 +780,8 @@ The command is triggered if: <source>Statistics</source> <target>Statistics</target> -<source>Don't show this dialog again</source> -<target>Don't show this dialogue again</target> +<source>&Don't show this dialog again</source> +<target>&Don't show this dialogue again</target> <source>Select a variant</source> <target>Select a variant</target> @@ -825,6 +831,12 @@ is the same <source>Configure your own synchronization rules.</source> <target>Configure your own synchronisation rules.</target> +<source>Detect moved files</source> +<target>Detect moved files</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Requires database files. Not supported by all file systems.</target> + <source>Error handling</source> <target>Error handling</target> @@ -849,17 +861,17 @@ is the same <source>Delete or overwrite files permanently</source> <target>Delete or overwrite files permanently</target> -<source>Recycle Bin</source> -<target>Recycle Bin</target> +<source>Recycle bin</source> +<target>Recycle bin</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Use Recycle Bin for deleted and overwritten files</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Back up deleted and overwritten files in the recycle bin</target> <source>Versioning</source> <target>Versioning</target> -<source>Move files to user-defined folder</source> -<target>Move files to user-defined folder</target> +<source>Move files to a user-defined folder</source> +<target>Move files to a user-defined folder</target> <source>Naming convention:</source> <target>Naming convention:</target> @@ -867,8 +879,8 @@ is the same <source>Batch job</source> <target>Batch job</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Create a batch file to automate synchronisation. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Create a batch file for unattended synchronisation. To start, double-click this file or schedule in a task planner: %x</target> <source>Exit</source> <target>Exit</target> @@ -891,30 +903,6 @@ is the same <source>Limit maximum number of log files</source> <target>Limit maximum number of log files</target> -<source>Source code written in C++ using:</source> -<target>Source code written in C++ using:</target> - -<source>If you like FreeFileSync</source> -<target>If you like FreeFileSync</target> - -<source>Donate with PayPal</source> -<target>Donate with PayPal</target> - -<source>Many thanks for localization:</source> -<target>Many thanks for localisation:</target> - -<source>Feedback and suggestions are welcome</source> -<target>Feedback and suggestions are welcome</target> - -<source>Homepage</source> -<target>Homepage</target> - -<source>Email</source> -<target>E-mail</target> - -<source>Published under the GNU General Public License</source> -<target>Published under the GNU General Public Licence</target> - <source>Delete on both sides</source> <target>Delete on both sides</target> @@ -922,12 +910,12 @@ is the same <target>Delete on both sides even if the file is selected on one side only</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -Only files that match all filter settings will be synchronised. -Note: File names must be relative to base directories. +Files will only be synchronised if they pass all filter rules. +Note: File paths must be relative to base directories. </target> <source>Include</source> @@ -957,20 +945,20 @@ Note: File names must be relative to base directories. <source>Fail-safe file copy</source> <target>Fail-safe file copy</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>Write to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of fatal error.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</target> <source>Copy locked files</source> <target>Copy locked files</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</target> <source>Copy file access permissions</source> <target>Copy file access permissions</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Transfer file and folder permissions (Requires Administrator rights)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>Transfer file and folder permissions (requires administrator rights)</target> <source>Restore hidden dialogs</source> <target>Restore hidden dialogues</target> @@ -984,33 +972,54 @@ Note: File names must be relative to base directories. <source>&Default</source> <target>&Default</target> -<source>Find what:</source> -<target>Find what:</target> +<source>Source code written in C++ using:</source> +<target>Source code written in C++ using:</target> -<source>Match case</source> -<target>Match case</target> +<source>If you like FreeFileSync</source> +<target>If you like FreeFileSync</target> -<source>&Find next</source> -<target>&Find next</target> +<source>Donate with PayPal</source> +<target>Donate with PayPal</target> + +<source>Feedback and suggestions are welcome</source> +<target>Feedback and suggestions are welcome</target> + +<source>Homepage</source> +<target>Homepage</target> + +<source>Email</source> +<target>E-mail</target> + +<source>Published under the GNU General Public License</source> +<target>Published under the GNU General Public Licence</target> + +<source>Many thanks for localization:</source> +<target>Many thanks for localisation:</target> <source>Start synchronization</source> <target>Start synchronisation</target> +<source>Comparison settings</source> +<target>Comparison settings</target> + +<source>Synchronization settings</source> +<target>Synchronisation settings</target> + <source>Delete</source> <target>Delete</target> <source>Configure filter</source> <target>Configure filter</target> -<source>Find</source> -<target>Find</target> - <source>Select time span</source> <target>Select time span</target> <source>Folder pairs</source> <target>Folder pairs</target> +<source>Find</source> +<target>Find</target> + <source>Overview</source> <target>Overview</target> @@ -1050,9 +1059,6 @@ Note: File names must be relative to base directories. <source>&Execute</source> <target>&Execute</target> -<source>&Don't show this dialog again</source> -<target>&Don't show this dialogue again</target> - <source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> @@ -1083,17 +1089,20 @@ Note: File names must be relative to base directories. <source>Set direction:</source> <target>Set direction:</target> -<source>Exclude temporarily</source> -<target>Exclude temporarily</target> +<source>multiple selection</source> +<target>multiple selection</target> -<source>Include temporarily</source> -<target>Include temporarily</target> +<source>Include via filter:</source> +<target>Include via filter:</target> <source>Exclude via filter:</source> <target>Exclude via filter:</target> -<source>multiple selection</source> -<target>multiple selection</target> +<source>Exclude temporarily</source> +<target>Exclude temporarily</target> + +<source>Include temporarily</source> +<target>Include temporarily</target> <source>Include all</source> <target>Include all</target> @@ -1140,8 +1149,8 @@ Note: File names must be relative to base directories. <source>Do&n't save</source> <target>Do&n't save</target> -<source>Never save changes</source> -<target>Never save changes</target> +<source>Never save &changes</source> +<target>Never save &changes</target> <source>Show files that exist on left side only</source> <target>Show files that exist on left side only</target> @@ -1194,6 +1203,9 @@ Note: File names must be relative to base directories. <source>All folders are in sync</source> <target>All folders are in sync</target> +<source>Cannot find %x</source> +<target>Cannot find %x</target> + <source>Comma-separated values</source> <target>Comma-separated values</target> @@ -1203,8 +1215,8 @@ Note: File names must be relative to base directories. <source>Searching for program updates...</source> <target>Searching for program updates...</target> -<source>Ignore further errors</source> -<target>Ignore further errors</target> +<source>&Ignore subsequent errors</source> +<target>&Ignore subsequent errors</target> <source>&Ignore</source> <target>&Ignore</target> @@ -1212,8 +1224,8 @@ Note: File names must be relative to base directories. <source>Fatal Error</source> <target>Fatal Error</target> -<source>Don't show this warning again</source> -<target>Don't show this warning again</target> +<source>&Don't show this warning again</source> +<target>&Don't show this warning again</target> <source>&Switch</source> <target>&Switch</target> @@ -1254,9 +1266,6 @@ Note: File names must be relative to base directories. <source>Log</source> <target>Log</target> -<source>Cannot find %x</source> -<target>Cannot find %x</target> - <source>Inactive</source> <target>Inactive</target> @@ -1288,12 +1297,12 @@ Note: File names must be relative to base directories. <target>Filter</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </target> <source> @@ -1467,8 +1476,8 @@ Note: File names must be relative to base directories. <source>Cannot change process I/O priorities.</source> <target>Cannot change process I/O priorities.</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>Unable to move %x to the Recycle Bin.</target> +<source>Unable to move %x to the recycle bin.</source> +<target>Unable to move %x to the recycle bin.</target> <source>Cannot determine final path for %x.</source> <target>Cannot determine final path for %x.</target> diff --git a/BUILD/Languages/finnish.lng b/BUILD/Languages/finnish.lng index 81c5bf61..54b8c2c7 100644 --- a/BUILD/Languages/finnish.lng +++ b/BUILD/Languages/finnish.lng @@ -25,14 +25,14 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Tarkistetaan Roskakorin käyttö hakemistolle %x...</target> -<source>Moving file %x to recycle bin</source> -<target>Siirrä tiedosto %x roskakoriin</target> +<source>Moving file %x to the recycle bin</source> +<target>Siirrä tiedosto %x Roskakoriin</target> -<source>Moving folder %x to recycle bin</source> -<target>Siirrä hakemisto %x roskakoriin</target> +<source>Moving folder %x to the recycle bin</source> +<target>Siirrä hakemisto %x Roskakoriin</target> -<source>Moving symbolic link %x to recycle bin</source> -<target>Siirrä pikakuvake %x roskakoriin</target> +<source>Moving symbolic link %x to the recycle bin</source> +<target>Siirrä linkki %x Roskakoriin</target> <source>Deleting file %x</source> <target>Poista tiedosto %x</target> @@ -43,14 +43,20 @@ <source>Deleting symbolic link %x</source> <target>Pistetaan pikakuvake %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>Roskakori ei ole käytössä näillä hakemistoilla. Tiedostot poistetaan pysyvästi:</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>Roskakori puuttuu näiltä hakemistoilta. Tiedostot poistetaan ehdotta:</target> <source>An exception occurred</source> <target>Virhe havaittu</target> -<source>Cannot find file %x.</source> -<target>Tiedosto %x ei löydy.</target> +<source>A directory path is expected after %x.</source> +<target>Tarvitaan hakemistopolku %x jälkeen.</target> + +<source>Syntax error</source> +<target>Komento virhe</target> + +<source>Cannot open file %x.</source> +<target>Tiedosto %x ei aukea.</target> <source>Error</source> <target>Virhe</target> @@ -58,6 +64,36 @@ <source>File %x does not contain a valid configuration.</source> <target>Tiedosto %x ei sisällä kelvollista kokoonpanoa.</target> +<source>Unequal number of left and right directories specified.</source> +<target>Hakemisto määrät ei täsmää (oikea<>vasen).</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>Määrittelyssä on oltava viittaukset hakemistopareista, jos hakemistot kutsutaam komentoriviltä.</target> + +<source>Warning</source> +<target>Varoitus</target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target>Hakemisto määriteltävä vain yhteen määrittelyyn.</target> + +<source>Syntax:</source> +<target>Syntaksi:</target> + +<source>config files</source> +<target>määrittelytiedosto</target> + +<source>directory</source> +<target>hakemisto</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>Vapaa määrä FreeFileSync .ffs_gui ja/tai .ffs_batch määrittelytiedostoja.</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>Vapaa määrä eri hakemistoja yhdessä määrittelytiedostossa.</target> + +<source>Command line</source> +<target>Komentokehote</target> + <source>A folder input field is empty.</source> <target>Hakemiston syöte on tyhjä.</target> @@ -215,8 +251,8 @@ <target>Kokonaisaika:</target> <source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </source> <target> <pluralform>1 tavu</pluralform> @@ -242,12 +278,12 @@ <target>Skannaus:</target> <source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </source> <target> -<pluralform>[1 säije]</pluralform> -<pluralform>[%x säijettä]</pluralform> +<pluralform>1 säije</pluralform> +<pluralform>%x säijettä</pluralform> </target> <source>Encoding extended time information: %x</source> @@ -256,6 +292,9 @@ <source>/sec</source> <target>/s</target> +<source>%x items</source> +<target>%x kpl</target> + <source>Configuration file %x loaded partially only.</source> <target>Kokoonpanotiedosto %x ladattu vain osittain.</target> @@ -268,8 +307,8 @@ <source>Browse directory</source> <target>Selaa hakemistoa</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Ei voi käyttää Volume Shadow Copy Service.</target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target>Volume Shadow Copy palvelu ei vastaa.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>Tilannevedoksia varten käytä tässä järjestelmässä FreeFileSync 64-bittinen versio.</target> @@ -280,8 +319,8 @@ <source>Cannot determine volume name for %x.</source> <target>Nimen %x tunnistus ei onnistu.</target> -<source>Volume name %x not part of file name %y.</source> -<target>Taltion nimi %x ei esiinny tiedostonimessä %y.</target> +<source>Volume name %x is not part of file path %y.</source> +<target>Nimi %x ei esiinny tiedostopolussa %y.</target> <source>Abort requested: Waiting for current operation to finish...</source> <target>Keskeytys pyydetty: Odotetaan toiminnon loppumista...</target> @@ -349,9 +388,6 @@ <source>Idle time between last detected change and execution of command</source> <target>Joutoaika edellisen muutoksen ja käskyn suorittamisen välillä</target> -<source>Command line</source> -<target>Komentokehote</target> - <source> The command is triggered if: - files or subfolders change @@ -375,9 +411,6 @@ Käsky suoritetaan jos: <source>RealtimeSync - Automated Synchronization</source> <target>RealtimeSync - Automaattisoitu täsmäytys</target> -<source>Warning</source> -<target>Varoitus</target> - <source>Build: %x</source> <target>Versio: %x</target> @@ -387,15 +420,21 @@ Käsky suoritetaan jos: <source>All files</source> <target>Kaikki tiedostot</target> +<source>Directory monitoring active</source> +<target>Hakemistovalvonta päällä</target> + +<source>Waiting until all directories are available...</source> +<target>Odota kunnes kaikki hakemistot on saatavilla...</target> + <source>&Restore</source> <target>&Palauta</target> +<source>&Show error</source> +<target>&Näytä virheet</target> + <source>&Exit</source> <target>&Poistu</target> -<source>Waiting for missing directories...</source> -<target>Odottaa puuttuvia hakemistoja...</target> - <source>Invalid command line:</source> <target>Virheellinen komentokehote:</target> @@ -405,14 +444,14 @@ Käsky suoritetaan jos: <source>File time and size</source> <target>Tiedoston aika ja koko</target> -<source> Two way </source> -<target> Molemmat </target> +<source>Two way</source> +<target>Molemmat</target> <source>Mirror</source> -<target>Peilaava </target> +<target>Peilaava</target> <source>Update</source> -<target>Päivittävä </target> +<target>Päivittävä</target> <source>Custom</source> <target>Oma määritelmä</target> @@ -468,11 +507,8 @@ Käsky suoritetaan jos: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>Näissä kohteissa on selvittämättömiä ristiriitoja, niitä ei täsmäytetä:</target> -<source>Significant difference detected:</source> -<target>Merkittävä eroavavuus todettu:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>Yli 50% tiedostoista kopioidaan tai poistetaan.</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>Hakemistoissa on oleelliset erot. Varmista että hakemistot on oikein valittu.</target> <source>Not enough free disk space available in:</source> <target>Vapaa levytila ei riitä:</target> @@ -492,12 +528,15 @@ Käsky suoritetaan jos: <source>Generating database...</source> <target>Tietokanta luodaan...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>Luodaan Volume Shadow Copy %x:lle...</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>Luo %x:lle Volume Shadow Copy ...</target> <source>Data verification error: %x and %y have different content.</source> <target>Tiedon verifiointie virhe: %x ja %y sisältö on erilainen.</target> +<source>job name</source> +<target>työnimi</target> + <source>Synchronization aborted</source> <target>Täsmäytys lopetettiin</target> @@ -522,6 +561,9 @@ Käsky suoritetaan jos: <source>Switching to FreeFileSync main dialog</source> <target>Siirry FreeFileSync perusikkunaan</target> +<source>Retrying operation after error:</source> +<target>Yritä virheen jälkeen uudestaan:</target> + <source>A new version of FreeFileSync is available:</source> <target>FreeFileSync:n uusi verio on saatavilla:</target> @@ -645,8 +687,8 @@ Käsky suoritetaan jos: <source>&Export file list...</source> <target>&Vie tiedostojoukko...</target> -<source>&Global settings...</source> -<target>&Yleiset asetukset...</target> +<source>&Global settings</source> +<target>&Yleiset asetukset</target> <source>&Tools</source> <target>&Asetukset</target> @@ -663,12 +705,6 @@ Käsky suoritetaan jos: <source>Compare</source> <target>Vertaile</target> -<source>Comparison settings</source> -<target>Vertailun asetukset</target> - -<source>Synchronization settings</source> -<target>Täsmäytyksen asetukset</target> - <source>Synchronize</source> <target>Täsmäytä</target> @@ -717,6 +753,9 @@ Käsky suoritetaan jos: <source>Synchronizing...</source> <target>Täsmäytetään...</target> +<source>Minimize to notification area</source> +<target>Pienennä huomiokenttään</target> + <source>On completion</source> <target>Valmistuttua</target> @@ -726,6 +765,15 @@ Käsky suoritetaan jos: <source>&Pause</source> <target>&Keskeytä</target> +<source>Variant</source> +<target>Vaihtoehto</target> + +<source>Statistics</source> +<target>Tilastot</target> + +<source>&Don't show this dialog again</source> +<target>&Älä näytä valitaa uudestaan</target> + <source>Select a variant</source> <target>Valitse tyyppi</target> @@ -774,6 +822,12 @@ on sama <source>Configure your own synchronization rules.</source> <target>Määritä omat täsmäytyssäännöt.</target> +<source>Detect moved files</source> +<target>Tunnista siirretyt tiedostot</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Vaatii tietokantaa. Ei toimi kaikissa käyttöjärjestelmissä.</target> + <source>Error handling</source> <target>Virheiden käsittely</target> @@ -798,16 +852,16 @@ on sama <source>Delete or overwrite files permanently</source> <target>Poista tai korvaa tiedostoja pysyvästi</target> -<source>Recycle Bin</source> +<source>Recycle bin</source> <target>Roskakori</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Käytä Roskakoria poistetuille/korvatille tiedostoille</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Tallenna poistetut/ylikirjoitetut tiedostot Roskakoriin</target> <source>Versioning</source> <target>Versiointi</target> -<source>Move files to user-defined folder</source> +<source>Move files to a user-defined folder</source> <target>Siirrä tiedostot määrättyyn hakemistoon</target> <source>Naming convention:</source> @@ -816,8 +870,8 @@ on sama <source>Batch job</source> <target>Eräajo</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Täsmäytyken automatisoinnen eräajotiedoston teko. Tehtävien ajoitus; Tuplaklikkaa tai ajoita tämä tiedosto: FreeFileSync.exe <job name>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Luo eräajo-tiedosto automaattiseen täsmäytykseen. Käynnista tuplaklickillä tai ajasta: %x</target> <source>Exit</source> <target>Poistu</target> @@ -840,30 +894,6 @@ on sama <source>Limit maximum number of log files</source> <target>Lokeja enintäin</target> -<source>Source code written in C++ using:</source> -<target>Koodikieli on C++ käyttäen:</target> - -<source>If you like FreeFileSync</source> -<target>Jos pidät FreeFileSync:tä</target> - -<source>Donate with PayPal</source> -<target>Lahjoita PayPal:lla</target> - -<source>Many thanks for localization:</source> -<target>Paljon kiitoksia kääntäjille:</target> - -<source>Feedback and suggestions are welcome</source> -<target>Palaute ja uudet ideat ovat tervetulleita</target> - -<source>Homepage</source> -<target>Kotisivu</target> - -<source>Email</source> -<target>S-posti</target> - -<source>Published under the GNU General Public License</source> -<target>Julkaistu lisenssillä GNU General Public License</target> - <source>Delete on both sides</source> <target>Poista molemmilta puolilta</target> @@ -871,12 +901,12 @@ on sama <target>Poista molemmin puolin, vaikka tiedosto on valittu vain toisella puolella</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -Vain tiedostot, jotka vastaavat kaikkia suodattimen asetuksia synkronoidaan. -Huom: Tiedostojen nimet täytyy olla suhteessa pää hakemistoihin. +Tiedostot synkronoidaan vain jos kaikki ehdot täyttyy. +HUOM: Tiedostopolku oltava suhteessa juurihakemistoon. </target> <source>Include</source> @@ -906,20 +936,20 @@ Huom: Tiedostojen nimet täytyy olla suhteessa pää hakemistoihin. <source>Fail-safe file copy</source> <target>Varmennettu tiedostokopiointi</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>Kirjoittaa ensin tilapäistiedostoon (*.ffs_tmp) ja nimeä sen uudestaan. Varmistaa eheyden myös Vakavan Virheen tapahtuessa.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>Kopio ensin välitiedostoon (*.ffs_tmp) ja nimeä sitten uudestaan. Varmistaa toimivuudet vakavan virheen tapahtuessa.</target> <source>Copy locked files</source> <target>Kopioi lukitut tiedostot</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Kopioi jaetut/lukitut tiedostot Volume Shadow Copy prosessilla (Vaatii Järjestelmävalvojan oikeuksia)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>Kopioi jaetut/lukitut tiedostot Volume Shadow Copy Service:lla (vaatii pääkäyttäjän oikeudet)</target> <source>Copy file access permissions</source> <target>Kopioi tiedoston käyttöoikeuksia</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Kopioi tiedosto ja hakemisto käyttöoikeuksia (Vaatii Järjestelmävalvojan oikeuksia)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>Vie tiedosto ja hakemisto ominaisuudet(vaatii pääkäyttäjän oikeudet)</target> <source>Restore hidden dialogs</source> <target>Palauta piiloitetut ikkunat</target> @@ -933,15 +963,6 @@ Huom: Tiedostojen nimet täytyy olla suhteessa pää hakemistoihin. <source>&Default</source> <target>&Vakio</target> -<source>Variant</source> -<target>Vaihtoehto</target> - -<source>Statistics</source> -<target>Tilastot</target> - -<source>Don't show this dialog again</source> -<target>Älä näytä tätä uudestaan</target> - <source>Find what:</source> <target>Etsi:</target> @@ -951,15 +972,45 @@ Huom: Tiedostojen nimet täytyy olla suhteessa pää hakemistoihin. <source>&Find next</source> <target>&Etsi seuraava</target> +<source>Source code written in C++ using:</source> +<target>Koodikieli on C++ käyttäen:</target> + +<source>If you like FreeFileSync</source> +<target>Jos pidät FreeFileSync:tä</target> + +<source>Donate with PayPal</source> +<target>Lahjoita PayPal:lla</target> + +<source>Feedback and suggestions are welcome</source> +<target>Palaute ja uudet ideat ovat tervetulleita</target> + +<source>Homepage</source> +<target>Kotisivu</target> + +<source>Email</source> +<target>S-posti</target> + +<source>Published under the GNU General Public License</source> +<target>Julkaistu lisenssillä GNU General Public License</target> + +<source>Many thanks for localization:</source> +<target>Paljon kiitoksia kääntäjille:</target> + +<source>Start synchronization</source> +<target>Käynnistä täsmäytys</target> + +<source>Comparison settings</source> +<target>Vertailun asetukset</target> + +<source>Synchronization settings</source> +<target>Täsmäytyksen asetukset</target> + <source>Delete</source> <target>Poista</target> <source>Configure filter</source> <target>Määritä suodin</target> -<source>Start synchronization</source> -<target>Käynnistä täsmäytys</target> - <source>Find</source> <target>Etsi</target> @@ -994,6 +1045,21 @@ Huom: Tiedostojen nimet täytyy olla suhteessa pää hakemistoihin. <target>Vertaile molemmat puolet</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>Haluatko varmasti suorittaa komentoa %y yhteen?</pluralform> +<pluralform>Haluatko varmasti suorittaa komentoa %y %x:n?</pluralform> +</target> + +<source>Confirm</source> +<target>Vahvista</target> + +<source>&Execute</source> +<target>&Suorita</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1029,12 +1095,15 @@ Huom: Tiedostojen nimet täytyy olla suhteessa pää hakemistoihin. <source>Include temporarily</source> <target>Sisällytä, tilapäisesti</target> -<source>Exclude via filter:</source> -<target>Sulje pois suotimella:</target> - <source>multiple selection</source> <target>monivalinta</target> +<source>Include via filter:</source> +<target>Lisää suotimella:</target> + +<source>Exclude via filter:</source> +<target>Sulje pois suotimella:</target> + <source>Include all</source> <target>Valitse kaikki</target> @@ -1080,8 +1149,8 @@ Huom: Tiedostojen nimet täytyy olla suhteessa pää hakemistoihin. <source>Do&n't save</source> <target>Äl&ä tallenna</target> -<source>Never save changes</source> -<target>Älä tallenna muutoksia</target> +<source>Never save &changes</source> +<target>Älä tallenna &muutoksia</target> <source>Show files that exist on left side only</source> <target>Näytä vain vasemmalla esiintyvät tiedostot</target> @@ -1134,8 +1203,8 @@ Huom: Tiedostojen nimet täytyy olla suhteessa pää hakemistoihin. <source>All folders are in sync</source> <target>Kaikki hakemistot täsmäytetty</target> -<source>Comma separated list</source> -<target>CSV-muotoinen lista</target> +<source>Comma-separated values</source> +<target>Pilkulla erotetut arvot</target> <source>File list exported</source> <target>Tiedostolista viety</target> @@ -1143,8 +1212,8 @@ Huom: Tiedostojen nimet täytyy olla suhteessa pää hakemistoihin. <source>Searching for program updates...</source> <target>Ohjelmapäivytys haetaa...</target> -<source>Ignore further errors</source> -<target>Hylkää toistuvat virheviestit</target> +<source>&Ignore subsequent errors</source> +<target>&Hylkää toistuvat virheet</target> <source>&Ignore</source> <target>&Unohda</target> @@ -1152,8 +1221,8 @@ Huom: Tiedostojen nimet täytyy olla suhteessa pää hakemistoihin. <source>Fatal Error</source> <target>Kohtalokas virhe</target> -<source>Don't show this warning again</source> -<target>Älä enää näytä varoitusta</target> +<source>&Don't show this warning again</source> +<target>&Älä enää näytä tätä varoitusta</target> <source>&Switch</source> <target>&Vaihda</target> @@ -1188,14 +1257,11 @@ Huom: Tiedostojen nimet täytyy olla suhteessa pää hakemistoihin. <source>Completed</source> <target>Valmis</target> -<source>Continue</source> -<target>Jatka</target> +<source>&Continue</source> +<target>&Jatka</target> -<source>Pause</source> -<target>Tauko</target> - -<source>Logging</source> -<target>Kirjaa</target> +<source>Log</source> +<target>Loki</target> <source>Cannot find %x</source> <target>En löydä %x</target> @@ -1231,12 +1297,12 @@ Huom: Tiedostojen nimet täytyy olla suhteessa pää hakemistoihin. <target>Suodin</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>Haluatko todella siirtää tätä Roskakoriin?</pluralform> -<pluralform>Haluatko todella siirtää nämä %x kohdetta Roskakoriin?</pluralform> +<pluralform>Haluatko varmasti siirtää kohde Roskakoriin?</pluralform> +<pluralform>Haluatko varmasti siirtää nämä %x kohteet Roskakoriin?</pluralform> </target> <source> @@ -1290,9 +1356,6 @@ Huom: Tiedostojen nimet täytyy olla suhteessa pää hakemistoihin. <source>Append a timestamp to each file name</source> <target>Lisää aikaleima tiedostoihin</target> -<source>Folder</source> -<target>Hakemisto</target> - <source>File</source> <target>Tiedosto</target> @@ -1413,8 +1476,8 @@ Huom: Tiedostojen nimet täytyy olla suhteessa pää hakemistoihin. <source>Cannot change process I/O priorities.</source> <target>Prosessin I/O -pririteetin muutos ei onnistu.</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>Ei voitu siirtää %x Roskakoriin.</target> +<source>Unable to move %x to the recycle bin.</source> +<target>%x siirto Roskakoriin epäonnistui.</target> <source>Cannot determine final path for %x.</source> <target>Polkua ei voida määrittää, %x.</target> diff --git a/BUILD/Languages/french.lng b/BUILD/Languages/french.lng index 0a720f41..ece832e9 100644 --- a/BUILD/Languages/french.lng +++ b/BUILD/Languages/french.lng @@ -25,14 +25,14 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Contrôle de la disponibilité de la Corbeille pour le dossier %x ...</target> -<source>Moving file %x to recycle bin</source> -<target>Envoi du fichier %x dans la corbeille</target> +<source>Moving file %x to the recycle bin</source> +<target>Déplacement du fichier %x vers la Corbeille<</target> -<source>Moving folder %x to recycle bin</source> -<target>Envoi du dossier %x dans la corbeille</target> +<source>Moving folder %x to the recycle bin</source> +<target>Déplacement du dossier %x vers la Corbeille<</target> -<source>Moving symbolic link %x to recycle bin</source> -<target>Envoi du lien symbolique %x dans la corbeille</target> +<source>Moving symbolic link %x to the recycle bin</source> +<target>Déplacement du lien symbolique %x vers la Corbeille</target> <source>Deleting file %x</source> <target>Suppression du fichier %x</target> @@ -43,14 +43,20 @@ <source>Deleting symbolic link %x</source> <target>Suppression du lien symbolique %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>La Corbeille est inaccessible pour les dossiers suivants. Les fichiers seront donc détruits définitivement.</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>La Corbeille n'est pas disponible por les dossiers suivants. Les fichiers seront détruits définitivement /</target> <source>An exception occurred</source> <target>Une erreur s'est produite</target> -<source>Cannot find file %x.</source> -<target>Impossible de trouver le fichier %x.</target> +<source>A directory path is expected after %x.</source> +<target>Un chemin est attendu après %x.</target> + +<source>Syntax error</source> +<target>Erreur de syntaxe</target> + +<source>Cannot open file %x.</source> +<target>Impossible d'ouvrir le fichier %x.</target> <source>Error</source> <target>Erreur</target> @@ -58,6 +64,36 @@ <source>File %x does not contain a valid configuration.</source> <target>Le fichier %x ne contient pas une configuration valide.</target> +<source>Unequal number of left and right directories specified.</source> +<target>Nombre incorrect de répertoires à gauche et à droite.</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>Le fichier de configuration ne peut pas contenir de paramètres au niveau de paires de répertoires quand ceux-ci sont définis par une ligne de commande.</target> + +<source>Warning</source> +<target>Attention</target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target>Les répertoires ne peuvent pas être définis pour plus d'un fichier de configuration.</target> + +<source>Syntax:</source> +<target>Syntaxe :</target> + +<source>config files</source> +<target>fichiers de configuration</target> + +<source>directory</source> +<target>répertoire</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>N'importe quel nombre de fichiers FreeFileSync .ffs_gui et/ou .ffs_batch.</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>N'importe quel nombre de répertoires alternatifs pour au plus un fichier de configuration.</target> + +<source>Command line</source> +<target>Ligne de commande</target> + <source>A folder input field is empty.</source> <target>Une entrée dossier est vide.</target> @@ -215,8 +251,8 @@ <target>Durée totale :</target> <source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </source> <target> <pluralform>%x octet</pluralform> @@ -242,12 +278,12 @@ <target>Lecture en cours :</target> <source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </source> <target> -<pluralform>[%x Tâche]</pluralform> -<pluralform>[%x Tâches]</pluralform> +<pluralform>%x tâche</pluralform> +<pluralform>%x tâches</pluralform> </target> <source>Encoding extended time information: %x</source> @@ -256,6 +292,9 @@ <source>/sec</source> <target>/sec</target> +<source>%x items</source> +<target>%x éléments</target> + <source>Configuration file %x loaded partially only.</source> <target>Le fichier de configuration %x a été chargé seulement partiellement.</target> @@ -268,8 +307,8 @@ <source>Browse directory</source> <target>Parcourir le répertoire</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Impossible d'accéder au service Volume Shadow Copy</target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target>Impossible d'accéder au service Volume Shadow Copy.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>Utilisez la version FreeFileSync 64-bit pour créer des "shadow copies" sur ce système.</target> @@ -280,8 +319,8 @@ <source>Cannot determine volume name for %x.</source> <target>Impossible de déterminer le nom du volume de %x.</target> -<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>Volume name %x is not part of file path %y.</source> +<target>Le nom de volume %x ne fait pas partie du chemin %y.</target> <source>Abort requested: Waiting for current operation to finish...</source> <target>Abandon demandé : En attente de la fin de l'opération en cours...</target> @@ -349,9 +388,6 @@ <source>Idle time between last detected change and execution of command</source> <target>Délai entre le dernier changement détecté et la dernière exécution de la commande</target> -<source>Command line</source> -<target>Ligne de commande</target> - <source> The command is triggered if: - files or subfolders change @@ -375,9 +411,6 @@ La commande est déclenchée si : <source>RealtimeSync - Automated Synchronization</source> <target>RealtimeSync - Synchronisation Automatisée</target> -<source>Warning</source> -<target>Attention</target> - <source>Build: %x</source> <target>Généré : %x</target> @@ -387,15 +420,21 @@ La commande est déclenchée si : <source>All files</source> <target>Tous les fichiers</target> +<source>Directory monitoring active</source> +<target>Gestion des répertoires active</target> + +<source>Waiting until all directories are available...</source> +<target>En attente de la disponibilité de tous les répertoires ...</target> + <source>&Restore</source> <target>&Restaurer</target> +<source>&Show error</source> +<target>&Afficher l'erreur</target> + <source>&Exit</source> <target>&Quitter</target> -<source>Waiting for missing directories...</source> -<target>En attente des répertoires absents ...</target> - <source>Invalid command line:</source> <target>Ligne de commande incorrecte :</target> @@ -405,14 +444,14 @@ La commande est déclenchée si : <source>File time and size</source> <target>Date et taille du fichier</target> -<source> Two way </source> -<target> Deux sens </target> +<source>Two way</source> +<target>Deux sens</target> <source>Mirror</source> -<target>Miroir </target> +<target>Miroir</target> <source>Update</source> -<target>Mise à Jour </target> +<target>Mise à Jour</target> <source>Custom</source> <target>Personnaliser</target> @@ -468,11 +507,8 @@ La commande est déclenchée si : <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>Les éléments suivants sont en conflit non résolu et ne seront pas synchronisés :</target> -<source>Significant difference detected:</source> -<target>Différence significative détectée :</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>Plus de 50% des fichiers seront copiés ou détruits.</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>Les dossiers suivants sont significativement différents. Assurez-vous que les dossiers correspondent avant de lancer la synchronisation.</target> <source>Not enough free disk space available in:</source> <target>Espace disque insuffisant sur :</target> @@ -492,12 +528,15 @@ La commande est déclenchée si : <source>Generating database...</source> <target>Génération de la base de données...</target> -<source>Creating Volume Shadow Copy for %x...</source> +<source>Creating a Volume Shadow Copy for %x...</source> <target>Création d'un Volume Shadow Copy pour %x ...</target> <source>Data verification error: %x and %y have different content.</source> <target>Erreur lors de la vérification des données : %x et %y ont des contenus différents.</target> +<source>job name</source> +<target>nom du job</target> + <source>Synchronization aborted</source> <target>Synchronisation abandonnée</target> @@ -522,6 +561,9 @@ La commande est déclenchée si : <source>Switching to FreeFileSync main dialog</source> <target>Passage à la fenêtre principale de FreeFileSync</target> +<source>Retrying operation after error:</source> +<target>Réessauer l'opération après erreur :</target> + <source>A new version of FreeFileSync is available:</source> <target>Une nouvelle version de FreeFileSync est disponible</target> @@ -645,8 +687,8 @@ La commande est déclenchée si : <source>&Export file list...</source> <target>&Exportation de la liste des fichiers...</target> -<source>&Global settings...</source> -<target>&Paramètres généraux...</target> +<source>&Global settings</source> +<target>&Paramètres généraux</target> <source>&Tools</source> <target>Ou&tils</target> @@ -717,6 +759,9 @@ La commande est déclenchée si : <source>Synchronizing...</source> <target>Synchronisation en cours...</target> +<source>Minimize to notification area</source> +<target>Réduction à la zone de notification</target> + <source>On completion</source> <target>À la fin</target> @@ -726,6 +771,15 @@ La commande est déclenchée si : <source>&Pause</source> <target>&Pause</target> +<source>Variant</source> +<target>Variante</target> + +<source>Statistics</source> +<target>Statistiques</target> + +<source>&Don't show this dialog again</source> +<target>&Ne plus afficher cette boîte de dialogue</target> + <source>Select a variant</source> <target>Choisir une variante</target> @@ -774,6 +828,12 @@ est identique <source>Configure your own synchronization rules.</source> <target>Paramétrage de vos règles de synchronisation.</target> +<source>Detect moved files</source> +<target>Détection des fichiers déplacés</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Exige les fichiers de la base de données. Non supporté par tous les systèmes de fichiers.</target> + <source>Error handling</source> <target>Erreur de gestion de fichiers</target> @@ -798,17 +858,17 @@ est identique <source>Delete or overwrite files permanently</source> <target>Supprimer ou écraser les fichiers définitivement</target> -<source>Recycle Bin</source> +<source>Recycle bin</source> <target>Corbeille</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Utiliser la corbeille pour les fichiers supprimés ou écrasés</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Sauvegarder les fichier détruits ou écrasés dans la Corbeille</target> <source>Versioning</source> <target>Gestion des versions</target> -<source>Move files to user-defined folder</source> -<target>Déplacer les fichiers vers un dossier choisi par l'utilisateur</target> +<source>Move files to a user-defined folder</source> +<target>Déplacer les fichiers vers un dossier utilisateur</target> <source>Naming convention:</source> <target>Convention de nommage :</target> @@ -816,8 +876,8 @@ est identique <source>Batch job</source> <target>Traitement batch</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Créer un fichier batch pour automatiser la synchronisation. Double-cliquez sur ce fichier ou entrez-le dans le planificateur de tâches : FreeFileSync.exe <job name>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Créer un fichier batch pour une synchronisation non assitée. Pour démarrer, double-cliquez sur ce fichier ou planifiez-le dans le gestionnaire des tâches : %x</target> <source>Exit</source> <target>Quitter</target> @@ -871,12 +931,12 @@ est identique <target>Suppression des deux côtés même si le fichier n'est sélectionné que d'un seul côté</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -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. +Les fichiers ne seront synchronisés que s'ils satisfont aux règles de filtrage. +Note : Les chemins doivent être relatifs aux répertoires de base. </target> <source>Include</source> @@ -906,20 +966,20 @@ Attention : les noms de fichiers doivent être relatifs aux répertoires de base <source>Fail-safe file copy</source> <target>Copie de fichiers sécurisé</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>Ecrit d'abord dans un fichier temporaire (*.ffs_tmp), puis le renomme. Ceci garantit la cohérence des données même en cas d'erreur fatale.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>Copie d'abord vers un fichier temporaire (*.ffs_tmp) puis le renomme. Cela garantit un état cohérent même en cas d'erreur fatale.</target> <source>Copy locked files</source> <target>Copier les fichiers verrouillés</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>La copie des fichiers partagés ou verrouillés nécessite le Service Volume Shadow Copy (avec les droits administrateur)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>Copie de fichiers partagés ou verrouillés à l'aide du service Volume Shadow Copy (exige les droits d'administrateur)</target> <source>Copy file access permissions</source> <target>Copie des droits d'accès aux fichiers</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Transférer les permissions des fichiers et des dossiers (Nécessite les droits administrateur)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>Transfert des autorisations de fichier et de dossier (exige les droits d'administrateur)</target> <source>Restore hidden dialogs</source> <target>Afficher les boîtes de dialogue masquées</target> @@ -933,15 +993,6 @@ Attention : les noms de fichiers doivent être relatifs aux répertoires de base <source>&Default</source> <target>&Défaut</target> -<source>Variant</source> -<target>Variante</target> - -<source>Statistics</source> -<target>Statistiques</target> - -<source>Don't show this dialog again</source> -<target>Ne plus afficher cette boîte de dialogue</target> - <source>Find what:</source> <target>Chercher cela :</target> @@ -951,15 +1002,15 @@ Attention : les noms de fichiers doivent être relatifs aux répertoires de base <source>&Find next</source> <target>&Chercher le suivant</target> +<source>Start synchronization</source> +<target>Démarrer la synchronisation</target> + <source>Delete</source> <target>Supprimer</target> <source>Configure filter</source> <target>Configuration des filtres</target> -<source>Start synchronization</source> -<target>Démarrer la synchronisation</target> - <source>Find</source> <target>Chercher</target> @@ -994,6 +1045,21 @@ Attention : les noms de fichiers doivent être relatifs aux répertoires de base <target>Comparer les deux listes</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>Etes-vous sûr de vouloir exécuter la commande %y pour %x élément ?</pluralform> +<pluralform>Etes-vous sûr de vouloir exécuter la commande %y pour %x éléments ?</pluralform> +</target> + +<source>Confirm</source> +<target>Confirmer</target> + +<source>&Execute</source> +<target>&Exécuter</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1029,12 +1095,15 @@ Attention : les noms de fichiers doivent être relatifs aux répertoires de base <source>Include temporarily</source> <target>Inclure temporairement</target> -<source>Exclude via filter:</source> -<target>Exclure à l'aide du filtre :</target> - <source>multiple selection</source> <target>sélection multiple</target> +<source>Include via filter:</source> +<target>Inclure via le filtre :</target> + +<source>Exclude via filter:</source> +<target>Exclure à l'aide du filtre :</target> + <source>Include all</source> <target>Inclure tout</target> @@ -1080,8 +1149,8 @@ Attention : les noms de fichiers doivent être relatifs aux répertoires de base <source>Do&n't save</source> <target>&Ne pas Sauvegarder</target> -<source>Never save changes</source> -<target>Ne jamais enregistrer les modifications</target> +<source>Never save &changes</source> +<target>Ne jamais sauvegarder les &modifications</target> <source>Show files that exist on left side only</source> <target>Afficher les fichiers existant seulement à gauche</target> @@ -1134,8 +1203,8 @@ Attention : les noms de fichiers doivent être relatifs aux répertoires de base <source>All folders are in sync</source> <target>Tous les dossiers sont synchronisés</target> -<source>Comma separated list</source> -<target>Liste d'éléments séparés par une virgule</target> +<source>Comma-separated values</source> +<target>Valeurs séparées par une virgule</target> <source>File list exported</source> <target>Liste des fichiers exportée</target> @@ -1143,8 +1212,8 @@ Attention : les noms de fichiers doivent être relatifs aux répertoires de base <source>Searching for program updates...</source> <target>Recherche de mises à jour ...</target> -<source>Ignore further errors</source> -<target>Ignorer les erreurs suivantes</target> +<source>&Ignore subsequent errors</source> +<target>&Ignorer les erreurs suivantes</target> <source>&Ignore</source> <target>&Ignorer</target> @@ -1152,8 +1221,8 @@ Attention : les noms de fichiers doivent être relatifs aux répertoires de base <source>Fatal Error</source> <target>Erreur Fatale</target> -<source>Don't show this warning again</source> -<target>Ne plus afficher cet avertissement</target> +<source>&Don't show this warning again</source> +<target>&Ne plus afficher cet avertissement</target> <source>&Switch</source> <target>&Changer</target> @@ -1188,14 +1257,11 @@ Attention : les noms de fichiers doivent être relatifs aux répertoires de base <source>Completed</source> <target>Terminé</target> -<source>Continue</source> -<target>Continuer</target> +<source>&Continue</source> +<target>&Continuer</target> -<source>Pause</source> -<target>Pause</target> - -<source>Logging</source> -<target>Connexion</target> +<source>Log</source> +<target>Log</target> <source>Cannot find %x</source> <target>Impossible de trouver %x</target> @@ -1231,12 +1297,12 @@ Attention : les noms de fichiers doivent être relatifs aux répertoires de base <target>Filtre</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>Voulez-vous vraiment mettre dans la corbeille %x élément ?</pluralform> -<pluralform>Voulez-vous vraiment mettre dans la corbeille ces %x éléments ?</pluralform> +<pluralform>Etes-vous sûr de vouloir mettre à la Corbeille %x élément suivant ?</pluralform> +<pluralform>Etes-vous sûr de vouloir mettre à la Corbeille les %x éléments suivants ?</pluralform> </target> <source> @@ -1290,9 +1356,6 @@ Attention : les noms de fichiers doivent être relatifs aux répertoires de base <source>Append a timestamp to each file name</source> <target>Ajouter un horodatage à chaque fichier</target> -<source>Folder</source> -<target>Dossier</target> - <source>File</source> <target>Fichier</target> @@ -1413,7 +1476,7 @@ Attention : les noms de fichiers doivent être relatifs aux répertoires de base <source>Cannot change process I/O priorities.</source> <target>Impossible de modifier les priorités E/S des tâches</target> -<source>Unable to move %x to the Recycle Bin.</source> +<source>Unable to move %x to the recycle bin.</source> <target>Impossible de déplacer %x dans la Corbeille.</target> <source>Cannot determine final path for %x.</source> diff --git a/BUILD/Languages/german.lng b/BUILD/Languages/german.lng index 35c30a34..cd78dc28 100644 --- a/BUILD/Languages/german.lng +++ b/BUILD/Languages/german.lng @@ -25,13 +25,13 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Prüfe Verfügbarkeit des Papierkorbs für Ordner %x...</target> -<source>Moving file %x to recycle bin</source> +<source>Moving file %x to the recycle bin</source> <target>Verschiebe Datei %x in den Papierkorb</target> -<source>Moving folder %x to recycle bin</source> +<source>Moving folder %x to the recycle bin</source> <target>Verschiebe Ordner %x in den Papierkorb</target> -<source>Moving symbolic link %x to recycle bin</source> +<source>Moving symbolic link %x to the recycle bin</source> <target>Verschiebe Symbolischen Link %x in den Papierkorb</target> <source>Deleting file %x</source> @@ -43,7 +43,7 @@ <source>Deleting symbolic link %x</source> <target>Lösche Symbolischen Link %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> <target>Der Papierkorb ist für die folgenden Ordner nicht verfügbar. Die Dateien werden stattdessen permanent gelöscht:</target> <source>An exception occurred</source> @@ -290,7 +290,7 @@ <target>Speichere erweiterte Zeitinformation: %x</target> <source>/sec</source> -<target>/s</target> +<target>/sek</target> <source>%x items</source> <target>%x Elemente</target> @@ -307,7 +307,7 @@ <source>Browse directory</source> <target>Verzeichnis öffnen</target> -<source>Cannot access Volume Shadow Copy Service.</source> +<source>Cannot access the Volume Shadow Copy Service.</source> <target>Auf den Volumenschattenkopiedienst kann nicht zugegriffen werden.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> @@ -528,12 +528,15 @@ Die Befehlszeile wird ausgelöst, wenn: <source>Generating database...</source> <target>Erzeuge Synchronisationsdatenbank...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>Erstelle Volumenschattenkopie für %x...</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>Erstelle eine Volumenschattenkopie für %x...</target> <source>Data verification error: %x and %y have different content.</source> <target>Verifizierungsfehler: %x und %y haben unterschiedlichen Inhalt.</target> +<source>job name</source> +<target>Auftragsname</target> + <source>Synchronization aborted</source> <target>Synchronisation abgebrochen</target> @@ -670,7 +673,7 @@ Die Befehlszeile wird ausgelöst, wenn: <target>&Speichern</target> <source>Save as &batch job...</source> -<target>Speichern als &Batch-Job...</target> +<target>Speichern als &Batch-Auftrag...</target> <source>1. &Compare</source> <target>1. &Vergleichen</target> @@ -684,8 +687,8 @@ Die Befehlszeile wird ausgelöst, wenn: <source>&Export file list...</source> <target>Dateiliste e&xportieren...</target> -<source>&Global settings...</source> -<target>&Globale Einstellungen...</target> +<source>&Global settings</source> +<target>&Globale Einstellungen</target> <source>&Tools</source> <target>E&xtras</target> @@ -702,12 +705,6 @@ Die Befehlszeile wird ausgelöst, wenn: <source>Compare</source> <target>Vergleichen</target> -<source>Comparison settings</source> -<target>Vergleichseinstellungen</target> - -<source>Synchronization settings</source> -<target>Synchronisationseinstellungen</target> - <source>Synchronize</source> <target>Synchronisieren</target> @@ -720,8 +717,17 @@ Die Befehlszeile wird ausgelöst, wenn: <source>Swap sides</source> <target>Seiten vertauschen</target> +<source>Close search bar</source> +<target>Suchleiste schließen</target> + +<source>Find what:</source> +<target>Suchen nach:</target> + +<source>Match case</source> +<target>Groß-/Kleinschreibung</target> + <source>Save as batch job</source> -<target>Als Batch-Job speichern</target> +<target>Als Batch-Auftrag speichern</target> <source>Hide excluded items</source> <target>Ausgeschlossene Elemente verstecken</target> @@ -774,8 +780,8 @@ Die Befehlszeile wird ausgelöst, wenn: <source>Statistics</source> <target>Statistiken</target> -<source>Don't show this dialog again</source> -<target>Diesen Dialog nicht mehr anzeigen</target> +<source>&Don't show this dialog again</source> +<target>&Diesen Dialog nicht mehr anzeigen</target> <source>Select a variant</source> <target>Variante auswählen</target> @@ -825,6 +831,12 @@ gleich ist <source>Configure your own synchronization rules.</source> <target>Eigene Synchronisationsregeln definieren.</target> +<source>Detect moved files</source> +<target>Verschobene Dateien erkennen</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Benötigt Datenbankdateien. Wird nicht von allen Dateisystemen unterstützt.</target> + <source>Error handling</source> <target>Fehlerbehandlung</target> @@ -849,26 +861,26 @@ gleich ist <source>Delete or overwrite files permanently</source> <target>Dateien endgültig löschen oder überschreiben</target> -<source>Recycle Bin</source> +<source>Recycle bin</source> <target>Papierkorb</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Verwende den Papierkorb für gelöschte und überschriebene Dateien</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Gelöschte und überschriebene Dateien im Papierkorb sichern</target> <source>Versioning</source> <target>Versionierung</target> -<source>Move files to user-defined folder</source> -<target>Dateien in den benutzerdefinierten Ordner verschieben</target> +<source>Move files to a user-defined folder</source> +<target>Dateien in einen benutzerdefinierten Ordner verschieben</target> <source>Naming convention:</source> <target>Namenskonvention:</target> <source>Batch job</source> -<target>Batch-Job</target> +<target>Batch-Auftrag</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Erstellt eine Batchdatei für die automatisierte Synchronisation. Anschließend die Datei doppelklicken oder in den Taskplaner des Betriebssystems eintragen: FreeFileSync.exe <Jobname>.ffs_batch.</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Erstellt eine Batchdatei für die unbeaufsichtigte Synchronisation. Zum Starten die Datei doppelklicken oder in einen Taskplaner eintragen: %x</target> <source>Exit</source> <target>Beenden</target> @@ -891,30 +903,6 @@ gleich ist <source>Limit maximum number of log files</source> <target>Maximale Anzahl der Logdateien begrenzen</target> -<source>Source code written in C++ using:</source> -<target>Sourcecode in C++ geschrieben mit Hilfe von:</target> - -<source>If you like FreeFileSync</source> -<target>Wenn Sie FreeFileSync mögen</target> - -<source>Donate with PayPal</source> -<target>Mit PayPal spenden</target> - -<source>Many thanks for localization:</source> -<target>Vielen Dank für die Lokalisation:</target> - -<source>Feedback and suggestions are welcome</source> -<target>Feedback und Vorschläge sind willkommen</target> - -<source>Homepage</source> -<target>Homepage</target> - -<source>Email</source> -<target>Email</target> - -<source>Published under the GNU General Public License</source> -<target>Veröffentlicht unter der Allgemeinen Öffentlichen GNU-Lizenz</target> - <source>Delete on both sides</source> <target>Auf beiden Seiten löschen</target> @@ -922,12 +910,12 @@ gleich ist <target>Lösche auf beiden Seiten, auch wenn die Datei nur auf einer Seite markiert ist</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -Nur Dateien, die zu allen Filtereinstellungen passen, werden synchronisiert. -Achtung: Dateinamen müssen relativ zu den Basisverzeichnissen sein. +Es werden nur Dateien synchronisiert, die zu allen Filterregeln passen. +Achtung: Dateipfade müssen relativ zu den Basisverzeichnissen sein. </target> <source>Include</source> @@ -957,20 +945,20 @@ Achtung: Dateinamen müssen relativ zu den Basisverzeichnissen sein. <source>Fail-safe file copy</source> <target>Dateien ausfallsicher kopieren</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>Schreibe zunächst in eine temporäre Datei (*.ffs_tmp) und benenne diese anschließend um. Dadurch wird ein konsistenter Status auch im größten Fehlerfall sichergestellt.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>Kopiere zunächst in eine temporäre Datei (*.ffs_tmp) und benenne diese anschließend um. Dadurch wird ein konsistenter Datenstand auch im größten Fehlerfall garantiert.</target> <source>Copy locked files</source> <target>Gesperrte Dateien kopieren</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Kopiere gesperrte Dateien mit Hilfe des Volumenschattenkopie-Dienstes (Benötigt Administratorrechte)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>Kopiere gesperrte Dateien mit Hilfe des Volumenschattenkopie-Dienstes (benötigt Administratorrechte)</target> <source>Copy file access permissions</source> <target>Dateizugriffsberechtigungen kopieren</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Ãœbertrage Datei- und Ordnerberechtigungen (Benötigt Administratorrechte)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>Ãœbertrage Datei- und Ordnerberechtigungen (benötigt Administratorrechte)</target> <source>Restore hidden dialogs</source> <target>Versteckte Dialoge wiederherstellen</target> @@ -984,26 +972,44 @@ Achtung: Dateinamen müssen relativ zu den Basisverzeichnissen sein. <source>&Default</source> <target>&Standard</target> -<source>Find what:</source> -<target>Suchen nach:</target> +<source>Source code written in C++ using:</source> +<target>Sourcecode in C++ geschrieben mit Hilfe von:</target> -<source>Match case</source> -<target>Groß-/Kleinschreibung</target> +<source>If you like FreeFileSync</source> +<target>Wenn Sie FreeFileSync mögen</target> -<source>&Find next</source> -<target>&Weitersuchen</target> +<source>Donate with PayPal</source> +<target>Mit PayPal spenden</target> + +<source>Feedback and suggestions are welcome</source> +<target>Feedback und Vorschläge sind willkommen</target> + +<source>Homepage</source> +<target>Homepage</target> + +<source>Email</source> +<target>Email</target> + +<source>Published under the GNU General Public License</source> +<target>Veröffentlicht unter der Allgemeinen Öffentlichen GNU-Lizenz</target> + +<source>Many thanks for localization:</source> +<target>Vielen Dank für die Lokalisation:</target> <source>Start synchronization</source> <target>Synchronisation starten</target> +<source>Comparison settings</source> +<target>Vergleichseinstellungen</target> + +<source>Synchronization settings</source> +<target>Synchronisationseinstellungen</target> + <source>Delete</source> <target>Löschen</target> <source>Configure filter</source> -<target>Konfiguriere Filter</target> - -<source>Find</source> -<target>Suchen</target> +<target>Filter konfigurieren</target> <source>Select time span</source> <target>Zeitspanne auswählen</target> @@ -1011,6 +1017,9 @@ Achtung: Dateinamen müssen relativ zu den Basisverzeichnissen sein. <source>Folder pairs</source> <target>Ordnerpaare</target> +<source>Find</source> +<target>Suchen</target> + <source>Overview</source> <target>Ãœbersicht</target> @@ -1050,9 +1059,6 @@ Achtung: Dateinamen müssen relativ zu den Basisverzeichnissen sein. <source>&Execute</source> <target>&Ausführen</target> -<source>&Don't show this dialog again</source> -<target>&Diesen Dialog nicht mehr anzeigen</target> - <source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> @@ -1083,17 +1089,20 @@ Achtung: Dateinamen müssen relativ zu den Basisverzeichnissen sein. <source>Set direction:</source> <target>Setze Richtung:</target> -<source>Exclude temporarily</source> -<target>Temporär ausschließen</target> +<source>multiple selection</source> +<target>Mehrfachauswahl</target> -<source>Include temporarily</source> -<target>Temporär einschließen</target> +<source>Include via filter:</source> +<target>Ãœber Filter einschließen:</target> <source>Exclude via filter:</source> <target>Ãœber Filter ausschließen:</target> -<source>multiple selection</source> -<target>Mehrfachauswahl</target> +<source>Exclude temporarily</source> +<target>Temporär ausschließen</target> + +<source>Include temporarily</source> +<target>Temporär einschließen</target> <source>Include all</source> <target>Alle einschließen</target> @@ -1140,8 +1149,8 @@ Achtung: Dateinamen müssen relativ zu den Basisverzeichnissen sein. <source>Do&n't save</source> <target>&Nicht speichern</target> -<source>Never save changes</source> -<target>Änderungen nie speichern</target> +<source>Never save &changes</source> +<target>Änderungen nie &speichern</target> <source>Show files that exist on left side only</source> <target>Nur links existierende Dateien anzeigen</target> @@ -1194,6 +1203,9 @@ Achtung: Dateinamen müssen relativ zu den Basisverzeichnissen sein. <source>All folders are in sync</source> <target>Alle Ordner sind synchron</target> +<source>Cannot find %x</source> +<target>%x wurde nicht gefunden.</target> + <source>Comma-separated values</source> <target>Kommagetrennte Werte</target> @@ -1203,8 +1215,8 @@ Achtung: Dateinamen müssen relativ zu den Basisverzeichnissen sein. <source>Searching for program updates...</source> <target>Suche nach aktualisierten Programmversionen...</target> -<source>Ignore further errors</source> -<target>Weitere Fehler ignorieren</target> +<source>&Ignore subsequent errors</source> +<target>&Nachfolgende Fehler ignorieren</target> <source>&Ignore</source> <target>&Ignorieren</target> @@ -1212,8 +1224,8 @@ Achtung: Dateinamen müssen relativ zu den Basisverzeichnissen sein. <source>Fatal Error</source> <target>Schwerer Fehler</target> -<source>Don't show this warning again</source> -<target>Diese Warnung nicht mehr anzeigen</target> +<source>&Don't show this warning again</source> +<target>&Diese Warnung nicht mehr anzeigen</target> <source>&Switch</source> <target>&Wechseln</target> @@ -1254,9 +1266,6 @@ Achtung: Dateinamen müssen relativ zu den Basisverzeichnissen sein. <source>Log</source> <target>Protokoll</target> -<source>Cannot find %x</source> -<target>%x wurde nicht gefunden.</target> - <source>Inactive</source> <target>Inaktiv</target> @@ -1288,8 +1297,8 @@ Achtung: Dateinamen müssen relativ zu den Basisverzeichnissen sein. <target>Filter</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> <pluralform>Soll das folgende Element wirklich in den Papierkorb verschoben werden?</pluralform> @@ -1467,7 +1476,7 @@ Achtung: Dateinamen müssen relativ zu den Basisverzeichnissen sein. <source>Cannot change process I/O priorities.</source> <target>Die Eingabe/Ausgabe Prioritäten für den Prozess konnten nicht geändert werden.</target> -<source>Unable to move %x to the Recycle Bin.</source> +<source>Unable to move %x to the recycle bin.</source> <target>%x kann nicht in den Papierkorb verschoben werden.</target> <source>Cannot determine final path for %x.</source> diff --git a/BUILD/Languages/greek.lng b/BUILD/Languages/greek.lng index dc22668c..96df2f6b 100644 --- a/BUILD/Languages/greek.lng +++ b/BUILD/Languages/greek.lng @@ -1,6 +1,6 @@ <header> <language>Eλληνικά</language> - <translator>ΓιώÏγος Γιαγλής</translator> + <translator>ΓιώÏγος Δ. Γιαγλής</translator> <locale>el_GR</locale> <flag_image>flag_greece.png</flag_image> <plural_form_count>2</plural_form_count> @@ -25,13 +25,13 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Έλεγχος της διαθεσιμότητας του κάδου ανακÏκλωσης για τον υποκατάλογο %x...</target> -<source>Moving file %x to recycle bin</source> +<source>Moving file %x to the recycle bin</source> <target>ΜεταφοÏά του αÏχείου %x στον κάδο ανακÏκλωσης</target> -<source>Moving folder %x to recycle bin</source> +<source>Moving folder %x to the recycle bin</source> <target>ΜεταφοÏά του υποκαταλόγου %x στον κάδο ανακÏκλωσης</target> -<source>Moving symbolic link %x to recycle bin</source> +<source>Moving symbolic link %x to the recycle bin</source> <target>ΜεταφοÏά του ÏƒÏ…Î¼Î²Î¿Î»Î¹ÎºÎ¿Ï Î´ÎµÏƒÎ¼Î¿Ï %x στον κάδο ανακÏκλωσης</target> <source>Deleting file %x</source> @@ -43,14 +43,20 @@ <source>Deleting symbolic link %x</source> <target>ΔιαγÏαφή του ÏƒÏ…Î¼Î²Î¿Î»Î¹ÎºÎ¿Ï Î´ÎµÏƒÎ¼Î¿Ï %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>Ο Κάθος ΑνακÏκλωσης δεν είναι διαθÎσιμος στους παÏακάτω υποκαταλόγους. Τα αÏχεία θα διαγÏαφοÏν μόνιμα:</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>Ο κάδος ανακÏκλωσης δεν είναι διαθÎσιμος για τους ακόλουθους υποκαταλόγους. Τα αÏχεία θα διαγÏαφοÏν μόνιμα:</target> <source>An exception occurred</source> <target>ΠαÏουσιάστηκε σφάλμα</target> -<source>Cannot find file %x.</source> -<target>Το αÏχείο %x δε βÏÎθηκε.</target> +<source>A directory path is expected after %x.</source> +<target>ΑναμÎνεται μια διαδÏομή υποκαταλόγου μετά το %x.</target> + +<source>Syntax error</source> +<target>Σφάλμα σÏνταξης</target> + +<source>Cannot open file %x.</source> +<target>Δεν είναι δυνατό το άνοιγμα του αÏχείου %x.</target> <source>Error</source> <target>Σφάλματα</target> @@ -58,6 +64,36 @@ <source>File %x does not contain a valid configuration.</source> <target>Το αÏχείο %x δεν πεÏιÎχει μια ÎγκυÏη διάταξη.</target> +<source>Unequal number of left and right directories specified.</source> +<target>Έχει οÏιστεί άνισος αÏιθμός υποκαταλόγων δεξιά από ÏŒ,τι αÏιστεÏά.</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>Το αÏχείο διάταξης δεν Ï€ÏÎπει να πεÏιλαμβάνει Ïυθμίσεις στο επίπεδο του ζεÏγους των υποκαταλόγων, όταν οι υποκατάλογοι οÏίζονται μÎσω της γÏαμμής εÏγασιών.</target> + +<source>Warning</source> +<target>Î Ïοειδοποίηση</target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target>Δεν μποÏοÏν να οÏιστοÏν υποκατάλογοι για πεÏισσότεÏα από Îνα αÏχεία διάταξης.</target> + +<source>Syntax:</source> +<target>ΣÏνταξη:</target> + +<source>config files</source> +<target>αÏχεία διάταξης</target> + +<source>directory</source> +<target>υποκατάλογος</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>Οποιοσδήποτε αÏιθμός αÏχείων διάταξης .ffs_gui ή/και .ffs_batch του FreeFileSync</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>Οποιοσδήποτε αÏιθμός εναλλακτικών υποκαταλόγων για το Ï€Î¿Î»Ï Îνα αÏχείο διάταξης.</target> + +<source>Command line</source> +<target>ΓÏαμμή εντολών</target> + <source>A folder input field is empty.</source> <target>Ένα πεδίο εισαγωγής υποκαταλόγων είναι άδειο.</target> @@ -215,12 +251,12 @@ <target>Συνολική διάÏκεια:</target> <source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </source> <target> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </target> <source>%x MB</source> @@ -242,12 +278,12 @@ <target>Ανίχνευση:</target> <source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </source> <target> -<pluralform>[1 Îήμα]</pluralform> -<pluralform>[%x Îήματα]</pluralform> +<pluralform>1 νήμα</pluralform> +<pluralform>%x νήματα</pluralform> </target> <source>Encoding extended time information: %x</source> @@ -256,6 +292,9 @@ <source>/sec</source> <target>/δευτεÏόλεπτο</target> +<source>%x items</source> +<target>%x αντικείμενα</target> + <source>Configuration file %x loaded partially only.</source> <target>Το αÏχείο διάταξης %x Îχει φοÏτωθεί μόνο κατά Îνα μÎÏος.</target> @@ -268,8 +307,8 @@ <source>Browse directory</source> <target>Αναζήτηση υποκαταλόγου</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Δεν Ï€Îτυχε η Ï€Ïόσφαση στην ΥπηÏεσεία Σκιώδους ΑντίγÏαφου Τόμου.</target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target>Δεν είναι δυνατή η Ï€Ïόσβαση στην ΥπηÏεσία Σκιώδους ΑντίγÏαφου Τόμου.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>ΧÏησιμοποιήστε την 64-μπιτη Îκδοση του FreeFileSync για να δημιουÏγήσετε σκιώδη αντίγÏαφα σε αυτόν τον υπολογιστή.</target> @@ -280,8 +319,8 @@ <source>Cannot determine volume name for %x.</source> <target>Δεν μποÏεί να Ï€ÏοσδιοÏιστεί το όνομα τόμου για το %x.</target> -<source>Volume name %x not part of file name %y.</source> -<target>Το όνομα τόμου %x δεν είναι μÎÏος του ονόματος του αÏχείου %y.</target> +<source>Volume name %x is not part of file path %y.</source> +<target>Το όνομα τόμου %x δεν είναι μÎÏος της διαδÏομής %y.</target> <source>Abort requested: Waiting for current operation to finish...</source> <target>Ζητήθηκε ματαίωση: Αναμονή για την λήξη της Ï„ÏÎχουσας εÏγασίας...</target> @@ -349,9 +388,6 @@ <source>Idle time between last detected change and execution of command</source> <target>Λανθάνων χÏόνος Î¼ÎµÏ„Î±Î¾Ï Ï„ÎµÎ»ÎµÏ…Ï„Î±Î¯Î±Ï‚ αλλαγής που ανιχνεÏθηκε και εκτÎλεσης της εντολής</target> -<source>Command line</source> -<target>ΓÏαμμή εντολών</target> - <source> The command is triggered if: - files or subfolders change @@ -375,9 +411,6 @@ The command is triggered if: <source>RealtimeSync - Automated Synchronization</source> <target>RealtimeSync - ΑυτοματοποιημÎνος ΣυγχÏονισμός</target> -<source>Warning</source> -<target>Î Ïοειδοποίηση</target> - <source>Build: %x</source> <target>ΔημιουÏγήθηκε : %x</target> @@ -387,15 +420,21 @@ The command is triggered if: <source>All files</source> <target>Όλα τα αÏχεία</target> +<source>Directory monitoring active</source> +<target>Η παÏακολοÏθηση των υποκαταλόγων είναι ενεÏγή</target> + +<source>Waiting until all directories are available...</source> +<target>Αναμονή μÎχÏι να είναι διαθÎσιμοι όλοι οι υποκατάλογοι...</target> + <source>&Restore</source> <target>&ΕπαναφοÏά</target> +<source>&Show error</source> +<target>&Εμφάνιση σφάλματος</target> + <source>&Exit</source> <target>Έ&ξοδος</target> -<source>Waiting for missing directories...</source> -<target>Αναμονή για τους υποκαταλόγους που απουσιάζουν...</target> - <source>Invalid command line:</source> <target>Σφάλμα στη γÏαμμή εντολών:</target> @@ -405,14 +444,14 @@ The command is triggered if: <source>File time and size</source> <target>ΗμεÏομηνία και μÎγεθος αÏχείων</target> -<source> Two way </source> -<target> Διπλής κατεÏθυνσης </target> +<source>Two way</source> +<target>Διπλής κατεÏθυνσης</target> <source>Mirror</source> -<target>ΚατοπτÏισμός </target> +<target>ΚατοπτÏισμός</target> <source>Update</source> -<target>ΕνημÎÏωση </target> +<target>ΕνημÎÏωση</target> <source>Custom</source> <target>Εξατομίκευση</target> @@ -468,11 +507,8 @@ The command is triggered if: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>Τα ακόλουθα στοιχεία Îχουν ανεπίλυτες διενÎξεις και δε θα συγχÏονιστοÏν:</target> -<source>Significant difference detected:</source> -<target>ΑνιχνεÏθηκαν σημαντικÎÏ‚ διαφοÏÎÏ‚:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>ΠεÏισσότεÏα από το 50% των αÏχείων θα αντιγÏαφοÏν ή διαγÏαφοÏν.</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>Οι ακόλουθοι υποκατάλογοι είναι σημαντικά διαφοÏετικοί. ΣιγουÏευτείτε ότι Îχετε επιλÎξει τους κατάλληλους υποκαταλόγους για συγχÏονισμό.</target> <source>Not enough free disk space available in:</source> <target>Δεν υπάÏχει αÏκετός διαθÎσιμος χώÏος στο δίσκο:</target> @@ -492,11 +528,14 @@ The command is triggered if: <source>Generating database...</source> <target>ΔημιουÏγία βάσης δεδομÎνων...</target> -<source>Creating Volume Shadow Copy for %x...</source> +<source>Creating a Volume Shadow Copy for %x...</source> <target>ΔημιουÏγία Σκιώδους ΑντίγÏαφου Τόμου για το %x...</target> <source>Data verification error: %x and %y have different content.</source> -<target>Λάθος επαλήθευσης δεδομÎνων: το %x και το %y Îχουν διαφοÏετικό πεÏιεχόμενο.</target> +<target>Σφάλμα επαλήθευσης δεδομÎνων: το %x και το %y Îχουν διαφοÏετικό πεÏιεχόμενο.</target> + +<source>job name</source> +<target>όνομα ενÎÏγειας</target> <source>Synchronization aborted</source> <target>Ο συγχÏονισμός ματαιώθηκε</target> @@ -522,6 +561,9 @@ The command is triggered if: <source>Switching to FreeFileSync main dialog</source> <target>Εναλλαγή στο βασικό παÏάθυÏο του FreeFileSync</target> +<source>Retrying operation after error:</source> +<target>Επανάληψη της Ï€Ïοσπάθειας μετά από σφάλμα:</target> + <source>A new version of FreeFileSync is available:</source> <target>Μια νÎα Îκδοση του FreeFileSync είναι διαθÎσιμη:</target> @@ -645,8 +687,8 @@ The command is triggered if: <source>&Export file list...</source> <target>Ε&ξαγωγή καταλόγου αÏχείων...</target> -<source>&Global settings...</source> -<target>ΓενικÎÏ‚ &Ïυθμίσεις...</target> +<source>&Global settings</source> +<target>ΓενικÎÏ‚ &Ïυθμίσεις</target> <source>&Tools</source> <target>&ΕÏγαλεία</target> @@ -717,6 +759,9 @@ The command is triggered if: <source>Synchronizing...</source> <target>Γίνεται συγχÏονισμός...</target> +<source>Minimize to notification area</source> +<target>Ελαχιστοποίηση στην πεÏιοχή ειδοποιήσεων</target> + <source>On completion</source> <target>Μετά την ολοκλήÏωση</target> @@ -726,6 +771,15 @@ The command is triggered if: <source>&Pause</source> <target>&ΠαÏση</target> +<source>Variant</source> +<target>ÎœÎθοδος</target> + +<source>Statistics</source> +<target>Στατιστικά</target> + +<source>&Don't show this dialog again</source> +<target>&Îα μην εμφανιστεί ξανά αυτό το μήνυμα</target> + <source>Select a variant</source> <target>ΕπιλÎξτε μια μÎθοδο</target> @@ -774,6 +828,12 @@ is the same <source>Configure your own synchronization rules.</source> <target>ΟÏίστε τους δικοÏÏ‚ σας κανόνες συγχÏονισμοÏ.</target> +<source>Detect moved files</source> +<target>Ανίχνευση των αÏχείων που μεταφÎÏθηκαν</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Απαιτεί αÏχεία βάσης δεδομÎνων. Δεν υποστηÏίζεται από όλα τα συστήματα αÏχείων.</target> + <source>Error handling</source> <target>ΔιαχείÏιση σφαλμάτων</target> @@ -798,17 +858,17 @@ is the same <source>Delete or overwrite files permanently</source> <target>Μόνιμη διαγÏαφή ή αντικατάσταση των αÏχείων</target> -<source>Recycle Bin</source> -<target>Κάδος ΑνακÏκλωσης</target> +<source>Recycle bin</source> +<target>Κάδος ανακÏκλωσης</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>ΧÏήση του Κάδου ΑνακÏκλωσης για αÏχεία που διαγÏάφηκαν ή αντικαταστάθηκαν</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>ΜεταφοÏά όλων των διαγÏαμμÎνων και αντικατεστημÎνων αÏχείων στον κάδο ανακÏκλωσης.</target> <source>Versioning</source> <target>ΔιατήÏηση παλιών εκδόσεων</target> -<source>Move files to user-defined folder</source> -<target>ΜεταφοÏά των αÏχείων σε Îναν υποκατάλογο που οÏίζεται από το χÏήστη</target> +<source>Move files to a user-defined folder</source> +<target>ΜεταφοÏά αÏχείων σε Îναν υποκατάλογο που οÏίζεται από το χÏήστη</target> <source>Naming convention:</source> <target>ΤÏόπος ονομασίας:</target> @@ -816,8 +876,8 @@ is the same <source>Batch job</source> <target>ΔÎσμη ενεÏγειών</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>ΔημιουÏγείστε Îνα αÏχείο δÎσμης για να αυτοματοποιήσετε το συγχÏονισμό. Κάντε διπλό κλικ στο αÏχείο αυτό ή Ï€ÏογÏαμματίστε το στο χÏονοδιάγÏαμμα εÏγασιών του συστήματός σας: FreeFileSync.exe <όνομα δÎσμης>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>ΔημιουÏγία ενός αÏχείου δÎσμης για αυτόματο συγχÏονισμό. Για να ξεκινήσετε, κάντε διπλό κλικ σε αυτό το αÏχείο ή ενσωματώστε το σε Îνα χÏονοδιάγÏαμμα εÏγασιών: %x</target> <source>Exit</source> <target>Έξοδος</target> @@ -871,12 +931,12 @@ is the same <target>ΔιαγÏαφή και στις δυο πλευÏÎÏ‚, ακόμα κι αν το αÏχείο Îχει επιλεχθεί μόνο στη μια πλευÏά</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -Θα συγχÏονιστοÏν μόνον όσα αÏχεία πληÏοÏν όλες τις απαιτήσεις των φίλτÏων. -Σημείωση: Î ÏÎπει να χÏησιμοποιοÏνται οι σχετικÎÏ‚ διαδÏομÎÏ‚ των αÏχείων ως Ï€Ïος τους υποκαταλόγους που συγχÏονίζονται. +Θα συγχÏονιστοÏν τα αÏχεία που ικανοποιοÏν όλους τους κανόνες των φίλτÏων. +Σημείωση: Οι διαδÏομÎÏ‚ των αÏχείων Ï€ÏÎπει να είναι σχετικÎÏ‚ ως Ï€Ïος τους βασικοÏÏ‚ υποκαταλόγους. </target> <source>Include</source> @@ -906,20 +966,20 @@ Note: File names must be relative to base directories. <source>Fail-safe file copy</source> <target>Ασφαλής αντιγÏαφή αÏχείων</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>ΕγγÏαφή Ï€Ïώτα σε Ï€ÏοσωÏινό αÏχείο (*.ffs_tmp) και μετά μετονομασία του. Αυτή η ÏÏθμιση εγγυάται συνÎπεια ακόμα και στην πεÏίπτωση σοβαÏÎ¿Ï ÏƒÏ†Î¬Î»Î¼Î±Ï„Î¿Ï‚.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>ΑντιγÏαφή αÏχικά σε Îνα Ï€ÏοσωÏινό αÏχείο (*.ffs_tmp) και στη συνÎχεια μετονομασία του. Αυτό εγγυάται μια συνεπή κατάσταση ακόμα και σε πεÏίπτωση μοιÏαίου σφάλματος.</target> <source>Copy locked files</source> <target>ΑντιγÏαφή κλειδωμÎνων αÏχείων</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>ΑντιγÏαφή κλειδωμÎνων ή διαμοιÏασμÎνων αÏχείων με την YπηÏεσία Σκιώδους ΑντίγÏαφου Τόμου (απαιτεί δικαιώματα Administrator)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>ΑντιγÏαφή των κοινόχÏηστων ή κλειδωμÎνων αÏχείων με τη χÏήση της ΥπηÏεσίας Σκιώδους ΑντίγÏαφου Τόμου (απαιτεί δικαιώματα διαχειÏιστή)</target> <source>Copy file access permissions</source> <target>ΑντιγÏαφή των αδειών Ï€ÏοσπÎλασης των αÏχείων</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>ΜεταφοÏά των αδειών των αÏχείων και των υποκαταλόγων (Απαιτεί δικαιώματα ΔιαχειÏιστή)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>ΜεταφοÏά των αδειών Ï€ÏοσπÎλασης των αÏχείων και των υποκαταλόγων(απαιτεί δικαιώματα διαχειÏιστή)</target> <source>Restore hidden dialogs</source> <target>Επανεμφάνιση κÏυμμÎνων μηνυμάτων</target> @@ -933,15 +993,6 @@ Note: File names must be relative to base directories. <source>&Default</source> <target>&Î Ïοεπιλογή</target> -<source>Variant</source> -<target>ÎœÎθοδος</target> - -<source>Statistics</source> -<target>Στατιστικά</target> - -<source>Don't show this dialog again</source> -<target>Îα μην εμφανιστεί ξανά αυτό το μήνυμα</target> - <source>Find what:</source> <target>Αναζήτηση του:</target> @@ -951,15 +1002,15 @@ Note: File names must be relative to base directories. <source>&Find next</source> <target>&ΕÏÏεση επομÎνου</target> +<source>Start synchronization</source> +<target>ΈναÏξη του συγχÏονισμοÏ</target> + <source>Delete</source> <target>ΔιαγÏαφή</target> <source>Configure filter</source> <target>ΡÏθμιση του φίλτÏου</target> -<source>Start synchronization</source> -<target>ΈναÏξη του συγχÏονισμοÏ</target> - <source>Find</source> <target>Αναζήτηση</target> @@ -994,6 +1045,21 @@ Note: File names must be relative to base directories. <target>ΣÏγκÏιση των δÏο πλευÏών</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>Είστε σίγουÏοι ότι θÎλετε να εκτελÎσετε την εντολή %y για 1 αντικείμενο;</pluralform> +<pluralform>Είστε σίγουÏοι ότι θÎλετε να εκτελÎσετε την εντολή %y για %x αντικείμενα;</pluralform> +</target> + +<source>Confirm</source> +<target>Επιβεβαίωση</target> + +<source>&Execute</source> +<target>&ΕκτÎλεση</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1029,12 +1095,15 @@ Note: File names must be relative to base directories. <source>Include temporarily</source> <target>Î ÏοσωÏινή συμπεÏίληψη</target> -<source>Exclude via filter:</source> -<target>ΕξαίÏεση με βάση το φίλτÏο:</target> - <source>multiple selection</source> <target>πολλαπλή επιλογή</target> +<source>Include via filter:</source> +<target>ΣυμπεÏίληψη μÎσω του φίλτÏου:</target> + +<source>Exclude via filter:</source> +<target>ΕξαίÏεση με βάση το φίλτÏο:</target> + <source>Include all</source> <target>ΣυμπεÏίληψη όλων</target> @@ -1080,8 +1149,8 @@ Note: File names must be relative to base directories. <source>Do&n't save</source> <target>Îα &μην αποθηκευθοÏν</target> -<source>Never save changes</source> -<target>Îα μην αποθηκεÏονται οι αλλαγÎÏ‚</target> +<source>Never save &changes</source> +<target>Îα &μην αποθηκεÏονται οι αλλαγÎÏ‚</target> <source>Show files that exist on left side only</source> <target>Εμφάνιση των αÏχείων που υπάÏχουν μόνο στα αÏιστεÏά</target> @@ -1134,8 +1203,8 @@ Note: File names must be relative to base directories. <source>All folders are in sync</source> <target>Όλοι οι υποκατάλογοι είναι συγχÏονισμÎνοι</target> -<source>Comma separated list</source> -<target>Κατάλογος οÏιοθετημÎνος με κόμματα</target> +<source>Comma-separated values</source> +<target>ΑÏχείο χωÏισμÎνο με κόμματα</target> <source>File list exported</source> <target>Ο κατάλογος των αÏχείων Îχει εξαχθεί</target> @@ -1143,8 +1212,8 @@ Note: File names must be relative to base directories. <source>Searching for program updates...</source> <target>Αναζήτηση καινοÏÏιας Îκδοσης...</target> -<source>Ignore further errors</source> -<target>Αγνόηση επόμενων σφαλμάτων</target> +<source>&Ignore subsequent errors</source> +<target>&Αγνόηση επόμενων σφαλμάτων</target> <source>&Ignore</source> <target>&ΠαÏάβλεψη</target> @@ -1152,8 +1221,8 @@ Note: File names must be relative to base directories. <source>Fatal Error</source> <target>Σημαντικό Σφάλμα</target> -<source>Don't show this warning again</source> -<target>Îα μην εμφανιστεί ξανά αυτή η Ï€Ïοειδοποίηση</target> +<source>&Don't show this warning again</source> +<target>&Îα μην εμφανιστεί ξανά αυτή η Ï€Ïοειδοποίηση</target> <source>&Switch</source> <target>&Εναλλαγή</target> @@ -1188,14 +1257,11 @@ Note: File names must be relative to base directories. <source>Completed</source> <target>ΟλοκληÏώθηκε</target> -<source>Continue</source> -<target>ΣυνÎχιση</target> +<source>&Continue</source> +<target>&ΣυνÎχεια</target> -<source>Pause</source> -<target>ΠαÏση</target> - -<source>Logging</source> -<target>ΚαταγÏαφÎντα μηνÏματα</target> +<source>Log</source> +<target>ΚαταγÏαφή</target> <source>Cannot find %x</source> <target>Δεν μποÏεί να βÏεθεί το %x</target> @@ -1231,12 +1297,12 @@ Note: File names must be relative to base directories. <target>ΦίλτÏο</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>Είσαι σίγουÏος ότι θÎλεις να μεταφεÏθεί το ακόλουθο αντικείμενο στον Κάδο ΑνακÏκλωσης;</pluralform> -<pluralform>Είσαι σίγουÏος ότι θÎλεις να μεταφεÏθοÏν τα ακόλουθα %x αντικείμενα στον Κάδο ΑνακÏκλωσης;</pluralform> +<pluralform>Είστε σίγουÏοι ότι θÎλετε να μετακινήσετε το ακόλουθο αντικείμενο στον κάδο ανακÏκλωσης;</pluralform> +<pluralform>Είστε σίγουÏοι ότι θÎλετε να μετακινήσετε τα ακόλουθα %x αντικείμενα στον κάδο ανακÏκλωσης;</pluralform> </target> <source> @@ -1290,9 +1356,6 @@ Note: File names must be relative to base directories. <source>Append a timestamp to each file name</source> <target>Î ÏοσάÏτηση χÏονικής σήμανσης σε κάθε όνομα αÏχείου</target> -<source>Folder</source> -<target>Υποκατάλογος</target> - <source>File</source> <target>ΑÏχείο</target> @@ -1413,8 +1476,8 @@ Note: File names must be relative to base directories. <source>Cannot change process I/O priorities.</source> <target>Δεν μποÏοÏν να αλλάξουν οι Ï€ÏοτεÏαιότητες I/O της διεÏγασίας.</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>Το αÏχείο %x δεν ήταν δυνατό να μεταφεÏθεί στον Κάδο ΑνακÏκλωσης.</target> +<source>Unable to move %x to the recycle bin.</source> +<target>Δεν ήταν δυνατή η μεταφοÏά του %x στον κάδο ανακÏκλωσης.</target> <source>Cannot determine final path for %x.</source> <target>Δεν μποÏεί να Ï€ÏοσδιοÏιστεί η τελική διαδÏομή για το %x.</target> diff --git a/BUILD/Languages/hebrew.lng b/BUILD/Languages/hebrew.lng index c7b0adcd..ede03515 100644 --- a/BUILD/Languages/hebrew.lng +++ b/BUILD/Languages/hebrew.lng @@ -7,6 +7,12 @@ <plural_definition>n == 1 ? 0 : 1</plural_definition> </header> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target></target> + +<source>Close search bar</source> +<target></target> + <source>Both sides have changed since last synchronization.</source> <target>×©× ×™ ×”×¦×“×“×™× ×©×•× ×• מ××– ×”×¡× ×›×¨×•×Ÿ ×”×חרון.</target> @@ -25,14 +31,14 @@ <source>Checking recycle bin availability for folder %x...</source> <target>בודק ×–×ž×™× ×•×ª סל מחזור עבור מחיצה %x...</target> -<source>Moving file %x to recycle bin</source> -<target>מעביר קובץ %x לסל מחזור</target> +<source>Moving file %x to the recycle bin</source> +<target>מעביר קובץ %x לסל המיחזור</target> -<source>Moving folder %x to recycle bin</source> -<target>מעביר מחיצה %x לסל מחזור</target> +<source>Moving folder %x to the recycle bin</source> +<target>מעביר תיקייה %x לסל המיחזור</target> -<source>Moving symbolic link %x to recycle bin</source> -<target>מעביר קישור סימבולי %x לסל מחזור</target> +<source>Moving symbolic link %x to the recycle bin</source> +<target>מעביר קישור סימבולי %x לסל המיחזור</target> <source>Deleting file %x</source> <target>מוחק קובץ %x</target> @@ -43,14 +49,20 @@ <source>Deleting symbolic link %x</source> <target>מוחק קישור סימבולי %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>סל המיחזור ××™× ×• זמין עבור התיקיות הב×ות. ×§×‘×¦×™× ×™×ž×—×§×• סופית:</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>סל המיחזור ××™× ×• זמין עבור התיקיות הב×ות. ×”×§×‘×¦×™× ×™×™×ž×—×§×• לחלוטין:</target> <source>An exception occurred</source> <target>×ירוע חריג</target> -<source>Cannot find file %x.</source> -<target>×œ× ×™×›×•×œ ×œ×ž×¦×•× ×§×•×‘×¥ %x.</target> +<source>A directory path is expected after %x.</source> +<target>× ×ª×™×‘ מחיצה × ×“×¨×© ×חרי %x.</target> + +<source>Syntax error</source> +<target>שגי×ת תחביר</target> + +<source>Cannot open file %x.</source> +<target>×œ× ×™×›×•×œ לפתוח קובץ %x.</target> <source>Error</source> <target>שגי××”</target> @@ -58,6 +70,36 @@ <source>File %x does not contain a valid configuration.</source> <target>קובץ %x ××™× ×• כולל תצורה ×ª×§×™× ×”.</target> +<source>Unequal number of left and right directories specified.</source> +<target>מספר בלתי שווה של מחיצות ימין ושמ×ל צוין.</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>קבצי ×”×§×•× ×¤×™×’×•×¨×¦×™×” ××™× × ×™×›×•×œ×™× ×œ×›×œ×•×œ הגדרות של זוגות מחיצות ×›×שר מחיצות מוגדרות ב×מצעות שורת הפקודה</target> + +<source>Warning</source> +<target>×זהרה</target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target>מחיצות ××™× ×• יכולות להיות מוגדרות עבור יותר מקובץ ×§×•× ×¤×™×’×•×¨×¦×™×” ×חד.</target> + +<source>Syntax:</source> +<target>תחביר:</target> + +<source>config files</source> +<target>קבצי ×§×•× ×¤×™×’×•×¨×¦×™×”</target> + +<source>directory</source> +<target>מחיצה</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>כל כמות של קבצי FreeFileSync .ffs_gui ו\×ו קבצי ×§×•× ×¤×™×’×•×¨×¦×™×” .ffs_batch.</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>כל כמות של מחיצות ××œ×˜×¨× ×˜×™×‘×™×•×ª עבור לפחות קובץ ×§×•× ×¤×™×’×•×¨×¦×™×” ×חד.</target> + +<source>Command line</source> +<target>שורת פקודות</target> + <source>A folder input field is empty.</source> <target>שדה קלט תיקייה ריק.</target> @@ -215,12 +257,12 @@ <target>זמן כולל:</target> <source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </source> <target> -<pluralform>1 בייט</pluralform> -<pluralform>%x בייט</pluralform> +<pluralform>בית 1</pluralform> +<pluralform>%x בתי×</pluralform> </target> <source>%x MB</source> @@ -242,12 +284,12 @@ <target>סורק:</target> <source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </source> <target> -<pluralform>[תהליכון 1]</pluralform> -<pluralform>[%x ×ª×”×œ×™×›×•× ×™×]</pluralform> +<pluralform>תהליך 1</pluralform> +<pluralform>%x תהליכי×</pluralform> </target> <source>Encoding extended time information: %x</source> @@ -256,6 +298,9 @@ <source>/sec</source> <target>/×©× </target> +<source>%x items</source> +<target>%x פריטי×</target> + <source>Configuration file %x loaded partially only.</source> <target>קובץ תצורה %x × ×˜×¢×Ÿ חלקית בלבד.</target> @@ -268,8 +313,8 @@ <source>Browse directory</source> <target>עיין במחיצה</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>×œ× ×™×›×•×œ לגשת ×ל volume shadow copy service.</target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target>×œ× × ×™×ª×Ÿ לגשת ×ל שרות Volume Shadow Copy</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>×× × ×”×©×ª×ž×© בגירסת 64-bit של FreeFileSync על ×ž× ×ª ליצר shadow copies במערכת הפעלה זו.</target> @@ -280,8 +325,8 @@ <source>Cannot determine volume name for %x.</source> <target>×œ× ×™×›×•×œ לקבוע ×©× ×מצעי ×חסון %x.</target> -<source>Volume name %x not part of file name %y.</source> -<target>×›×›×•× ×Ÿ %x ×œ× ×‘× ×ª×™×‘ של קובץ %y.</target> +<source>Volume name %x is not part of file path %y.</source> +<target>כרך ×‘×©× %x ××™× ×• חלק של × ×ª×™×‘ קובץ %y.</target> <source>Abort requested: Waiting for current operation to finish...</source> <target>התקבלה בקשת ביטול: מחכה לפעולה ×”× ×•×›×—×™×ª להסתיי×...</target> @@ -349,9 +394,6 @@ <source>Idle time between last detected change and execution of command</source> <target>זמן ×”×ž×ª× ×” בין ×©×™× ×•×™×™ מ×ובחן ×חרון לבין ביצוע של פקודה</target> -<source>Command line</source> -<target>שורת פקודות</target> - <source> The command is triggered if: - files or subfolders change @@ -375,9 +417,6 @@ The command is triggered if: <source>RealtimeSync - Automated Synchronization</source> <target>RealtimeSync - ×¡×™× ×›×¨×•×Ÿ ×וטומטי</target> -<source>Warning</source> -<target>×זהרה</target> - <source>Build: %x</source> <target>×ž×‘× ×”: %x</target> @@ -387,15 +426,21 @@ The command is triggered if: <source>All files</source> <target>כל הקבצי×</target> +<source>Directory monitoring active</source> +<target>× ×™×˜×•×¨ מחיצות פעיל</target> + +<source>Waiting until all directories are available...</source> +<target>מחכה עד שכל המחיצות יהיו ×–×ž×™× ×•×ª...</target> + <source>&Restore</source> <target>&טען מחדש</target> +<source>&Show error</source> +<target>&הר××” שגי××”</target> + <source>&Exit</source> <target>&יצי××”</target> -<source>Waiting for missing directories...</source> -<target>מחכה למחיצות חסרות...</target> - <source>Invalid command line:</source> <target>שורת פקודה בלתי חוקית:</target> @@ -405,14 +450,14 @@ The command is triggered if: <source>File time and size</source> <target>זמן וגודל קובץ</target> -<source> Two way </source> +<source>Two way</source> <target>דו ×›×•×•× ×™</target> <source>Mirror</source> -<target>מר××” </target> +<target>מר××”</target> <source>Update</source> -<target>שדרג </target> +<target>שדרג</target> <source>Custom</source> <target>מות××</target> @@ -468,11 +513,8 @@ The command is triggered if: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>×œ×¤×¨×™×˜×™× ×”×‘××™× ×™×© ×§×•× ×¤×œ×™×§×˜×™× ×‘×œ×ª×™ ×¤×ª×•×¨×™× ×•×”× ×œ× ×™×¡×•× ×›×¨× ×•:</target> -<source>Significant difference detected:</source> -<target>התגלה ×©×•× ×™ גדול מידי:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>יותר מ 50% ×ž×”×§×‘×¦×™× ×™×ž×—×§×• ×ו יועתקו.</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>התיקיות הב×ות ×©×•× ×•×ª ב×ופן מהותי. ×•×“× ×ת הת×מת התיקיות ×œ×¡×™× ×›×¨×•×Ÿ.</target> <source>Not enough free disk space available in:</source> <target>×ין מספיק ×ž×§×•× ×“×™×¡×§ ×¤× ×•×™ ב:</target> @@ -492,12 +534,15 @@ The command is triggered if: <source>Generating database...</source> <target>מייצר מסד × ×ª×•× ×™×...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>יוצר העתק volume shadow עבור %x...</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>מייצר Volume Shadow Copy עבור %x...</target> <source>Data verification error: %x and %y have different content.</source> <target>שגי×ת ×ימות × ×ª×•× ×™×. ל %x ו %y יש תוכן ×©×•× ×”.</target> +<source>job name</source> +<target>×©× ×ž×©×™×ž×”</target> + <source>Synchronization aborted</source> <target>×¡×™× ×›×¨×•×Ÿ בוטל</target> @@ -522,6 +567,9 @@ The command is triggered if: <source>Switching to FreeFileSync main dialog</source> <target>מחליף לתיבת דו שיח ר×שית של FreeFileSync</target> +<source>Retrying operation after error:</source> +<target>×ž× ×¡×” ×©× ×™×ª ל×חר שגי××”:</target> + <source>A new version of FreeFileSync is available:</source> <target>גירסה חדשה של FreeFileSync ×–×ž×™× ×”:</target> @@ -645,8 +693,8 @@ The command is triggered if: <source>&Export file list...</source> <target>&×™×¦× ×¨×©×™×ž×ª קבצי×...</target> -<source>&Global settings...</source> -<target>&×ž×©×ª× ×™× ×’×œ×•×‘×œ×™×™×...</target> +<source>&Global settings</source> +<target>&×ž×©×ª× ×™× ×’×œ×•×‘×œ×™×™×</target> <source>&Tools</source> <target>&כלי×</target> @@ -663,12 +711,6 @@ The command is triggered if: <source>Compare</source> <target>השוו××”</target> -<source>Comparison settings</source> -<target>הגדרות השוו××”</target> - -<source>Synchronization settings</source> -<target>הגדרות ×¡× ×›×¨×•×Ÿ</target> - <source>Synchronize</source> <target>×¡× ×›×¨×Ÿ</target> @@ -681,6 +723,12 @@ The command is triggered if: <source>Swap sides</source> <target>החלף צדדי×</target> +<source>Find what:</source> +<target>חפש מה:</target> + +<source>Match case</source> +<target>הת×× ×¨×™×©×™×•×ª</target> + <source>Save as batch job</source> <target>שמור כעבודת ×צווה</target> @@ -717,6 +765,9 @@ The command is triggered if: <source>Synchronizing...</source> <target>×ž×¡× ×›×¨×Ÿ...</target> +<source>Minimize to notification area</source> +<target>הקטן ל×יזור ההתרעות</target> + <source>On completion</source> <target>ל×חר סיו×:</target> @@ -726,6 +777,15 @@ The command is triggered if: <source>&Pause</source> <target>&עצור</target> +<source>Variant</source> +<target>×ž×©×ª× ×”</target> + +<source>Statistics</source> +<target>סטטיסטיקה</target> + +<source>&Don't show this dialog again</source> +<target>&×ל תר××” דושיח ×–×” ×©× ×™×ª</target> + <source>Select a variant</source> <target>בחר גירסה</target> @@ -774,6 +834,12 @@ is the same <source>Configure your own synchronization rules.</source> <target>סדר ×ת כללי ×”×¡× ×›×¨×•×Ÿ שלך.</target> +<source>Detect moved files</source> +<target>גלה ×§×‘×¦×™× ×ž×•×¢×‘×¨×™×</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>דורש קבצי בסיס × ×ª×•× ×™×. ×œ× × ×ª×ž×š ×¢"×™ כל מערכות הקבצי×.</target> + <source>Error handling</source> <target>טיפול בשגי×ות</target> @@ -798,17 +864,17 @@ is the same <source>Delete or overwrite files permanently</source> <target>מחק ×ו דרוס ×§×‘×¦×™× ×œ×¦×ž×™×ª×•×ª</target> -<source>Recycle Bin</source> -<target>סל מחזור</target> +<source>Recycle bin</source> +<target>סל מיחזור</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>השתמש בסל המחזור עבור ×§×‘×¦×™× × ×ž×—×§×™× ×ו × ×“×¨×¡×™×</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>גבה ×§×‘×¦×™× ×©× ×ž×—×§×• ×ו ×©× ×“×¨×¡×• בסל המיחזור</target> <source>Versioning</source> <target>עדכון גרס×ות</target> -<source>Move files to user-defined folder</source> -<target>העבר ×§×‘×¦×™× ×œ×ž×—×™×¦×” שהוגדרה ×¢"×™ המשתמש</target> +<source>Move files to a user-defined folder</source> +<target>העבר ×§×‘×¦×™× ×œ×ª×™×§×™×™×” המוגדרת ×¢"×™ המפעיל</target> <source>Naming convention:</source> <target>מוסכמות לקביעת שמות:</target> @@ -816,8 +882,8 @@ is the same <source>Batch job</source> <target>עבודת ×צווה</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>יצר קובץ ×צווה למכן ×ת ×”×¡× ×›×¨×•×Ÿ. הקלק ×¤×¢×ž×™×™× ×¢×œ קובץ ×–×” ×ו תזמן ×‘×ž×ª×›× ×Ÿ המשימות: FreeFileSYnc.exe <jobname>.ffs</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>צור קובץ ×צווה ×œ×¡×™× ×›×¨×•×Ÿ ×œ×œ× ×”×ª×¢×¨×‘×•×ª מפעיל. כדי להפעיל, הקלק הקלקה כפולה על הקובץ ×ו תזמן ×‘×ž×ª×›× ×Ÿ המשימות: %x</target> <source>Exit</source> <target>יצי××”</target> @@ -840,30 +906,6 @@ is the same <source>Limit maximum number of log files</source> <target>הגבל מספר מכסימלי של קבצי יומן</target> -<source>Source code written in C++ using:</source> -<target>קוד מקור × ×›×ª×‘ ב- C++ ב×מצעות:</target> - -<source>If you like FreeFileSync</source> -<target>במידה ו-FreeFileSync מוצ×ת חן ×‘×¢×™× ×›×</target> - -<source>Donate with PayPal</source> -<target>×ª×¨×•× ×¢× ×¤×™×™×¤×œ</target> - -<source>Many thanks for localization:</source> -<target>תודות עבור ×ª×¨×’×•× ×©×¤×•×ª:</target> - -<source>Feedback and suggestions are welcome</source> -<target>משוב והצעות יתקבלו בברכה</target> - -<source>Homepage</source> -<target>×תר-הבית:</target> - -<source>Email</source> -<target>דו×"ל:</target> - -<source>Published under the GNU General Public License</source> -<target>×ž×¤×•×¨×¡× ×‘×ž×¡×’×¨×ª GNU General Public License</target> - <source>Delete on both sides</source> <target>מחק ×‘×©× ×™ הצדדי×</target> @@ -871,12 +913,12 @@ is the same <target>מחק ×‘×©× ×™ ×”×¦×“×“×™× ××£ ×× ×”×§×•×‘×¥ × ×‘×—×¨ בצד ×חד בלבד</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -רק ×§×‘×¦×™× ×”×ž×ª××™×ž×™× ×œ×›×œ הגדרות ×”×ž×¡× ×Ÿ ×™×¡×•× ×›×¨× ×•. -הערה: שמות ×§×‘×¦×™× ×—×™×™×‘×™× ×œ×”×™×•×ª ×ž×•×’×“×¨×™× ×‘×ופן יחסי למחיצות הר×שיות. +×§×‘×¦×™× ×™×¡×•× ×›×¨× ×• רק ×× ×™×§×™×™×ž×• ×ת כל חוקי ×”×ž×¡× ×Ÿ. +הערה: × ×ª×™×‘×™ ×§×‘×¦×™× ×—×™×™×‘×™× ×œ×”×™×•×ª ×™×—×¡×™×™× ×œ×ž×—×™×¦×•×ª הבסיס. </target> <source>Include</source> @@ -906,20 +948,17 @@ Note: File names must be relative to base directories. <source>Fail-safe file copy</source> <target>כשלון ב×בטחת העתקת קובץ</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>×¨×©×•× ×œ×§×•×‘×¥ ×–×ž× ×™ (*.ffs_tmp) תחילה ×•×©× ×” ש×. פעולה זו מבטיחה עקביות המצב ×’× ×‘×ž×§×¨×” של שגי××” חמורה.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>העתק לקובץ ×–×ž× ×™ (*.ffs_tmp) ר×שית ו××– ×©× ×” ×ת שמו. ×–×” מבטיח במצ עיקבי במקרה של שגי××” חמורה.</target> <source>Copy locked files</source> <target>העתק ×§×‘×¦×™× × ×¢×•×œ×™×</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>העתק ×§×‘×¦×™× ×‘×©×™×ª×•×£ ×ו × ×¢×•×œ×™× ×‘×מצעות שרות Volume Shadow Copy Service (דורש הרש×ות ×ž× ×”×œ מערכת)</target> - <source>Copy file access permissions</source> <target>העתק הרש×ות גישה של הקובץ</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>העבר הרש×ות של תיקיות ×•×§×‘×¦×™× (דורש זכויות ×ž× ×”×œ)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>העבר הרש×ות של קובץ ותיקיה (דורש זכויות ×ž× ×”×œ)</target> <source>Restore hidden dialogs</source> <target>שחזר די××œ×•×’×™× ×ž×•×¡×ª×¨×™×</target> @@ -933,35 +972,44 @@ Note: File names must be relative to base directories. <source>&Default</source> <target>&ברירת מחדל</target> -<source>Variant</source> -<target>×ž×©×ª× ×”</target> +<source>Source code written in C++ using:</source> +<target>קוד מקור × ×›×ª×‘ ב- C++ ב×מצעות:</target> -<source>Statistics</source> -<target>סטטיסטיקה</target> +<source>If you like FreeFileSync</source> +<target>במידה ו-FreeFileSync מוצ×ת חן ×‘×¢×™× ×›×</target> -<source>Don't show this dialog again</source> -<target>×ל תר××” דו-שיח ×–×” שוב</target> +<source>Donate with PayPal</source> +<target>×ª×¨×•× ×¢× ×¤×™×™×¤×œ</target> -<source>Find what:</source> -<target>חפש מה:</target> +<source>Feedback and suggestions are welcome</source> +<target>משוב והצעות יתקבלו בברכה</target> -<source>Match case</source> -<target>הת×× ×¨×™×©×™×•×ª</target> +<source>Homepage</source> +<target>×תר-הבית:</target> -<source>&Find next</source> -<target>&×ž×¦× ×”×‘×</target> +<source>Email</source> +<target>דו×"ל:</target> -<source>Delete</source> -<target>מחק</target> +<source>Published under the GNU General Public License</source> +<target>×ž×¤×•×¨×¡× ×‘×ž×¡×’×¨×ª GNU General Public License</target> -<source>Configure filter</source> -<target>תצורת ×ž×¡× ×Ÿ</target> +<source>Many thanks for localization:</source> +<target>תודות עבור ×ª×¨×’×•× ×©×¤×•×ª:</target> <source>Start synchronization</source> <target>התחל ×¡× ×›×¨×•×Ÿ</target> -<source>Find</source> -<target>חפש</target> +<source>Comparison settings</source> +<target>הגדרות השוו××”</target> + +<source>Synchronization settings</source> +<target>הגדרות ×¡× ×›×¨×•×Ÿ</target> + +<source>Delete</source> +<target>מחק</target> + +<source>Configure filter</source> +<target>תצורת ×ž×¡× ×Ÿ</target> <source>Select time span</source> <target>בחר ×ª×—×•× ×–×ž×Ÿ</target> @@ -969,6 +1017,9 @@ Note: File names must be relative to base directories. <source>Folder pairs</source> <target>זוגות מחיצות</target> +<source>Find</source> +<target>חפש</target> + <source>Overview</source> <target>מבט כללי</target> @@ -994,6 +1045,21 @@ Note: File names must be relative to base directories. <target>השווה בין ×©× ×™ הצדדי×</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>×”×× ×‘×¨×¦×•× ×š לבצע ×ת הפקודה %y עבור פריט ×חד?</pluralform> +<pluralform>×”×× ×‘×¨×¦×•× ×œ לבצע ×ת הפקודה %y עבור %x פריטי×?</pluralform> +</target> + +<source>Confirm</source> +<target>×שר</target> + +<source>&Execute</source> +<target>&בצע</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1023,17 +1089,20 @@ Note: File names must be relative to base directories. <source>Set direction:</source> <target>בחר כוון:</target> -<source>Exclude temporarily</source> -<target>×ל תכלול ×–×ž× ×™×ª</target> +<source>multiple selection</source> +<target>בחירה מרובה</target> -<source>Include temporarily</source> -<target>כלול ×–×ž× ×™×ª</target> +<source>Include via filter:</source> +<target>כלול ב×מצעות ×ž×¡× ×Ÿ:</target> <source>Exclude via filter:</source> <target>×ל תכלול בעזרת ×¡× ×Ÿ:</target> -<source>multiple selection</source> -<target>בחירה מרובה</target> +<source>Exclude temporarily</source> +<target>×ל תכלול ×–×ž× ×™×ª</target> + +<source>Include temporarily</source> +<target>כלול ×–×ž× ×™×ª</target> <source>Include all</source> <target>הכלל הכל</target> @@ -1080,8 +1149,8 @@ Note: File names must be relative to base directories. <source>Do&n't save</source> <target>×ל &תשמור</target> -<source>Never save changes</source> -<target>×ל תשמור ×©×™× ×•×™×™× ×œ×¢×•×œ×</target> +<source>Never save &changes</source> +<target>×œ× ×œ×©×ž×•×¨ ×©×™× ×•×™×™× ×œ&עול×</target> <source>Show files that exist on left side only</source> <target>הר××” ×§×‘×¦×™× ×”× ×ž×¦××™× ×ך ורק בצד ימין</target> @@ -1134,8 +1203,11 @@ Note: File names must be relative to base directories. <source>All folders are in sync</source> <target>כל התיקיות ×ž×¡×•× ×›×¨× ×•×ª</target> -<source>Comma separated list</source> -<target>רשימה מופרדת פסיקי×</target> +<source>Cannot find %x</source> +<target>×œ× ×ž×•×¦× %x</target> + +<source>Comma-separated values</source> +<target>×¢×¨×›×™× ×ž×•×¤×¨×“×™× ×‘×מצעות פסיק</target> <source>File list exported</source> <target>רשימת ×§×‘×¦×™× ×™×•×¦××”</target> @@ -1143,8 +1215,8 @@ Note: File names must be relative to base directories. <source>Searching for program updates...</source> <target>מחפש ×¢×™×“×›×•× ×™ ×ª×•×›× ×”...</target> -<source>Ignore further errors</source> -<target>×”×ª×¢×œ× ×ž×©×’×™×ות × ×•×¡×¤×•×ª</target> +<source>&Ignore subsequent errors</source> +<target>&×”×ª×¢×œ× ×ž×זהרות × ×•×¡×¤×•×ª</target> <source>&Ignore</source> <target>&התעל×</target> @@ -1152,8 +1224,8 @@ Note: File names must be relative to base directories. <source>Fatal Error</source> <target>שגי××” פטלית</target> -<source>Don't show this warning again</source> -<target>×ל תר××” ×זהרה זו שוב</target> +<source>&Don't show this warning again</source> +<target>&×œ× ×œ×”×¨×ות ×זהרה זו שוב</target> <source>&Switch</source> <target>&החלפה</target> @@ -1188,17 +1260,11 @@ Note: File names must be relative to base directories. <source>Completed</source> <target>הושל×</target> -<source>Continue</source> -<target>המשך</target> - -<source>Pause</source> -<target>עצור</target> +<source>&Continue</source> +<target>&המשך</target> -<source>Logging</source> -<target>×¨×™×©×•× ×‘×™×•×ž×Ÿ</target> - -<source>Cannot find %x</source> -<target>×œ× ×ž×•×¦× %x</target> +<source>Log</source> +<target>יומן</target> <source>Inactive</source> <target>בלתי פעיל</target> @@ -1231,12 +1297,12 @@ Note: File names must be relative to base directories. <target>×ž×¡× ×Ÿ</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>×”×× ×‘×¨×¦×•× ×š להעביר ×ת הפריט ×”×‘× ×œ×¡×œ המיחזור?</pluralform> -<pluralform>×”×× ×‘×¨×¦×•× ×š להעביר ×ת ×”×¤×¨×™×˜×™× %x הב××™× ×œ×¡×œ המיחזור?</pluralform> +<pluralform>×”×× ×‘×מת ×‘×¨×¦×•× ×š להעביר ×ת הפריט ×”×‘× ×œ×¡×œ המחזור?</pluralform> +<pluralform>×”×× ×‘×מת ×‘×¨×¦×•× ×š להעביר ×ת ×”×¤×¨×™×˜×™× ×”×‘××™× %x לסל המחזור?</pluralform> </target> <source> @@ -1290,9 +1356,6 @@ Note: File names must be relative to base directories. <source>Append a timestamp to each file name</source> <target>הצמד תג זמן לכל ×©× ×§×•×‘×¥</target> -<source>Folder</source> -<target>תיקייה</target> - <source>File</source> <target>קובץ</target> @@ -1413,8 +1476,8 @@ Note: File names must be relative to base directories. <source>Cannot change process I/O priorities.</source> <target>×œ× ×™×›×•×œ ×œ×©× ×•×ª קדימויות של תהליך קלט פלט.</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>×œ× ×™×›×•×œ להעביר ×ת %x לסל המיחזור.</target> +<source>Unable to move %x to the recycle bin.</source> +<target>×œ× ×™×›×•×œ להעביר ×ת %x לסל המחזור</target> <source>Cannot determine final path for %x.</source> <target>×œ× ×™×›×•×œ לקבוע ×ת המסלול הסופי ל %x.</target> diff --git a/BUILD/Languages/hungarian.lng b/BUILD/Languages/hungarian.lng index a58698fb..8061b8bf 100644 --- a/BUILD/Languages/hungarian.lng +++ b/BUILD/Languages/hungarian.lng @@ -11,7 +11,7 @@ <target>Mindkét oldal megváltozott az utolsó szikronizálás óta.</target> <source>Cannot determine sync-direction:</source> -<target>Nem lehet meghatározni a szinkronizálás irányát:</target> +<target>Nem meghatározható a szinkronizálás iránya:</target> <source>No change since last synchronization.</source> <target>Az utolsó szinkronizálás óta nem történt változás.</target> @@ -23,19 +23,19 @@ <target>Alapértelmezett szinkronizálási irányok beállÃtása: a régebbi fájlokat Ãrja felül az újabbakkal.</target> <source>Checking recycle bin availability for folder %x...</source> -<target>A Lomtár elérhetÅ‘ségének ellenÅ‘rzése a következÅ‘ könyvtár vonatkozásában: %x.</target> +<target>A Lomtár elérhetÅ‘ségének ellenÅ‘rzése %x könyvtár vonatkozásában...</target> -<source>Moving file %x to recycle bin</source> -<target>%x fájl mozgatása a Lomtárba (Recycle Bin)</target> +<source>Moving file %x to the recycle bin</source> +<target>%x fájlt a Lomtárba mozgatja</target> -<source>Moving folder %x to recycle bin</source> -<target>%x könyvtár mozgatása a Lomtárba (Recycle Bin)</target> +<source>Moving folder %x to the recycle bin</source> +<target>%x könyvtárat a Lomtárba mozgatja</target> -<source>Moving symbolic link %x to recycle bin</source> -<target>%x szimbolikus hivatkozás mozgatása a Lomtárba (Recycle Bin)</target> +<source>Moving symbolic link %x to the recycle bin</source> +<target>%x szimbolikus linket a Lomtárba mozgatja</target> <source>Deleting file %x</source> -<target>%x Fájl törlése</target> +<target>%x fájl törlése</target> <source>Deleting folder %x</source> <target>%x könyvtár törlése</target> @@ -43,23 +43,59 @@ <source>Deleting symbolic link %x</source> <target>%x szimbolikus hivatkozás törlése</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>A Lomtár nem elérhetÅ‘ a következÅ‘ könytárak esetében. A fájlok ehelyett végleges törlésre kerülnek!</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>A Lomtár nem elérhetÅ‘ a következÅ‘ könytárak esetében. A fájlok ezért véglegesen törlÅ‘dnek:</target> <source>An exception occurred</source> -<target>Kivétel lépett fel</target> +<target>Kivétel történt</target> -<source>Cannot find file %x.</source> -<target>Nem található a következÅ‘ fájl: %x.</target> +<source>A directory path is expected after %x.</source> +<target>%x után egy könyvtár elérési útvonalának kell következnie.</target> + +<source>Syntax error</source> +<target>Szintaktikai hiba</target> + +<source>Cannot open file %x.</source> +<target>%x fájl nem nyitható.</target> <source>Error</source> <target>Hiba</target> <source>File %x does not contain a valid configuration.</source> -<target>A következÅ‘ fájl nem tartalmaz érvényes beállÃtásokat: %x.</target> +<target>%x fájl nem tartalmaz érvényes beállÃtásokat.</target> + +<source>Unequal number of left and right directories specified.</source> +<target>EltérÅ‘ számú bal- és jobboldali könyvtárat határozott meg.</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>A konfigurációs fájl nem tartalmazhat beállÃtásokat könyvár-pár szinten, ha a könyvtárakat parancssorban állÃtjuk be.</target> + +<source>Warning</source> +<target>Figyelmeztetés</target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target>A könyvtárakat nem lehet egynél több konfigurációs fájlra beállÃtani</target> + +<source>Syntax:</source> +<target>Szintaxis:</target> + +<source>config files</source> +<target>konfigurációs fájlok</target> + +<source>directory</source> +<target>könyvtár</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>TetszÅ‘leges számú .ffs_gui és/vagy .ffs_batch konfigurációs fájl készÃthetÅ‘ a FreeFileSync-hez</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>TetszÅ‘leges számú alternatÃv könyvtár legfeljebb egy konfigurációs fájlhoz</target> + +<source>Command line</source> +<target>Parancssor</target> <source>A folder input field is empty.</source> -<target>A könyvtár beviteli mezeje üres.</target> +<target>A könyvtár beviteli mezÅ‘ üres.</target> <source>The corresponding folder will be considered as empty.</source> <target>A kapcsolódó könyvtárat üresként kezeli.</target> @@ -68,7 +104,7 @@ <target>A következÅ‘ könyvtárak nem találhatóak:</target> <source>You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.</source> -<target>Figyelmen kÃvül hagyhatod ezt a hibát ezzel üresnek tekintve minden egyes könyvtárat. A könytárak automatikusan létrejönnek a szinkronizálás folyamán.</target> +<target>Figyelmen kÃvül hagyhatod ezt a hibát, ezzel üresnek tekintve minden egyes könyvtárat. A könytárak ekkor automatikusan létrejönnek a szinkronizálás folyamán.</target> <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>A következÅ‘ könytárak egymástól függÅ‘ útvonalat tartalmaznak. Légy óvatos a szinkronizálás szabályainak meghatározásánál!</target> @@ -215,12 +251,12 @@ <target>Összes idÅ‘szükségelet:</target> <source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </source> <target> -<pluralform>1 Bájt</pluralform> -<pluralform>%x Bájt</pluralform> +<pluralform>1 bájt</pluralform> +<pluralform>%x bájt</pluralform> </target> <source>%x MB</source> @@ -242,12 +278,12 @@ <target>Vizsgálat:</target> <source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </source> <target> -<pluralform>[1 szál]</pluralform> -<pluralform>[%x szál]</pluralform> +<pluralform>1 szál</pluralform> +<pluralform>%x szál</pluralform> </target> <source>Encoding extended time information: %x</source> @@ -256,6 +292,9 @@ <source>/sec</source> <target>/másodperc</target> +<source>%x items</source> +<target>%x elem</target> + <source>Configuration file %x loaded partially only.</source> <target>%x konfigurációs fájl csak részlegesen töltÅ‘dött be: .</target> @@ -268,8 +307,8 @@ <source>Browse directory</source> <target>Tallózza a könyvtárat</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Nem sikerült elérni a kötet-árnyékmásolat (Volume Shadow Copy) szolgáltatást.</target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target>Nem elérhetÅ‘ a Kötet Ãrnyék-másolat szolgáltatás.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>Kérjük, használd a FreeFileSync 64 bites verzióját az árnyékmásolatok készÃtéséhez ezen a rendszeren.</target> @@ -280,8 +319,8 @@ <source>Cannot determine volume name for %x.</source> <target>Nem lehet meghatározni a kötet-nevet a(z) %x számára</target> -<source>Volume name %x not part of file name %y.</source> -<target>%x kötet-nevet nem tartalmazza a(z) %y fájlnév.</target> +<source>Volume name %x is not part of file path %y.</source> +<target>%x kötet név nem része a(z) %y fájl elérési útvonalnak</target> <source>Abort requested: Waiting for current operation to finish...</source> <target>MegszakÃtást igényelt: Várakozás a folyamatban lévÅ‘ művelet befejezésére...</target> @@ -349,9 +388,6 @@ <source>Idle time between last detected change and execution of command</source> <target>Ãœresjárat idÅ‘tartama az utolsó változás észlelése és a parancs végrehajtása között</target> -<source>Command line</source> -<target>Parancssor</target> - <source> The command is triggered if: - files or subfolders change @@ -375,9 +411,6 @@ A parancs végrehajtódik, ha: <source>RealtimeSync - Automated Synchronization</source> <target>Valós idejű - Automatikus szinkronizálás</target> -<source>Warning</source> -<target>Figyelem</target> - <source>Build: %x</source> <target>Build: %x</target> @@ -387,15 +420,21 @@ A parancs végrehajtódik, ha: <source>All files</source> <target>Összes fájl</target> +<source>Directory monitoring active</source> +<target>A könytár figyelés aktÃv</target> + +<source>Waiting until all directories are available...</source> +<target>Várakozik, amÃg az összes könyvtár elérhetÅ‘vé válik...</target> + <source>&Restore</source> <target>&VisszaállÃt</target> +<source>&Show error</source> +<target>&Mutassa a hibákat</target> + <source>&Exit</source> <target>&Kilép</target> -<source>Waiting for missing directories...</source> -<target>Várakozás a hiányzó könyvtárakra...</target> - <source>Invalid command line:</source> <target>Érvénytelen parancssor:</target> @@ -405,14 +444,14 @@ A parancs végrehajtódik, ha: <source>File time and size</source> <target>Fájl dátuma és mérete</target> -<source> Two way </source> -<target> Kétirányú </target> +<source>Two way</source> +<target>Kétirányú</target> <source>Mirror</source> -<target>Tükröz </target> +<target>Tükröz</target> <source>Update</source> -<target>FrissÃt </target> +<target>FrissÃt</target> <source>Custom</source> <target>Egyedi</target> @@ -468,11 +507,8 @@ A parancs végrehajtódik, ha: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>A következÅ‘ elemek feloldatlan ütközést tartalmaznak, Ãgy nem lesznek szinkronizálva:</target> -<source>Significant difference detected:</source> -<target>JelentÅ‘s különbség érzékelt:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>Az összes fájl több mint 50%-át másolni vagy törölni fogja.</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>A következÅ‘ könyvtárak lényegileg különböznek. GyÅ‘zÅ‘djön meg róla, hogy a megfelelÅ‘ könyvtárakat illesztette-e össze szinkronizáláshoz.</target> <source>Not enough free disk space available in:</source> <target>Nincs elég szabad lemezterület:</target> @@ -492,12 +528,15 @@ A parancs végrehajtódik, ha: <source>Generating database...</source> <target>Adatbázis generálása...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>Kötet árnyékmásolat (Volume Shadow Copy) létrehozása %x számára...</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>KészÃt egy ányékmásolat-kötetet %x számára</target> <source>Data verification error: %x and %y have different content.</source> <target>Adat-ellenÅ‘rzési hiba: %x és %y tartalma különbözÅ‘.</target> +<source>job name</source> +<target>feladat neve</target> + <source>Synchronization aborted</source> <target>A szinkronizálás megszakÃtva</target> @@ -522,6 +561,9 @@ A parancs végrehajtódik, ha: <source>Switching to FreeFileSync main dialog</source> <target>Váltás a FreeFileSync fÅ‘ párbeszéd-ablakára</target> +<source>Retrying operation after error:</source> +<target>Újrapróbálja a műveletet a hiba után:</target> + <source>A new version of FreeFileSync is available:</source> <target>ElérhetÅ‘ a FreeFileSync új verziója:</target> @@ -645,8 +687,8 @@ A parancs végrehajtódik, ha: <source>&Export file list...</source> <target>&Exportálja a fájllistát...</target> -<source>&Global settings...</source> -<target>&Globális beállÃtások...</target> +<source>&Global settings</source> +<target>&Globális beállÃtások</target> <source>&Tools</source> <target>Es&zközök</target> @@ -717,6 +759,9 @@ A parancs végrehajtódik, ha: <source>Synchronizing...</source> <target>Szinkronizálás folyamatban...</target> +<source>Minimize to notification area</source> +<target>Minimalizálja a figyelmeztetési területre</target> + <source>On completion</source> <target>Befejezés esetén</target> @@ -726,6 +771,15 @@ A parancs végrehajtódik, ha: <source>&Pause</source> <target>&Várakozás</target> +<source>Variant</source> +<target>Variáns</target> + +<source>Statistics</source> +<target>Statisztika</target> + +<source>&Don't show this dialog again</source> +<target>&Ne mutassa ismételten ezt a párbeszédablakot</target> + <source>Select a variant</source> <target>Válassz egy variánst</target> @@ -774,11 +828,17 @@ megegyezik <source>Configure your own synchronization rules.</source> <target>ÃllÃtsd be a saját szinkronizálási szabályaidat</target> +<source>Detect moved files</source> +<target>Érzékelje a mozgatott fájlokat</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Adatbázis fájlok szükségesek. Nem minden fájlrendszer támogatja.</target> + <source>Error handling</source> <target>Hibakezelés</target> <source>Ignore</source> -<target>Kihagy</target> +<target>Figyelmen kÃvül hagy</target> <source>Hide all error and warning messages</source> <target>Rejtse el az összes hibaüzenetet és figyelmeztetést</target> @@ -798,17 +858,17 @@ megegyezik <source>Delete or overwrite files permanently</source> <target>Törölje vagy Ãrja felül véglegesen a fájlokat</target> -<source>Recycle Bin</source> -<target>Lomtár (Recycle Bin)</target> +<source>Recycle bin</source> +<target>Lomtár</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Használd a Lomtárat a törölt és felülÃrt fájlok számára</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Mentse a törölt és felülÃrt fájlokat a Lomtárba</target> <source>Versioning</source> <target>Verziókövetés</target> -<source>Move files to user-defined folder</source> -<target>Mozgasd a fájlokat a felhasználó által megadott könyvtárba</target> +<source>Move files to a user-defined folder</source> +<target>Mozgassa a fájlokat egy a felhasználó által meghatározott könyvtárba</target> <source>Naming convention:</source> <target>Elnevezési konvenció:</target> @@ -816,8 +876,8 @@ megegyezik <source>Batch job</source> <target>Kötegelt feladat</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Kötegelt fájl létrehozása a szinkronizálás automatizálásához. Kattints duplán a fájlnévre vagy ütemezd a rendszered feladatütemezÅ‘jével: FreeFileSync.exe <feladatnév>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Készitsen egy parancsfájlt a felügyelet nélküli szinkronizáláshoz. Az indÃtáshoz kattintson kétszer erre a fájlra vagy ütemezze a feladat-tervezÅ‘ben: %x</target> <source>Exit</source> <target>Kilép</target> @@ -871,12 +931,12 @@ megegyezik <target>Törlés mindkét oldalon, még akkor is, ha a fájl csak az egyik oldalon lett kijelölve</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -Csak a valamennyi szűrÅ‘-beállÃtásnak megfelelÅ‘ fájlok lesznek szinkronizálva. -Megjegyzés: A fájlneveket az alapkönyvtárakhoz képest kell vizsgálni. +A fájlokat csak akkor szinkronizálja, ha azok valamennyi szűrÅ‘feltételnek megfelelnek. +Megjegyzés: Az útvonalakat az alapkönyvtárakhoz képest kell megadni. </target> <source>Include</source> @@ -906,20 +966,20 @@ Megjegyzés: A fájlneveket az alapkönyvtárakhoz képest kell vizsgálni. <source>Fail-safe file copy</source> <target>Hibamentes fájlmásolás</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>Ãrja egy ideiglenes fájlba (*.ffs_tmp), majd azt nevezze át. Ez garantálja az konzisztens állapotot még végzetes hiba esetén is.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>Másolja elÅ‘ször egy ideiglenes fájlba (*.ffs_tmp) aztán nevezze át. Ez garantálja a konzisztents állapotot végzetes hibák esetén is.</target> <source>Copy locked files</source> <target>Másolja a zárolt fájlokat</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Másolja a megosztott vagy zárolt fájlokat a Volume Shadow Copy szolgáltatással (Adminisztrátori jogosultság szükséges)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>A megosztott és zárolt fájlokat a kötet-árnyékmásolat szolgáltatás használatával másolja(adminisztrátori jogosultság szükséges)</target> <source>Copy file access permissions</source> <target>Másolja a fájl hozzáférési jogosultságokat</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Fájlok és könytárak jogosultságainak átvitele (Adminisztrátori jogosultság szükséges)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>ÖrökÃtse át a fájl és könyvtár jogosultságokat (adminisztrátori jogosultság szükséges)</target> <source>Restore hidden dialogs</source> <target>ÃllÃtsa vissza a rejtett párbeszédablakokat</target> @@ -933,15 +993,6 @@ Megjegyzés: A fájlneveket az alapkönyvtárakhoz képest kell vizsgálni. <source>&Default</source> <target>&Alapértelmezett</target> -<source>Variant</source> -<target>Variáns</target> - -<source>Statistics</source> -<target>Statisztika</target> - -<source>Don't show this dialog again</source> -<target>Ne mutasd többé ezt a párbeszédablakot</target> - <source>Find what:</source> <target>Mit keres:</target> @@ -951,15 +1002,15 @@ Megjegyzés: A fájlneveket az alapkönyvtárakhoz képest kell vizsgálni. <source>&Find next</source> <target>&Keresse a következÅ‘t</target> +<source>Start synchronization</source> +<target>IndÃtja a szinkronizálást</target> + <source>Delete</source> <target>Töröl</target> <source>Configure filter</source> <target>BeállÃtja a szűrÅ‘t</target> -<source>Start synchronization</source> -<target>IndÃtja a szinkronizálást</target> - <source>Find</source> <target>Keres:</target> @@ -994,6 +1045,21 @@ Megjegyzés: A fájlneveket az alapkönyvtárakhoz képest kell vizsgálni. <target>Vesse össze mindkét oldalt</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>Tényleg a végre akarja hajtani a(z) %y parancsot a következÅ‘ elemen?</pluralform> +<pluralform>Tényleg a végre akarja hajtani a(z) %y parancsot a következÅ‘ %x elemen?</pluralform> +</target> + +<source>Confirm</source> +<target>Jóváhagy</target> + +<source>&Execute</source> +<target>Vé&grehajt</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1029,12 +1095,15 @@ Megjegyzés: A fájlneveket az alapkönyvtárakhoz képest kell vizsgálni. <source>Include temporarily</source> <target>Csatolja ideiglenesen</target> -<source>Exclude via filter:</source> -<target>Zárja ki szűrÅ‘ segÃtségével:</target> - <source>multiple selection</source> <target>többszörös kijelölés</target> +<source>Include via filter:</source> +<target>A szűrÅ‘t figyelembe véve adja hozzá</target> + +<source>Exclude via filter:</source> +<target>Zárja ki szűrÅ‘ segÃtségével:</target> + <source>Include all</source> <target>Csatolja az összest</target> @@ -1080,8 +1149,8 @@ Megjegyzés: A fájlneveket az alapkönyvtárakhoz képest kell vizsgálni. <source>Do&n't save</source> <target>&ne mentse</target> -<source>Never save changes</source> -<target>Ne mentse a változtatásokat</target> +<source>Never save &changes</source> +<target>N&e mentse a változásokat</target> <source>Show files that exist on left side only</source> <target>Mutassa a csak a bal oldalon létezÅ‘ fájlokat</target> @@ -1134,8 +1203,8 @@ Megjegyzés: A fájlneveket az alapkönyvtárakhoz képest kell vizsgálni. <source>All folders are in sync</source> <target>Minden könyvtár szinkronban</target> -<source>Comma separated list</source> -<target>CSV formátumú (vesszÅ‘vel elválasztott) lista</target> +<source>Comma-separated values</source> +<target>VesszÅ‘vel elválasztott értékek (CSV)</target> <source>File list exported</source> <target>A fájllista exportálása befejezÅ‘dött</target> @@ -1143,8 +1212,8 @@ Megjegyzés: A fájlneveket az alapkönyvtárakhoz képest kell vizsgálni. <source>Searching for program updates...</source> <target>ProgramfrissÃtés keresése...</target> -<source>Ignore further errors</source> -<target>Hagyja figyelmen kÃvül a további hibákat</target> +<source>&Ignore subsequent errors</source> +<target>F&igyelmen kÃvül hagyja az utána következÅ‘ hibákat</target> <source>&Ignore</source> <target>&Kihagy</target> @@ -1152,8 +1221,8 @@ Megjegyzés: A fájlneveket az alapkönyvtárakhoz képest kell vizsgálni. <source>Fatal Error</source> <target>Kritikus hiba</target> -<source>Don't show this warning again</source> -<target>Ne mutassa ismét ezt a figyelmeztetést</target> +<source>&Don't show this warning again</source> +<target>&Ne mutassa ismételten ezt a figyelmeztetést</target> <source>&Switch</source> <target>&Váltás</target> @@ -1188,14 +1257,11 @@ Megjegyzés: A fájlneveket az alapkönyvtárakhoz képest kell vizsgálni. <source>Completed</source> <target>BefejezÅ‘dött</target> -<source>Continue</source> -<target>Folytat</target> +<source>&Continue</source> +<target>&Folytat</target> -<source>Pause</source> -<target>Szünet</target> - -<source>Logging</source> -<target>Naplózás</target> +<source>Log</source> +<target>Napló</target> <source>Cannot find %x</source> <target>Nem található: %x</target> @@ -1231,12 +1297,12 @@ Megjegyzés: A fájlneveket az alapkönyvtárakhoz képest kell vizsgálni. <target>SzűrÅ‘</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>Valóban a Lomtárba akarod mozgatni a következÅ‘ elemet?</pluralform> -<pluralform>Valóban a Lomtárba akarod mozgatni a következÅ‘ %x elemet?</pluralform> +<pluralform>Tényleg a Lomtárba akarja áthelyezni a következÅ‘ elemet?</pluralform> +<pluralform>Tényleg a Lomtárba akarja áthelyezni a következÅ‘ %x elemet?</pluralform> </target> <source> @@ -1290,9 +1356,6 @@ Megjegyzés: A fájlneveket az alapkönyvtárakhoz képest kell vizsgálni. <source>Append a timestamp to each file name</source> <target>Adjon idÅ‘bélyeget minden fájlnévhez</target> -<source>Folder</source> -<target>Könyvtár</target> - <source>File</source> <target>Fájl</target> @@ -1413,8 +1476,8 @@ Megjegyzés: A fájlneveket az alapkönyvtárakhoz képest kell vizsgálni. <source>Cannot change process I/O priorities.</source> <target>Nem sikerült a folyamatok I/O prioritását megváltoztatni.</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>%x Lomtárba helyezése sikertelen.</target> +<source>Unable to move %x to the recycle bin.</source> +<target>%x nem helyezhetÅ‘ a Lomtárba</target> <source>Cannot determine final path for %x.</source> <target>Nem lehet meghatározni a végsÅ‘ útvonalat a(z) %x számára.</target> diff --git a/BUILD/Languages/italian.lng b/BUILD/Languages/italian.lng index 3dcac298..3a3f8e3d 100644 --- a/BUILD/Languages/italian.lng +++ b/BUILD/Languages/italian.lng @@ -7,78 +7,6 @@ <plural_definition>n == 1 ? 0 : 1</plural_definition> </header> -<source>Log</source> -<target></target> - -<source>Comma-separated values</source> -<target></target> - -<source>Minimize to notification area</source> -<target></target> - -<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> -<target></target> - -<source>&Show error</source> -<target></target> - -<source>Waiting until all directories are available...</source> -<target></target> - -<source>Directory monitoring active</source> -<target></target> - -<source>Volume name %x is not part of file path %y.</source> -<target></target> - -<source>%x items</source> -<target></target> - -<source> -<pluralform>1 thread</pluralform> -<pluralform>%x threads</pluralform> -</source> -<target></target> - -<source> -<pluralform>1 byte</pluralform> -<pluralform>%x bytes</pluralform> -</source> -<target></target> - -<source>Any number of alternative directories for at most one config file.</source> -<target></target> - -<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> -<target></target> - -<source>directory</source> -<target></target> - -<source>config files</source> -<target></target> - -<source>Syntax:</source> -<target></target> - -<source>Directories cannot be set for more than one configuration file.</source> -<target></target> - -<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> -<target></target> - -<source>Unequal number of left and right directories specified.</source> -<target></target> - -<source>Cannot open file %x.</source> -<target></target> - -<source>Syntax error</source> -<target></target> - -<source>A directory path is expected after %x.</source> -<target></target> - <source>Both sides have changed since last synchronization.</source> <target>Entrambi i lati sono cambiati dall'ultima sincronizzazione.</target> @@ -97,14 +25,14 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Controllo di disponibilità Cestino per la cartella %x...</target> -<source>Moving file %x to recycle bin</source> -<target>Spostamento file %x nel Cestino</target> +<source>Moving file %x to the recycle bin</source> +<target>Spostamento file %x nel cestino</target> -<source>Moving folder %x to recycle bin</source> -<target>Spostamento cartella %x nel Cestino</target> +<source>Moving folder %x to the recycle bin</source> +<target>Spostamento delle cartelle %x nel cestino</target> -<source>Moving symbolic link %x to recycle bin</source> -<target>Spostamento collegamento %x nel Cestino</target> +<source>Moving symbolic link %x to the recycle bin</source> +<target>Spostamento collegamento %x nel cestino</target> <source>Deleting file %x</source> <target>Eliminazione file %x</target> @@ -115,21 +43,54 @@ <source>Deleting symbolic link %x</source> <target>Eliminazione collegamento %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>Il Cestino non è disponibile per le seguenti cartelle. I file verranno quindi eliminati in modo permanente:</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>Il cestino non è disponibile per le seguenti cartelle. I file verranno invece eliminati in modo permanente:</target> <source>An exception occurred</source> <target>Si è verificata una eccezione</target> +<source>A directory path is expected after %x.</source> +<target>Un percorso di directory è previsto dopo %x.</target> + +<source>Syntax error</source> +<target>Errore di sintassi</target> + +<source>Cannot open file %x.</source> +<target>Impossibile aprire il file %x.</target> + <source>Error</source> <target>Errore</target> <source>File %x does not contain a valid configuration.</source> <target>Il file %x non contiene una configurazione valida.</target> +<source>Unequal number of left and right directories specified.</source> +<target>Numero disuguale di directory sinistra e destra specificate.</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>Il file di configurazione non deve contenere le impostazioni a livello di coppia di directory quando le directory sono impostati tramite linea di comando.</target> + <source>Warning</source> <target>Attenzione</target> +<source>Directories cannot be set for more than one configuration file.</source> +<target>Directory non possono essere impostate per più di un file di configurazione.</target> + +<source>Syntax:</source> +<target>Sintassi:</target> + +<source>config files</source> +<target>file di configurazione</target> + +<source>directory</source> +<target>directory</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>Qualsiasi numero di FreeFileSync.ffs_gui e/o File di configurazione .ffs_batch.</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>Qualsiasi numero di directory alternativa per al massimo un file di configurazione.</target> + <source>Command line</source> <target>Linea di comando</target> @@ -289,6 +250,15 @@ <source>Total time:</source> <target>Tempo totale:</target> +<source> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> +</source> +<target> +<pluralform>1 byte</pluralform> +<pluralform>%x byte</pluralform> +</target> + <source>%x MB</source> <target>%x MB</target> @@ -307,12 +277,24 @@ <source>Scanning:</source> <target>Scansione di:</target> +<source> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> +</source> +<target> +<pluralform>1 thread</pluralform> +<pluralform>%x thread</pluralform> +</target> + <source>Encoding extended time information: %x</source> <target>Codifica estesa informazioni orario: %x</target> <source>/sec</source> <target>/sec</target> +<source>%x items</source> +<target>%x articoli</target> + <source>Configuration file %x loaded partially only.</source> <target>File di configurazione %x caricato solo parzialmente.</target> @@ -325,8 +307,8 @@ <source>Browse directory</source> <target>Sfoglia cartelle</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Impossibile accedere al servizio Volume Shadow Copy.</target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target>Impossibile accedere al Volume Shadow Copy Service.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>E' necessario utilizzare FreeFileSync versione 64-bit per creare copie shadow su questo sistema.</target> @@ -337,6 +319,9 @@ <source>Cannot determine volume name for %x.</source> <target>Impossibile determinare nome del volume per %x.</target> +<source>Volume name %x is not part of file path %y.</source> +<target>Nome volume %x non fa parte del percorso del file %y.</target> + <source>Abort requested: Waiting for current operation to finish...</source> <target>Richiesta interruazione: attendere conclusione dell'operazione...</target> @@ -435,9 +420,18 @@ Il comando è attivato se: <source>All files</source> <target>Tutti i file</target> +<source>Directory monitoring active</source> +<target>Directory di monitoraggio attiva</target> + +<source>Waiting until all directories are available...</source> +<target>Aspettare fino a quando sono disponibili tutte le directory...</target> + <source>&Restore</source> <target>&Ripristina</target> +<source>&Show error</source> +<target>&Mostra errore</target> + <source>&Exit</source> <target>&Esci</target> @@ -513,6 +507,9 @@ Il comando è attivato se: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>I seguenti oggetti hanno conflitti irrisolti e non saranno sincronizzati:</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>Le seguenti cartelle sono significativamente differenti. Assicurarsi che si sta confrontando le cartelle corrette per la sincronizzazione.</target> + <source>Not enough free disk space available in:</source> <target>Spazio libero su disco insufficiente in:</target> @@ -531,12 +528,15 @@ Il comando è attivato se: <source>Generating database...</source> <target>Generazione database...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>Creazione di Volume Shadow Copy per %x...</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>Creazione di un Volume Shadow Copy per %x...</target> <source>Data verification error: %x and %y have different content.</source> <target>Dati di verifica errore: %x e %y hanno un contenuto diverso.</target> +<source>job name</source> +<target>nome del lavoro</target> + <source>Synchronization aborted</source> <target>Sincronizzazione abortita</target> @@ -687,8 +687,8 @@ Il comando è attivato se: <source>&Export file list...</source> <target>&Esporta l'elenco dei file...</target> -<source>&Global settings...</source> -<target>&Preferenze...</target> +<source>&Global settings</source> +<target>&Preferenze</target> <source>&Tools</source> <target>&Strumenti</target> @@ -759,6 +759,9 @@ Il comando è attivato se: <source>Synchronizing...</source> <target>Sincronizzazione...</target> +<source>Minimize to notification area</source> +<target>Ridurre al minimo l'area di notifica</target> + <source>On completion</source> <target>In completamento</target> @@ -774,8 +777,8 @@ Il comando è attivato se: <source>Statistics</source> <target>Statistiche</target> -<source>Don't show this dialog again</source> -<target>Non mostrare più questo messaggio</target> +<source>&Don't show this dialog again</source> +<target>&Non mostrare più questo avviso</target> <source>Select a variant</source> <target>Seleziona una variante</target> @@ -825,6 +828,12 @@ I file sono considerati identici se <source>Configure your own synchronization rules.</source> <target>Configura le tue regole di sincronizzazione.</target> +<source>Detect moved files</source> +<target>Rileva file spostati</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Richiede il file di database. Non è supportato da tutti i sistemi di file.</target> + <source>Error handling</source> <target>Gestione degli errori</target> @@ -849,17 +858,17 @@ I file sono considerati identici se <source>Delete or overwrite files permanently</source> <target>Elimina o sovrascrivi i file definitivamente</target> -<source>Recycle Bin</source> +<source>Recycle bin</source> <target>Cestino</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Utilizza il Cestino per file cancellati e sovrascritti</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Eseguire il backup di file sovrascritti e cancellati nel cestino</target> <source>Versioning</source> <target>Versione</target> -<source>Move files to user-defined folder</source> -<target>Sposta file in cartella personalizzata</target> +<source>Move files to a user-defined folder</source> +<target>Spostare i file in una cartella definita dall'utente</target> <source>Naming convention:</source> <target>Modalità di rinomina:</target> @@ -867,8 +876,8 @@ I file sono considerati identici se <source>Batch job</source> <target>Attività batch</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Crea un file batch per automatizzare la sincronizzazione. Doppio click su questo file o schedula nelle operazioni pianificate del tuo sistema: FreeFileSync.exe <nome file batch>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Creare un file batch per la sincronizzazione automatica. Per iniziare, fare doppio clic su questo file o programmarlo in un pianificatore di compiti: %x</target> <source>Exit</source> <target>Esci</target> @@ -922,12 +931,12 @@ I file sono considerati identici se <target>Elimina su entrambi i lati anche se il file è selezionato su un solo lato.</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -Solo i file che corrispondono esattamente a tutti i parametri dei filtri verrranno sincronizzati. -Nota: I nomi dei file devono essere relativi alle cartelle di appartenenza. +I file verranno sincronizzati solo se passano tutte le regole di filtraggio. +Nota: percorso dei file deve essere relativo alla directory di base. </target> <source>Include</source> @@ -957,20 +966,20 @@ Nota: I nomi dei file devono essere relativi alle cartelle di appartenenza. <source>Fail-safe file copy</source> <target>Copia file di fail-safe</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 in un file temporaneo (*.ffs_tmp) prima di rinominarlo. Ciò garantisce uno stato consistente anche in caso di errore fatale.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>Copiare prima in un file temporaneo (*.ffs_tmp) poi rinominarlo. Questo garantisce uno stato costante anche in caso di un 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 amministratore)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>Copiare i file condivisi o bloccati usando il Volume Shadow Copy Service (richiede i diritti di amministratore)</target> <source>Copy file access permissions</source> <target>Copia permessi di accesso file</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Permessi di traferimento file e cartelle (Richiede diritti di Amministratore)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>Trasferimento di file e autorizzazioni cartelle (richiede i diritti di amministratore)</target> <source>Restore hidden dialogs</source> <target>Ripristina i messaggi nascosti</target> @@ -1050,9 +1059,6 @@ Nota: I nomi dei file devono essere relativi alle cartelle di appartenenza. <source>&Execute</source> <target>&Esecuzione</target> -<source>&Don't show this dialog again</source> -<target>&Non mostrare più questo avviso</target> - <source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> @@ -1089,12 +1095,15 @@ Nota: I nomi dei file devono essere relativi alle cartelle di appartenenza. <source>Include temporarily</source> <target>Includi temporaneamente</target> -<source>Exclude via filter:</source> -<target>Escludi tramite filtro:</target> - <source>multiple selection</source> <target>selezione multipla</target> +<source>Include via filter:</source> +<target>Includi tramite filtro:</target> + +<source>Exclude via filter:</source> +<target>Escludi tramite filtro:</target> + <source>Include all</source> <target>Includi tutto</target> @@ -1140,8 +1149,8 @@ Nota: I nomi dei file devono essere relativi alle cartelle di appartenenza. <source>Do&n't save</source> <target>No&n salvare</target> -<source>Never save changes</source> -<target>Non salvare mai le modifiche</target> +<source>Never save &changes</source> +<target>Non salvare mai &modifiche</target> <source>Show files that exist on left side only</source> <target>Mostra file esistenti solo a sinistra</target> @@ -1194,14 +1203,17 @@ Nota: I nomi dei file devono essere relativi alle cartelle di appartenenza. <source>All folders are in sync</source> <target>Tutte le cartelle sono sincronizzate</target> +<source>Comma-separated values</source> +<target>Valori separati da virgole</target> + <source>File list exported</source> <target>Elenco file esportato</target> <source>Searching for program updates...</source> <target>Ricerca di aggiornamenti al programma...</target> -<source>Ignore further errors</source> -<target>Ignora i prossimi errori</target> +<source>&Ignore subsequent errors</source> +<target>&Ignora errori successivi</target> <source>&Ignore</source> <target>&Ignora</target> @@ -1209,8 +1221,8 @@ Nota: I nomi dei file devono essere relativi alle cartelle di appartenenza. <source>Fatal Error</source> <target>Errore fatale</target> -<source>Don't show this warning again</source> -<target>Non mostrare più questo avviso</target> +<source>&Don't show this warning again</source> +<target>&Non mostrare più questo avviso</target> <source>&Switch</source> <target>&Passa</target> @@ -1248,6 +1260,9 @@ Nota: I nomi dei file devono essere relativi alle cartelle di appartenenza. <source>&Continue</source> <target>&Continuare</target> +<source>Log</source> +<target>Log</target> + <source>Cannot find %x</source> <target>Impossibile trovare %x</target> @@ -1282,12 +1297,12 @@ Nota: I nomi dei file devono essere relativi alle cartelle di appartenenza. <target>Filtro</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items 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 davvero spostare la seguente voce nel cestino?</pluralform> +<pluralform>Vuoi davvero spostare i seguenti %x articoli nel cestino?</pluralform> </target> <source> @@ -1461,8 +1476,8 @@ Nota: I nomi dei file devono essere relativi alle cartelle di appartenenza. <source>Cannot change process I/O priorities.</source> <target>Impossibile modificare le priorità I/O del processo.</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>Impossibile spostare %x nel Cestino.</target> +<source>Unable to move %x to the recycle bin.</source> +<target>Impossibile spostare %x nel cestino.</target> <source>Cannot determine final path for %x.</source> <target>Impossibile determinare il percorso finale per %x.</target> diff --git a/BUILD/Languages/japanese.lng b/BUILD/Languages/japanese.lng index fb3de4e8..d27d0ff2 100644 --- a/BUILD/Languages/japanese.lng +++ b/BUILD/Languages/japanese.lng @@ -25,13 +25,13 @@ <source>Checking recycle bin availability for folder %x...</source> <target>フォルダ %x をゴミ箱ã¨ã—ã¦ä½¿ç”¨ã§ãã‚‹ã‹ã‚’確èªä¸...</target> -<source>Moving file %x to recycle bin</source> +<source>Moving file %x to the recycle bin</source> <target>ファイル %x をゴミ箱ã«ç§»å‹•ä¸</target> -<source>Moving folder %x to recycle bin</source> +<source>Moving folder %x to the recycle bin</source> <target>フォルダ %x をゴミ箱ã«ç§»å‹•ä¸</target> -<source>Moving symbolic link %x to recycle bin</source> +<source>Moving symbolic link %x to the recycle bin</source> <target>シンボリックリンク %x をゴミ箱ã«ç§»å‹•ä¸</target> <source>Deleting file %x</source> @@ -43,14 +43,20 @@ <source>Deleting symbolic link %x</source> <target>シンボリックリンク %x を削除ä¸</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>以下ã®ãƒ•ã‚©ãƒ«ãƒ€ã§ã¯ã€ã‚´ãƒŸç®±ã‚’使用ã™ã‚‹äº‹ãŒå‡ºæ¥ã¾ã›ã‚“。代替手段ã¨ã—ã¦ãƒ•ã‚¡ã‚¤ãƒ«ã¯å®Œå…¨ã«å‰Šé™¤ã•ã‚Œã¾ã™:</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>以下ã®ãƒ•ã‚©ãƒ«ãƒ€ã§ã¯ã‚´ãƒŸç®±ã‚’利用ã§ãã¾ã›ã‚“。代替手段ã¨ã—ã¦ãƒ•ã‚¡ã‚¤ãƒ«ã®å®Œå…¨å‰Šé™¤ã‚’利用ã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™:</target> <source>An exception occurred</source> <target>例外ãŒç™ºç”Ÿã—ã¾ã—ãŸ</target> -<source>Cannot find file %x.</source> -<target>ファイル %x ãŒã¿ã¤ã‹ã‚Šã¾ã›ã‚“.</target> +<source>A directory path is expected after %x.</source> +<target>%x ã®å¾Œã«ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãƒ»ãƒ‘スãŒå¿…è¦ã§ã™</target> + +<source>Syntax error</source> +<target>構文エラー</target> + +<source>Cannot open file %x.</source> +<target>ファイル %x ã‚’é–‹ã‘ã¾ã›ã‚“</target> <source>Error</source> <target>エラー</target> @@ -58,6 +64,36 @@ <source>File %x does not contain a valid configuration.</source> <target>ファイル %x ã«ã¯æœ‰åŠ¹ãªæ§‹æˆãŒå«ã¾ã‚Œã¦ã„ã¾ã›ã‚“.</target> +<source>Unequal number of left and right directories specified.</source> +<target>誤ã£ãŸæ•°ã®å·¦å³ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒæŒ‡å®šã•ã‚Œã¦ã„ã¾ã™.</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>コマンドライン経由ã§ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒè¨å®šã•ã‚Œã¦ã„る時ã¯ã€æ§‹æˆè¨å®šã«ãƒšã‚¢ãƒ»ãƒ¬ãƒ™ãƒ«ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¯å«ã‚られã¾ã›ã‚“.</target> + +<source>Warning</source> +<target>è¦å‘Š</target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target>構æˆè¨å®šãƒ•ã‚¡ã‚¤ãƒ«ã«ã²ã¨ã¤ä»¥ä¸Šã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¯è¨å®šã§ãã¾ã›ã‚“.</target> + +<source>Syntax:</source> +<target>構文:</target> + +<source>config files</source> +<target>構æˆè¨å®šãƒ•ã‚¡ã‚¤ãƒ«</target> + +<source>directory</source> +<target>ディレクトリ</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>ä»»æ„ã®æ•°ã® FreeFileSync 構æˆè¨å®šãƒ•ã‚¡ã‚¤ãƒ«(.ffs_gui ãŠã‚ˆã³/ã¾ãŸã¯ .ffs_batch).</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>ã²ã¨ã¤ã®æ§‹æˆè¨å®šãƒ•ã‚¡ã‚¤ãƒ«ã«å¯¾ã—ã¦ä»»æ„ã®æ•°ã®ä»£æ›¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª.</target> + +<source>Command line</source> +<target>コマンドライン</target> + <source>A folder input field is empty.</source> <target>フォルダ入力欄ãŒç©ºç™½ã§ã™.</target> @@ -214,8 +250,8 @@ <target>åˆè¨ˆæ™‚é–“:</target> <source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </source> <target> <pluralform>%x ãƒã‚¤ãƒˆ</pluralform> @@ -240,11 +276,11 @@ <target>スã‚ャン:</target> <source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </source> <target> -<pluralform>[%x スレッド]</pluralform> +<pluralform>%x スレッド</pluralform> </target> <source>Encoding extended time information: %x</source> @@ -253,6 +289,9 @@ <source>/sec</source> <target>/秒</target> +<source>%x items</source> +<target>%x 個ã®é …ç›®</target> + <source>Configuration file %x loaded partially only.</source> <target>構æˆãƒ•ã‚¡ã‚¤ãƒ« %x ã¯éƒ¨åˆ†çš„ã®ã¿èªã¿è¾¼ã¾ã‚Œã¾ã™.</target> @@ -265,8 +304,8 @@ <source>Browse directory</source> <target>ディレクトリをå‚ç…§</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>ボリï½ï½°ï¾‘シャドウコピーサービスã«ã‚¢ã‚¯ã‚»ã‚¹å‡ºæ¥ã¾ã›ã‚“.</target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target>ボリュームシャドウコピーサービスã«ã‚¢ã‚¯ã‚»ã‚¹å‡ºæ¥ã¾ã›ã‚“.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>FreeFileSync 64-bit 版を使用ã—ã¦ã“ã®ã‚·ã‚¹ãƒ†ãƒ ã«ã‚·ãƒ£ãƒ‰ã‚¦ã‚³ãƒ”ーを作æˆã—ã¦ãã ã•ã„.</target> @@ -277,8 +316,8 @@ <source>Cannot determine volume name for %x.</source> <target>%x ã®ãƒœãƒªãƒ¥ãƒ¼ãƒ åãŒæ±ºå®šã•ã‚Œã¦ã„ã¾ã›ã‚“</target> -<source>Volume name %x not part of file name %y.</source> -<target>ボリュームå %x ã«ãƒ•ã‚¡ã‚¤ãƒ«å %y ã¯ã‚ã‚Šã¾ã›ã‚“.</target> +<source>Volume name %x is not part of file path %y.</source> +<target>ボリュームå %x ã¯ã€ãƒ•ã‚¡ã‚¤ãƒ«ãƒ‘ス %y ã®ä¸€éƒ¨ã§ã¯ã‚ã‚Šã¾ã›ã‚“.</target> <source>Abort requested: Waiting for current operation to finish...</source> <target>ユーザã«ã‚ˆã‚‹ä¸æ–: ç¾åœ¨ã®å‡¦ç†ã‚’終了ã—ã¦ã„ã¾ã™.. ãŠå¾…ã¡ãã ã•ã„...</target> @@ -346,9 +385,6 @@ <source>Idle time between last detected change and execution of command</source> <target>最後ã«ã‚³ãƒžãƒ³ãƒ‰ã‚’実行ã—ã¦ã‹ã‚‰ã€æ¬¡ã«å¤‰æ›´ã‚’検出ã™ã‚‹ã¾ã§ã®å¾…機時間</target> -<source>Command line</source> -<target>コマンドライン</target> - <source> The command is triggered if: - files or subfolders change @@ -372,9 +408,6 @@ The command is triggered if: <source>RealtimeSync - Automated Synchronization</source> <target>リアルタイムåŒæœŸ - 自動åŒæœŸ</target> -<source>Warning</source> -<target>è¦å‘Š</target> - <source>Build: %x</source> <target>ビルド: %x</target> @@ -384,15 +417,21 @@ The command is triggered if: <source>All files</source> <target>ã™ã¹ã¦ã®ãƒ•ã‚¡ã‚¤ãƒ«</target> +<source>Directory monitoring active</source> +<target>ディレクトリã®ç›£è¦–アクティブ</target> + +<source>Waiting until all directories are available...</source> +<target>全ディレクトリãŒåˆ©ç”¨å¯èƒ½ã«ãªã‚‹ã¾ã§å¾…æ©Ÿä¸...</target> + <source>&Restore</source> <target>修復(&R)</target> +<source>&Show error</source> +<target>エラー表示(&S)</target> + <source>&Exit</source> <target>終了(&E)</target> -<source>Waiting for missing directories...</source> -<target>見失ã£ãŸãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®å¾…æ©Ÿä¸...</target> - <source>Invalid command line:</source> <target>無効ãªã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³:</target> @@ -402,14 +441,14 @@ The command is triggered if: <source>File time and size</source> <target>ファイル時刻ã¨ã‚µã‚¤ã‚º</target> -<source> Two way </source> -<target> ä¸¡æ–¹å‘ </target> +<source>Two way</source> +<target>両方å‘</target> <source>Mirror</source> -<target>ミラー </target> +<target>ミラー</target> <source>Update</source> -<target>æ›´æ–° </target> +<target>æ›´æ–°</target> <source>Custom</source> <target>カスタム</target> @@ -465,11 +504,8 @@ The command is triggered if: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>以下ã®é …ç›®ã¯ã€æœªè§£æ±ºã®ç«¶åˆãŒå˜åœ¨ã™ã‚‹ãŸã‚åŒæœŸå‡¦ç†ã‚’実行ã§ãã¾ã›ã‚“ã§ã—ãŸ:</target> -<source>Significant difference detected:</source> -<target>é‡å¤§ãªå·®ç•°ãŒæ¤œå‡ºã•ã‚Œã¾ã—ãŸ:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>ファイルåˆè¨ˆç·æ•°ã® 50% 以上ãŒå‰Šé™¤ã€ã¾ãŸã¯ã‚³ãƒ”ーã•ã‚Œã¾ã™ã€‚</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>以下ã®ãƒ•ã‚©ãƒ«ãƒ€ã«ã¯å¤§é‡ã®å·®ç•°ãŒå˜åœ¨ã—ã¾ã™ã€‚åŒæœŸãƒ•ã‚©ãƒ«ãƒ€ã®åŒæ–¹ãŒæ£ç¢ºã«ã‚»ãƒƒãƒˆã•ã‚Œã¦ã„ã‚‹ã‹ã©ã†ã‹ã‚’ã‚‚ã†ä¸€åº¦æ…Žé‡ã«ã”確èªãã ã•ã„.</target> <source>Not enough free disk space available in:</source> <target>利用å¯èƒ½ãªãƒ‡ã‚£ã‚¹ã‚¯ç©ºã容é‡ãŒè¶³ã‚Šã¾ã›ã‚“:</target> @@ -489,12 +525,15 @@ The command is triggered if: <source>Generating database...</source> <target>データベースを作æˆä¸...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>%x ã®ãƒœãƒªãƒ¥ãƒ¼ãƒ シャドウコピーを作æˆä¸...</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>ボリュームシャドウコピーを作æˆä¸ %x...</target> <source>Data verification error: %x and %y have different content.</source> <target>データ検証エラー: %x 㨠%y ã«ã¯ç•°ãªã‚‹å†…容ãŒå«ã¾ã‚Œã¦ã„ã¾ã™.</target> +<source>job name</source> +<target>ジョブå</target> + <source>Synchronization aborted</source> <target>åŒæœŸå‡¦ç†ã‚’ä¸æ–</target> @@ -519,6 +558,9 @@ The command is triggered if: <source>Switching to FreeFileSync main dialog</source> <target>FreeFileSync メインダイアãƒã‚°ã‚’切り替ãˆä¸</target> +<source>Retrying operation after error:</source> +<target>エラーã®å¾Œã§å‡¦ç†ã‚’å†è©¦è¡Œ:</target> + <source>A new version of FreeFileSync is available:</source> <target>FreeFileSync ã®æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒåˆ©ç”¨ã§ãã¾ã™:</target> @@ -642,8 +684,8 @@ The command is triggered if: <source>&Export file list...</source> <target>ファイル一覧をエクスãƒãƒ¼ãƒˆ(&E)...</target> -<source>&Global settings...</source> -<target>全般的ãªè¨å®š(&G)...</target> +<source>&Global settings</source> +<target>全般的ãªè¨å®š(&G)</target> <source>&Tools</source> <target>ツール(&T)</target> @@ -714,6 +756,9 @@ The command is triggered if: <source>Synchronizing...</source> <target>åŒæœŸå‡¦ç†ä¸...</target> +<source>Minimize to notification area</source> +<target>é€šçŸ¥é ˜åŸŸã«æœ€å°åŒ–</target> + <source>On completion</source> <target>完了時ã®å‹•ä½œ</target> @@ -723,6 +768,15 @@ The command is triggered if: <source>&Pause</source> <target>一時åœæ¢(&P)</target> +<source>Variant</source> +<target>変化</target> + +<source>Statistics</source> +<target>統計</target> + +<source>&Don't show this dialog again</source> +<target>次回以é™ã‹ã‚‰è¡¨ç¤ºã—ãªã„(&D)</target> + <source>Select a variant</source> <target>ãƒãƒªã‚¢ãƒ³ãƒˆã‚’é¸æŠž</target> @@ -771,6 +825,12 @@ is the same <source>Configure your own synchronization rules.</source> <target>ã‚ãªãŸã®è¨å®šã—ãŸåŒæœŸè¦å‰‡ã‚’使用ã—ã¾ã™ã€‚</target> +<source>Detect moved files</source> +<target>移動済ã¿ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’検出ã™ã‚‹</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>データベースファイルãŒå¿…è¦ã§ã™(ã™ã¹ã¦ã®ã‚·ã‚¹ãƒ†ãƒ ã«ã¯æœªå¯¾å¿œ).</target> + <source>Error handling</source> <target>ãƒãƒ³ãƒ‰ãƒªãƒ³ã‚°ã®ã‚¨ãƒ©ãƒ¼æ™‚:</target> @@ -795,17 +855,17 @@ is the same <source>Delete or overwrite files permanently</source> <target>ファイルを上書ãã€ã¾ãŸã¯å®Œå…¨ã«å‰Šé™¤</target> -<source>Recycle Bin</source> -<target>ゴミ箱ã«ç§»å‹•</target> +<source>Recycle bin</source> +<target>ゴミ箱</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>ファイルã®å‰Šé™¤ã€ä¸Šæ›¸ã時ã«ã‚´ãƒŸç®±ã‚’使用ã™ã‚‹</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>ファイルを削除/上書ãã™ã‚‹æ™‚ã€ã‚´ãƒŸç®±ã«ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã‚’ã¨ã‚‹</target> <source>Versioning</source> <target>ãƒãƒ¼ã‚¸ãƒ§ãƒ³ä»˜ã‘</target> -<source>Move files to user-defined folder</source> -<target>ユーザ定義フォルダã«ãƒ•ã‚¡ã‚¤ãƒ«ã‚’移動</target> +<source>Move files to a user-defined folder</source> +<target>ユーザ定義ã®ãƒ•ã‚©ãƒ«ãƒ€ã«ãƒ•ã‚¡ã‚¤ãƒ«ã‚’移動</target> <source>Naming convention:</source> <target>命åè¦å‰‡:</target> @@ -813,8 +873,8 @@ is the same <source>Batch job</source> <target>一括処ç†</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>åŒæœŸå‡¦ç†ã‚’自動的ã«è¡Œã†ãŸã‚ã®ä¸€æ‹¬ãƒ•ã‚¡ã‚¤ãƒ«ã‚’作æˆã—ã¾ã™ã€‚ファイルをダブルクリック,ã¾ãŸã¯æ¬¡ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’タスクã‹ã‚‰å®Ÿè¡Œ:FreeFileSync.exe <ジョブå>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>無人ã§åŒæœŸã‚’è¡Œã†ç‚ºã®ãƒãƒƒãƒãƒ•ã‚¡ã‚¤ãƒ«ã‚’ä½œæˆ - ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‹ã€ã‚¿ã‚¹ã‚¯ãƒ—ランナーã‹ã‚‰ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒ«ã‚’ダブルクリックã™ã‚‹ã“ã¨ã§é–‹å§‹: %x</target> <source>Exit</source> <target>終了</target> @@ -868,12 +928,12 @@ is the same <target>片å´ã®ãƒšã‚¤ãƒ³ã®ã¿é¸æŠžã•ã‚Œã¦ã„ã‚‹å ´åˆã§ã‚‚両方を削除ã™ã‚‹</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -ã™ã¹ã¦ã®ãƒ•ã‚£ãƒ«ã‚¿ãƒ¼ã«åˆè‡´ã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã®ã¿ãŒåŒæœŸã•ã‚Œã¾ã™. -注æ„: ファイルåã¯åŸºæº–ディレクトリã«æ¯”例ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™. +ã™ã¹ã¦ã®ãƒ•ã‚£ãƒ«ã‚¿ãƒ¼è¦å‰‡ã«é©åˆã—ãŸå ´åˆã®ã¿ã€ãƒ•ã‚¡ã‚¤ãƒ«ã®åŒæœŸãŒè¡Œã‚ã‚Œã¾ã™. +注æ„: ファイルパスã¯åŸºæº–ディレクトリã‹ã‚‰ã®ç›¸å¯¾ãƒ‘スを使用ã—ã¦ãã ã•ã„. </target> <source>Include</source> @@ -903,20 +963,20 @@ Note: File names must be relative to base directories. <source>Fail-safe file copy</source> <target>安全ãªãƒ•ã‚¡ã‚¤ãƒ«ã‚³ãƒ”ーを実施</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>最åˆã«ä¸€æ™‚ファイル(*.ffs_tmp)ã«æ›¸ãè¾¼ã¿ã€ãれをリãƒãƒ¼ãƒ ã™ã‚‹ã“ã¨ã§ã€è‡´å‘½çš„ãªã‚¨ãƒ©ãƒ¼ãŒèµ·ã“ã£ãŸå ´åˆã§ã‚‚一貫性ã¯ä¿è¨¼ã•ã‚Œã¾ã™</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>リãƒãƒ¼ãƒ ã™ã‚‹å‰ã«ä¸€æ™‚ファイル(*.ffs_tmp)ã¸ã‚³ãƒ”ーã™ã‚‹ã€‚ã“ã‚Œã«ã‚ˆã‚Šã€äºˆæœŸã›ã¬ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ãŸå ´åˆã‚‚一貫性をä¿ã¤ã“ã¨ãŒå¯èƒ½ã§ã™.</target> <source>Copy locked files</source> <target>ãƒãƒƒã‚¯ã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’コピーã™ã‚‹</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>ボリュームシャドウコピーを使用ã—ã¦å…±æœ‰/ãƒãƒƒã‚¯ã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’コピーã—ã¾ã™(管ç†è€…権é™ãŒå¿…è¦)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>共有ã®ã‚³ãƒ”ーã¨ãƒ•ã‚¡ã‚¤ãƒ«ã®ãƒãƒƒã‚¯ã«ï¾Žï¾žï¾˜ï½ï½°ï¾‘ シャドウ コピーサービスを使用ã™ã‚‹ (管ç†è€…権é™ãŒå¿…è¦)</target> <source>Copy file access permissions</source> <target>ファイルã®ã‚¢ã‚¯ã‚»ã‚¹ãƒ‘ーミッションをコピーã™ã‚‹</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>ファイルã¨ãƒ•ã‚©ãƒ«ãƒ€ã®ãƒ‘ーミッションを転é€ã—ã¾ã™(管ç†è€…権é™ãŒå¿…è¦)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>ファイル転é€ã¨ãƒ•ã‚©ãƒ«ãƒ€ã®ãƒ‘ーミッション(管ç†è€…権é™ãŒå¿…è¦)</target> <source>Restore hidden dialogs</source> <target>éš ã—ãŸãƒ€ã‚¤ã‚¢ãƒã‚°ã‚’復帰</target> @@ -930,15 +990,6 @@ Note: File names must be relative to base directories. <source>&Default</source> <target>デフォルト(&D)</target> -<source>Variant</source> -<target>変化</target> - -<source>Statistics</source> -<target>統計</target> - -<source>Don't show this dialog again</source> -<target>次回ã‹ã‚‰ãƒ€ã‚¤ã‚¢ãƒã‚°ã‚’表示ã—ãªã„</target> - <source>Find what:</source> <target>検索語:</target> @@ -948,15 +999,15 @@ Note: File names must be relative to base directories. <source>&Find next</source> <target>次を検索(&F)</target> +<source>Start synchronization</source> +<target>åŒæœŸã®é–‹å§‹</target> + <source>Delete</source> <target>削除</target> <source>Configure filter</source> <target>フィルターè¨å®š</target> -<source>Start synchronization</source> -<target>åŒæœŸã®é–‹å§‹</target> - <source>Find</source> <target>検索</target> @@ -991,6 +1042,20 @@ Note: File names must be relative to base directories. <target>両方を比較</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>本当ã«åˆè¨ˆ %x ã“ã®é …ç›®ã«å¯¾ã—ã¦ã‚³ãƒžãƒ³ãƒ‰ %y を実行ã—ã¾ã™ã‹?</pluralform> +</target> + +<source>Confirm</source> +<target>確èª</target> + +<source>&Execute</source> +<target>実行(&E)</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1003,7 +1068,7 @@ Note: File names must be relative to base directories. <pluralform>%x files</pluralform> </source> <target> -<pluralform>%x ファイル</pluralform> +<pluralform>%x 個ã®ãƒ•ã‚¡ã‚¤ãƒ«</pluralform> </target> <source> @@ -1011,24 +1076,27 @@ Note: File names must be relative to base directories. <pluralform>%y of %x rows in view</pluralform> </source> <target> -<pluralform>%y ã® %x è¡Œ(表示内)</pluralform> +<pluralform>%y / %x è¡Œ(表示内)</pluralform> </target> <source>Set direction:</source> <target>æ–¹å‘ã®è¨å®š:</target> <source>Exclude temporarily</source> -<target>一時フォルダを除外</target> +<target>一時的ã«é™¤å¤–</target> <source>Include temporarily</source> -<target>一時フォルダをå«ã‚ã‚‹</target> - -<source>Exclude via filter:</source> -<target>フィルターを通ã—ã¦é™¤å¤–</target> +<target>一時的ã«å«ã‚ã‚‹</target> <source>multiple selection</source> <target>複数é¸æŠž</target> +<source>Include via filter:</source> +<target>フィルター経由ã§å«ã‚ã‚‹:</target> + +<source>Exclude via filter:</source> +<target>フィルターを経由ã—ã¦é™¤å¤–</target> + <source>Include all</source> <target>ã™ã¹ã¦å«ã‚ã‚‹</target> @@ -1074,8 +1142,8 @@ Note: File names must be relative to base directories. <source>Do&n't save</source> <target>ä¿å˜ã—ãªã„(&N)</target> -<source>Never save changes</source> -<target>変更をä¿å˜ã—ãªã„</target> +<source>Never save &changes</source> +<target>変更ã®ä¿å˜ã‚’ã—ãªã„(&C)</target> <source>Show files that exist on left side only</source> <target>å·¦å´ã®ã¿ã«å˜åœ¨ã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã‚’表示</target> @@ -1128,8 +1196,8 @@ Note: File names must be relative to base directories. <source>All folders are in sync</source> <target>ã™ã¹ã¦ã®ãƒ•ã‚©ãƒ«ãƒ€ã‚’åŒæœŸ</target> -<source>Comma separated list</source> -<target>カンマ区切り</target> +<source>Comma-separated values</source> +<target>カンマ区切りã®å€¤</target> <source>File list exported</source> <target>ファイル一覧ã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆãŒå®Œäº†</target> @@ -1137,8 +1205,8 @@ Note: File names must be relative to base directories. <source>Searching for program updates...</source> <target>アップデートを検索ã—ã¦ã„ã¾ã™...</target> -<source>Ignore further errors</source> -<target>以é™ã®ã‚¨ãƒ©ãƒ¼ã‚’無視</target> +<source>&Ignore subsequent errors</source> +<target>以é™ã®ã‚¨ãƒ©ãƒ¼ã¯ç„¡è¦–ã™ã‚‹(&I)</target> <source>&Ignore</source> <target>無視(&I)</target> @@ -1146,8 +1214,8 @@ Note: File names must be relative to base directories. <source>Fatal Error</source> <target>致命的ãªã‚¨ãƒ©ãƒ¼</target> -<source>Don't show this warning again</source> -<target>次回ã‹ã‚‰ã“ã®è¦å‘Šã¯è¡¨ç¤ºã—ãªã„</target> +<source>&Don't show this warning again</source> +<target>次回ã‹ã‚‰ã“ã®è¦å‘Šã‚’表示ã—ãªã„(&D)</target> <source>&Switch</source> <target>切り替ãˆ(&S)</target> @@ -1180,15 +1248,12 @@ Note: File names must be relative to base directories. <target>ä¸æ–</target> <source>Completed</source> -<target>完了ã—ã¾ã—ãŸ</target> +<target>完了ã—ã¾ã—ãŸ!</target> -<source>Continue</source> -<target>続行</target> +<source>&Continue</source> +<target>続行(&C)</target> -<source>Pause</source> -<target>一時åœæ¢</target> - -<source>Logging</source> +<source>Log</source> <target>ãƒã‚°</target> <source>Cannot find %x</source> @@ -1225,11 +1290,11 @@ Note: File names must be relative to base directories. <target>フィルター</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>本当ã«ä»¥ä¸‹ã® %x 個ã®é …目をゴミ箱ã«ç§»å‹•ã—ã¾ã™ã‹</pluralform> +<pluralform>本当ã«ä»¥ä¸‹ %x 個ã®é …目をゴミ箱ã«ç§»å‹•ã—ã¾ã™ã‹?</pluralform> </target> <source> @@ -1282,9 +1347,6 @@ Note: File names must be relative to base directories. <source>Append a timestamp to each file name</source> <target>å„ファイルåã«ã‚¿ã‚¤ãƒ ã‚¹ã‚¿ãƒ³ãƒ—ã‚’è¿½åŠ </target> -<source>Folder</source> -<target>フォルダ</target> - <source>File</source> <target>ファイル</target> @@ -1402,7 +1464,7 @@ Note: File names must be relative to base directories. <source>Cannot change process I/O priorities.</source> <target>プãƒã‚»ã‚¹ã® I/O 優先度を変更ã§ãã¾ã›ã‚“</target> -<source>Unable to move %x to the Recycle Bin.</source> +<source>Unable to move %x to the recycle bin.</source> <target>%x をゴミ箱ã«ç§»å‹•ã§ãã¾ã›ã‚“.</target> <source>Cannot determine final path for %x.</source> diff --git a/BUILD/Languages/korean.lng b/BUILD/Languages/korean.lng index d25b490b..01ec80b0 100644 --- a/BUILD/Languages/korean.lng +++ b/BUILD/Languages/korean.lng @@ -11,7 +11,7 @@ <target>마지막 ë™ê¸°í™” ìž‘ì—… ì´í›„, 양측 ëª¨ë‘ ë³€ê²½ ë˜ì—ˆìŠµë‹ˆë‹¤.</target> <source>Cannot determine sync-direction:</source> -<target>ë™ê¸°í™” ë°©í–¥ì„ ê²°ì •í• ìˆ˜ 없습니다 :</target> +<target>ë™ê¸°í™” ë°©í–¥ì„ ê²°ì •í• ìˆ˜ 없습니다:</target> <source>No change since last synchronization.</source> <target>마지막 ë™ê¸°í™” ì´í›„ ë³€ê²½ì‚¬í• ì—†ìŒ.</target> @@ -20,18 +20,18 @@ <target>ë°ì´í„°ë² ì´ìŠ¤ í•ëª©ì´ 현재 ì„¤ì •ì„ ê³ ë ¤í•˜ì—¬ ë™ê¸°í™” ë˜ì§€ 않았습니다.</target> <source>Setting default synchronization directions: Old files will be overwritten with newer files.</source> -<target>기본값 ë™ê¸°í™” ë°©í–¥ ì„¤ì • : ì´ì „ 파ì¼ë“¤ì€ 보다 ìµœì‹ íŒŒì¼ë“¤ë¡œ ë®ì–´ 쓰여집니다.</target> +<target>기본값 ë™ê¸°í™” ë°©í–¥ ì„¤ì •: ì´ì „ 파ì¼ë“¤ì€ 보다 ìµœì‹ íŒŒì¼ë“¤ë¡œ ë®ì–´ 쓰여집니다.</target> <source>Checking recycle bin availability for folder %x...</source> -<target>í´ë” %x ì„(를) 위한 휴지통 가용성 여부 í™•ì¸ ì¤‘...</target> +<target>í´ë” %xì„(를) 위한 휴지통 가용성 여부 í™•ì¸ ì¤‘...</target> -<source>Moving file %x to recycle bin</source> +<source>Moving file %x to the recycle bin</source> <target>íŒŒì¼ %xì„(를) 휴지통으로 ì´ë™ 중</target> -<source>Moving folder %x to recycle bin</source> +<source>Moving folder %x to the recycle bin</source> <target>í´ë” %xì„(를) 휴지통으로 ì´ë™ 중</target> -<source>Moving symbolic link %x to recycle bin</source> +<source>Moving symbolic link %x to the recycle bin</source> <target>ì‹¬ë³¼ë¦ ë§í¬ %xì„(를) 휴지통으로 ì´ë™ 중</target> <source>Deleting file %x</source> @@ -43,14 +43,20 @@ <source>Deleting symbolic link %x</source> <target>ì‹¬ë³¼ë¦ ë§í¬ %x ì‚ì œ 중</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>ë‹¤ìŒ í´ë”ë“¤ì„ ìœ„í•´ íœ´ì§€í†µì„ ì‚¬ìš©í• ìˆ˜ 없어 ëŒ€ì‹ íŒŒì¼ë“¤ì„ ì˜êµ¬ ì‚ì œí•©ë‹ˆë‹¤ :</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>ë‹¤ìŒ í´ë”ë“¤ì„ ìœ„í•´ íœ´ì§€í†µì„ ì‚¬ìš©í• ìˆ˜ 없습니다. ëŒ€ì‹ íŒŒì¼ë“¤ì„ ì˜êµ¬ ì‚ì œí•©ë‹ˆë‹¤:</target> <source>An exception occurred</source> <target>예외 ë°œìƒ</target> -<source>Cannot find file %x.</source> -<target>íŒŒì¼ %x ì„(를) ì°¾ì„ ìˆ˜ 없습니다.</target> +<source>A directory path is expected after %x.</source> +<target>%x ì´í›„ ì¼ë°˜ì 으로 ë””ë ‰í† ë¦¬ 경로가 하나 나옵니다.</target> + +<source>Syntax error</source> +<target>구문 오류</target> + +<source>Cannot open file %x.</source> +<target>íŒŒì¼ %xì„(를) ì—´ 수 없습니다.</target> <source>Error</source> <target>오류</target> @@ -58,6 +64,36 @@ <source>File %x does not contain a valid configuration.</source> <target>íŒŒì¼ %x ì˜ êµ¬ì„±ì´ ìœ íš¨í•˜ì§€ 않습니다.</target> +<source>Unequal number of left and right directories specified.</source> +<target>ì§€ì •ëœ ì¢Œì¸¡ ë° ìš°ì¸¡ ë””ë ‰í„°ë¦¬ 개수가 같지 ì•ŠìŒ.</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>ëª…ë ¹ì¤„ì„ í†µí•´ ì„¤ì •ëœ ë””ë ‰í† ë¦¬ì˜ ê²½ìš°, ì„¤ì • 파ì¼ì€ ë””ë ‰í† ë¦¬ 페어 ìƒì˜ ì„¤ì •ì„ í¬í•¨í• 수 없습니다.</target> + +<source>Warning</source> +<target>ê²½ê³ </target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target>ë””ë ‰í† ë¦¬ëŠ” 하나 ì´ìƒì˜ ì„¤ì • 파ì¼ì„ 위해 ì„¤ì •ë 수 없습니다.</target> + +<source>Syntax:</source> +<target>구문(Syntax):</target> + +<source>config files</source> +<target>ì„¤ì • 파ì¼</target> + +<source>directory</source> +<target>ë””ë ‰í† ë¦¬</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>FreeFileSync .ffs_gui ë˜ëŠ” .ffs_batch ì„¤ì •íŒŒì¼ ê°œìˆ˜</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>최대 한개 ì„¤ì •íŒŒì¼ì— 대한 대체 ë””ë ‰í† ë¦¬ 개수</target> + +<source>Command line</source> +<target>ëª…ë ¹ì¤„(커맨드ë¼ì¸)</target> + <source>A folder input field is empty.</source> <target>í´ë” ìž…ë ¥ í•„ë“œ 하나가 비어 있습니다.</target> @@ -65,25 +101,25 @@ <target>해당 í´ë”를 비어 있는 ìƒíƒœë¡œ 간주합니다.</target> <source>Cannot find the following folders:</source> -<target>ë‹¤ìŒ í´ë”를 ì°¾ì„ ìˆ˜ 없습니다 :</target> +<target>ë‹¤ìŒ í´ë”를 ì°¾ì„ ìˆ˜ 없습니다:</target> <source>You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.</source> <target>ê° í´ë”를 비어있는 ìƒíƒœë¡œ ê°„ì£¼í• ê²½ìš° ì´ ì˜¤ë¥˜ëŠ” 무시ë 수 있습니다. í´ë”ë“¤ì€ ë™ê¸°í™”ê°€ 진행ë˜ëŠ” ë™ì•ˆ ìžë™ ìƒì„±ë©ë‹ˆë‹¤.</target> <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> -<target>ë‹¤ìŒ í´ë”들ì—는 ì¢…ì† ê²½ë¡œê°€ 있습니다. ë™ê¸°í™” ê·œì¹™ì„ ì„¤ì • ì‹œ 주ì˜í•˜ì‹œê¸° ë°”ëžë‹ˆë‹¤ :</target> +<target>ë‹¤ìŒ í´ë”들ì—는 ì¢…ì† ê²½ë¡œê°€ 있습니다. ë™ê¸°í™” ê·œì¹™ì„ ì„¤ì • ì‹œ 주ì˜í•˜ì‹œê¸° ë°”ëžë‹ˆë‹¤:</target> <source>File %x has an invalid date.</source> <target>íŒŒì¼ %x ì˜ ë‚ ì§œê°€ ìœ íš¨í•˜ì§€ 않습니다.</target> <source>Date:</source> -<target>ë‚ ì§œ :</target> +<target>ë‚ ì§œ:</target> <source>Files %x have the same date but a different size.</source> <target>íŒŒì¼ %x ì˜ ë‚ ì§œëŠ” 같으나, í¬ê¸°ê°€ 다릅니다.</target> <source>Size:</source> -<target>í¬ê¸° :</target> +<target>í¬ê¸°:</target> <source>Items differ in attributes only</source> <target>í•ëª©ë“¤ì´ ì†ì„±ì—서만 ì°¨ì´ê°€ 있습니다.</target> @@ -164,19 +200,19 @@ <target>ë°ì´í„°ë² ì´ìŠ¤ íŒŒì¼ %x ì€(는) 호환 불가능합니다.</target> <source>Initial synchronization:</source> -<target>초기 ë™ê¸°í™” :</target> +<target>초기 ë™ê¸°í™”:</target> <source>Database file %x does not yet exist.</source> <target>ë°ì´í„°ë² ì´ìŠ¤ íŒŒì¼ %x ì€(는) ì•„ì§ ì¡´ìž¬í•˜ì§€ 않습니다.</target> <source>Database file is corrupt:</source> -<target>ë°ì´í„°ë² ì´ìŠ¤ íŒŒì¼ ì†ìƒ :</target> +<target>ë°ì´í„°ë² ì´ìŠ¤ íŒŒì¼ ì†ìƒ:</target> <source>Cannot write file %x.</source> -<target>íŒŒì¼ %x ì„(를) 쓸 수 없습니다.</target> +<target>íŒŒì¼ %xì„(를) 쓸 수 없습니다.</target> <source>Cannot read file %x.</source> -<target>íŒŒì¼ %x ì„(를) ì½ì„ 수 없습니다.</target> +<target>íŒŒì¼ %xì„(를) ì½ì„ 수 없습니다.</target> <source>Database files do not share a common session.</source> <target>ë°ì´í„°ë² ì´ìŠ¤ 파ì¼ì´ ì¼ë°˜/ê³µë™ ì„¸ì…˜ì„ ê³µìœ í•˜ì§€ 않습니다.</target> @@ -205,17 +241,17 @@ <target>íŒŒì¼ %x ìƒì„± 중</target> <source>Items processed:</source> -<target>ì²˜ë¦¬ëœ í•ëª© :</target> +<target>ì²˜ë¦¬ëœ í•ëª©:</target> <source>Items remaining:</source> -<target>ë‚¨ì€ í•ëª© :</target> +<target>ë‚¨ì€ í•ëª©:</target> <source>Total time:</source> -<target>ì „ì²´ 시간 :</target> +<target>ì „ì²´ 시간:</target> <source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </source> <target> <pluralform>%x ë°”ì´íŠ¸</pluralform> @@ -237,24 +273,27 @@ <target>%x ì— ëŒ€í•œ ë””ë ‰í† ë¦¬ ìž ê¸ˆì„ ì„¤ì •í• ìˆ˜ 없습니다.</target> <source>Scanning:</source> -<target>스캔 :</target> +<target>스캔 중:</target> <source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </source> <target> -<pluralform>[%x ìŠ¤ë ˆë“œ]</pluralform> +<pluralform>%x ìŠ¤ë ˆë“œ</pluralform> </target> <source>Encoding extended time information: %x</source> -<target>ì¸ì½”딩 확장 시간 ì •ë³´ : %x</target> +<target>ì¸ì½”딩 확장 시간 ì •ë³´: %x</target> <source>/sec</source> <target>/ì´ˆ</target> +<source>%x items</source> +<target>%x í•ëª©</target> + <source>Configuration file %x loaded partially only.</source> -<target>구성 íŒŒì¼ %x ì´(ê°€) 부분ì 으로만 로드 ë˜ì—ˆìŒ.</target> +<target>구성 íŒŒì¼ %xì´(ê°€) 부분ì 으로만 로드 ë˜ì—ˆìŒ.</target> <source>Show in Explorer</source> <target>íƒìƒ‰ê¸°ì— 표시</target> @@ -265,29 +304,29 @@ <source>Browse directory</source> <target>ë””ë ‰í† ë¦¬ 찾아보기</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Volume Shadow Copy Service ì ‘ê·¼ 불가</target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target>Volume Shadow Copy Serviceì— ì ‘ê·¼í• ìˆ˜ 없습니다.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>본 ìš´ì˜ì²´ì œì—ì„œì˜ Shadow Copy ìƒì„±ì€ FreeFileSync 64-비트 ë²„ì „ì„ ì‚¬ìš©í•˜ì„¸ìš”.</target> <source>Cannot load file %x.</source> -<target>íŒŒì¼ %x ì„(를) ë¡œë“œí• ìˆ˜ 없습니다.</target> +<target>íŒŒì¼ %xì„(를) ë¡œë“œí• ìˆ˜ 없습니다.</target> <source>Cannot determine volume name for %x.</source> <target>%x ì— ëŒ€í•œ 볼륨 ì´ë¦„ì„ ê²°ì •í• ìˆ˜ 없습니다.</target> -<source>Volume name %x not part of file name %y.</source> -<target>볼륨 ì´ë¦„ %x ì€(는) íŒŒì¼ ì´ë¦„ %y ì˜ ì¼ë¶€ê°€ 아님.</target> +<source>Volume name %x is not part of file path %y.</source> +<target>볼륨 ì´ë¦„ %xì€(는) íŒŒì¼ ê²½ë¡œ %yì˜ ì¼ë¶€ê°€ 아닙니다.</target> <source>Abort requested: Waiting for current operation to finish...</source> -<target>사용ìžì— ì˜í•œ ìž‘ì—… 중단 : 현재 ìž‘ì—… 종료 대기 중...</target> +<target>사용ìžì— ì˜í•œ ìž‘ì—… 중단: 현재 ìž‘ì—… 종료 대기 중...</target> <source>Failure to create timestamp for versioning:</source> -<target>ë²„ì €ë‹ì„ 위한 타임 스탬프 ìƒì„± 실패 :</target> +<target>ë²„ì €ë‹ì„ 위한 타임 스탬프 ìƒì„± 실패:</target> <source>Cannot read the following XML elements:</source> -<target>ë‹¤ìŒ XML 요소를 ì½ì„ 수 없습니다 :</target> +<target>ë‹¤ìŒ XML 요소를 ì½ì„ 수 없습니다:</target> <source>&Open...</source> <target>열기(&O)</target> @@ -311,7 +350,7 @@ <target>ë„움ë§(&H)</target> <source>Usage:</source> -<target>사용 :</target> +<target>사용:</target> <source>1. Select folders to watch.</source> <target>1. ì—´ì–´ ë³¼ í´ë”를 ì„ íƒí•˜ì„¸ìš”.</target> @@ -346,18 +385,15 @@ <source>Idle time between last detected change and execution of command</source> <target>마지막으로 ê°ì§€ëœ 변화와 ëª…ë ¹ 실행 ê°„ì˜ ìœ íœ´ 시간</target> -<source>Command line</source> -<target>ëª…ë ¹ì¤„(커맨드ë¼ì¸)</target> - <source> The command is triggered if: - files or subfolders change - new folders arrive (e.g. USB stick insert) </source> <target> -ëª…ë ¹ì€ ë‹¤ìŒê³¼ ê°™ì€ ê²½ìš°ì— ì‹¤í–‰ë©ë‹ˆë‹¤ : +ëª…ë ¹ì€ ë‹¤ìŒê³¼ ê°™ì€ ê²½ìš°ì— ì‹¤í–‰ë©ë‹ˆë‹¤: - 파ì¼ì´ë‚˜ 하위 í´ë” 변경 ì‹œ -- 새 í´ë”ê°€ ìƒê²¼ì„ ì‹œ (예 : USB 스틱 삽입) +- 새 í´ë”ê°€ ìƒê²¼ì„ ì‹œ (예: USB 스틱 삽입) </target> <source>Start</source> @@ -372,9 +408,6 @@ The command is triggered if: <source>RealtimeSync - Automated Synchronization</source> <target>실시간 ë™ê¸°í™” - ìžë™ ë™ê¸°í™”</target> -<source>Warning</source> -<target>ê²½ê³ </target> - <source>Build: %x</source> <target>빌드: %x</target> @@ -384,17 +417,23 @@ The command is triggered if: <source>All files</source> <target>ëª¨ë“ íŒŒì¼</target> +<source>Directory monitoring active</source> +<target>ë””ë ‰í† ë¦¬ ëª¨ë‹ˆí„°ë§ í™œì„±í™”</target> + +<source>Waiting until all directories are available...</source> +<target>ëª¨ë“ ë””ë ‰í† ë¦¬ê°€ 사용 ê°€ëŠ¥í• ë•Œê¹Œì§€ 대기 중...</target> + <source>&Restore</source> <target>ë³µì›(&R)</target> +<source>&Show error</source> +<target>오류 표시(&S)</target> + <source>&Exit</source> <target>나가기(&E)</target> -<source>Waiting for missing directories...</source> -<target>ëˆ„ë½ ë””ë ‰í† ë¦¬ 대기 중...</target> - <source>Invalid command line:</source> -<target>ìž˜ëª»ëœ ëª…ë ¹ì¤„ :</target> +<target>ìž˜ëª»ëœ ëª…ë ¹ì¤„:</target> <source>File content</source> <target>íŒŒì¼ ë‚´ìš©</target> @@ -402,14 +441,14 @@ The command is triggered if: <source>File time and size</source> <target>íŒŒì¼ ì‹œê°„ ë° í¬ê¸°</target> -<source> Two way </source> -<target> ì–‘ë°©/ì–‘ë©´ (Two Way) </target> +<source>Two way</source> +<target>ì–‘ë°©/ì–‘ë©´ (Two Way)</target> <source>Mirror</source> -<target>미러 </target> +<target>미러</target> <source>Update</source> -<target>ì—…ë°ì´íŠ¸ </target> +<target>ì—…ë°ì´íŠ¸</target> <source>Custom</source> <target>ê°œì¸ ì„¤ì •</target> @@ -463,22 +502,19 @@ The command is triggered if: <target>소스 í´ë” %xì„(를) ì°¾ì„ ìˆ˜ ì—†ìŒ.</target> <source>The following items have unresolved conflicts and will not be synchronized:</source> -<target>ì•„ëž˜ì˜ í•ëª©ë“¤ì€ 해결치 못 í•œ 충ëŒë¡œ ì¸í•´ ë™ê¸°í™”í• ìˆ˜ 없습니다 :</target> +<target>ì•„ëž˜ì˜ í•ëª©ë“¤ì€ 해결치 못 í•œ 충ëŒë¡œ ì¸í•´ ë™ê¸°í™”í• ìˆ˜ 없습니다:</target> -<source>Significant difference detected:</source> -<target>ìƒë‹¹í•œ ì°¨ì´ê°€ ê°ì§€ë습니다 :</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>ì´ íŒŒì¼ ê°œìˆ˜ì˜ 50% ì´ìƒì´ 복사ë˜ê±°ë‚˜ ì‚ì œ ë©ë‹ˆë‹¤.</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>ë‹¤ìŒ í´ë”ë“¤ì˜ ì°¨ì´ê°€ ìƒë‹¹í•©ë‹ˆë‹¤. ë™ê¸°í™”를 위해 올바른 í´ë”ë“¤ì´ ë§¤ì¹˜ë˜ì—ˆëŠ”지 확ì¸í•´ ë³´ì‹ì‹œì˜¤.</target> <source>Not enough free disk space available in:</source> -<target>사용 가능한 ë””ìŠ¤í¬ ì—¬ìœ ê³µê°„ì´ ë¶€ì¡±í•©ë‹ˆë‹¤ :</target> +<target>사용 가능한 ë””ìŠ¤í¬ ì—¬ìœ ê³µê°„ì´ ë¶€ì¡±í•©ë‹ˆë‹¤:</target> <source>Required:</source> -<target>í•„ìš” 공간(í¬ê¸°) :</target> +<target>í•„ìš” 공간(í¬ê¸°):</target> <source>Available:</source> -<target>ì—¬ìœ ê³µê°„(í¬ê¸°) :</target> +<target>ì—¬ìœ ê³µê°„(í¬ê¸°):</target> <source>A folder will be modified which is part of multiple folder pairs. Please review synchronization settings.</source> <target>다중 í´ë” íŽ˜ì–´ì˜ ì¼ë¶€ì¸ í´ë”ê°€ 변경ë©ë‹ˆë‹¤. ë™ê¸°í™” ì„¤ì •ì„ ìž¬ê²€í† í•˜ì„¸ìš”.</target> @@ -489,11 +525,14 @@ The command is triggered if: <source>Generating database...</source> <target>ë°ì´í„°ë² ì´ìŠ¤ ìƒì„± 중...</target> -<source>Creating Volume Shadow Copy for %x...</source> +<source>Creating a Volume Shadow Copy for %x...</source> <target>%xì„(를) 위한 Volume Shadow Copy ìƒì„± 중...</target> <source>Data verification error: %x and %y have different content.</source> -<target>ë°ì´í„° í™•ì¸ ì˜¤ë¥˜ : %x ë° %y ì˜ ë‚´ìš©ì´ ì„œë¡œ 다릅니다.</target> +<target>ë°ì´í„° í™•ì¸ ì˜¤ë¥˜: %x ë° %y ì˜ ë‚´ìš©ì´ ì„œë¡œ 다릅니다.</target> + +<source>job name</source> +<target>ìž‘ì—… ì´ë¦„</target> <source>Synchronization aborted</source> <target>ë™ê¸°í™” 중단</target> @@ -514,13 +553,16 @@ The command is triggered if: <target>로그 íŒŒì¼ %x ì €ìž¥ 중...</target> <source>Press "Switch" to resolve issues in FreeFileSync main dialog.</source> -<target>FreeFileSync ë©”ì¸ ë‹¤ì´ì–¼ë¡œê·¸ì—ì„œ ë¬¸ì œ í•´ê²°ì„ í•˜ë ¤ë©´ "Switch" [ì „í™˜]ì„ ëˆ„ë¥´ì‹ì‹œì˜¤.</target> +<target>FreeFileSync 기본 대화 ì°½ì—ì„œ ë¬¸ì œ í•´ê²°ì„ í•˜ë ¤ë©´ "Switch" [ì „í™˜]ì„ ëˆ„ë¥´ì‹ì‹œì˜¤.</target> <source>Switching to FreeFileSync main dialog</source> <target>FreeFileSync 기본 대화 창으로 ì „í™˜</target> +<source>Retrying operation after error:</source> +<target>오류 ë°œìƒ í›„, ìž‘ì—… ìž¬ì‹œë„ ì¤‘:</target> + <source>A new version of FreeFileSync is available:</source> -<target>새로운 ë²„ì „ì˜ FreeFileSyncê°€ 나왔습니다 :</target> +<target>새로운 ë²„ì „ì˜ FreeFileSyncê°€ 나왔습니다:</target> <source>Download now?</source> <target>지금 다운로드 í•˜ì‹œê² ìŠµë‹ˆê¹Œ?</target> @@ -580,7 +622,7 @@ The command is triggered if: <target>드래그 앤 ë“œëž(&&) [마우스로 íŒŒì¼ ëŒì–´ë‹¤ 놓기]</target> <source>Close progress dialog</source> -<target>í”„ë¡œê·¸ë ˆìŠ¤ 다ì´ì–¼ë¡œê·¸ (진행 표시 ì°½) 닫기</target> +<target>진행 표시 ì°½ 닫기</target> <source>Standby</source> <target>대기</target> @@ -642,7 +684,7 @@ The command is triggered if: <source>&Export file list...</source> <target>íŒŒì¼ ë¦¬ìŠ¤íŠ¸ 내보내기(&E)</target> -<source>&Global settings...</source> +<source>&Global settings</source> <target>ì „ì²´ ì„¤ì •(&G)</target> <source>&Tools</source> @@ -700,20 +742,23 @@ The command is triggered if: <target>ë³µì‚¬í• ì „ì²´ ë°”ì´íŠ¸ í¬ê¸°</target> <source>Items found:</source> -<target>ë°œê²¬ëœ í•ëª© :</target> +<target>ë°œê²¬ëœ í•ëª©:</target> <source>Speed:</source> -<target>ì†ë„ :</target> +<target>ì†ë„:</target> <source>Time remaining:</source> -<target>ë‚¨ì€ ì‹œê°„ :</target> +<target>ë‚¨ì€ ì‹œê°„:</target> <source>Time elapsed:</source> -<target>경과 시간 :</target> +<target>경과 시간:</target> <source>Synchronizing...</source> <target>ë™ê¸°í™” ìž‘ì—… 중...</target> +<source>Minimize to notification area</source> +<target>알림 ì˜ì—으로 최소화</target> + <source>On completion</source> <target>완료 ì‹œ</target> @@ -723,6 +768,15 @@ The command is triggered if: <source>&Pause</source> <target>ì¼ì‹œì •ì§€(&P)</target> +<source>Variant</source> +<target>ë² ì–´ë¦¬ì–¸íŠ¸</target> + +<source>Statistics</source> +<target>통계</target> + +<source>&Don't show this dialog again</source> +<target>ì´ ëŒ€í™” ì°½ì„ ë‹¤ì‹œ 표시 안 함 (&D)</target> + <source>Select a variant</source> <target>ë² ì–´ë¦¬ì–¸íŠ¸ ì„ íƒ</target> @@ -771,8 +825,14 @@ is the same <source>Configure your own synchronization rules.</source> <target>ê°œì¸ ë™ê¸°í™” 규칙 ì„¤ì •</target> +<source>Detect moved files</source> +<target>ì´ë™ íŒŒì¼ íƒì§€</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>ë°ì´í„°ë² ì´ìŠ¤ 파ì¼ì´ 필요합니다. ëª¨ë“ íŒŒì¼ ì‹œìŠ¤í…œì—ì„œ 지ì›ë˜ì§€ëŠ” 않습니다.</target> + <source>Error handling</source> -<target>오류 ë°œìƒì‹œ :</target> +<target>오류 ë°œìƒì‹œ:</target> <source>Ignore</source> <target>무시</target> @@ -795,26 +855,26 @@ is the same <source>Delete or overwrite files permanently</source> <target>íŒŒì¼ ì˜êµ¬ ì‚ì œ ë˜ëŠ” ë®ì–´ì“°ê¸°</target> -<source>Recycle Bin</source> +<source>Recycle bin</source> <target>휴지통</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>ì‚ì œ ë˜ëŠ” ë®ì–´ ì¨ì§„ 파ì¼ë“¤ì€ 휴지통으로 ì´ë™</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>íœ´ì§€í†µì— ì‚ì œë˜ê³ ë®ì–´ 씌어진 íŒŒì¼ ë°±ì—…</target> <source>Versioning</source> <target>ë²„ì €ë‹</target> -<source>Move files to user-defined folder</source> +<source>Move files to a user-defined folder</source> <target>ì‚¬ìš©ìž ì •ì˜ í´ë”ë¡œ íŒŒì¼ ì´ë™</target> <source>Naming convention:</source> -<target>ì´ë¦„ ì§€ì • :</target> +<target>ì´ë¦„ ì§€ì •:</target> <source>Batch job</source> <target>ì¼ê´„ ìž‘ì—…</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>ìžë™ ë™ê¸°í™”를 위한 ì¼ê´„ 파ì¼ì„ 만ë“니다. 본 파ì¼ì„ ë”블 í´ë¦í•˜ê±°ë‚˜ 시스템 íƒœìŠ¤í¬ í”Œëž˜ë„ˆì— ë‹¤ìŒê³¼ ê°™ì´ ì˜ˆì•½í•˜ì„¸ìš” : FreeFileSync.exe <job name>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>ì§ì ‘ 지켜보지 않는 ìžë™ ë™ê¸°í™”ì˜ ê²½ìš°, 배치 파ì¼ì„ 만ë“니다. ì‹œìž‘í•˜ë ¤ë©´ 파ì¼ì„ ë”블 í´ë¦í•˜ê±°ë‚˜ ìž‘ì—… 플래너ì—ì„œ ì¼ì •ì„ 만ë“니다: %x</target> <source>Exit</source> <target>종료</target> @@ -823,7 +883,7 @@ is the same <target>첫 번째 오류 ì‹œ ë™ê¸°í™” 중지</target> <source>Show progress dialog</source> -<target>í”„ë¡œê·¸ë ˆìŠ¤ 다ì´ì–¼ë¡œê·¸ (진행 표시 ì°½) 보기</target> +<target>진행 표시 ì°½ 보기</target> <source>Save log</source> <target>로그 ì €ìž¥</target> @@ -838,7 +898,7 @@ is the same <target>로그 파ì¼ì˜ 최대 개수 ì œí•œ</target> <source>Source code written in C++ using:</source> -<target>소스코드는 C++ 언어로 아래 íˆ´ì„ ì‚¬ìš©í•˜ì—¬ 작성ë˜ì—ˆìŠµë‹ˆë‹¤ :</target> +<target>소스코드는 C++ 언어로 아래 íˆ´ì„ ì‚¬ìš©í•˜ì—¬ 작성ë˜ì—ˆìŠµë‹ˆë‹¤:</target> <source>If you like FreeFileSync</source> <target>FreeFileSync를 위한 기부</target> @@ -868,12 +928,12 @@ is the same <target>ì–´ëŠ í•œìª½ì˜ íŒŒì¼ë§Œ ì„ íƒí•˜ë”ë¼ë„ 양측 ëª¨ë‘ ì‚ì œ</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -ëª¨ë“ í•„í„° ì„¤ì •ê³¼ ì¼ì¹˜í•˜ëŠ” 파ì¼ë§Œ ë™ê¸°í™” ë©ë‹ˆë‹¤. -ì°¸ê³ : íŒŒì¼ ì´ë¦„ì€ ê¸°ë³¸ ë””ë ‰í† ë¦¬ì™€ ìƒì‘해야 합니다. +ëª¨ë“ í•„í„° ê·œì¹™ì— ì¤€í• ê²½ìš°ì—만 파ì¼ì„ ë™ê¸°í™” 시킵니다. +ì°¸ê³ : íŒŒì¼ ê²½ë¡œê°€ 기본 ë””ë ‰í† ë¦¬ì— ì—°ê²°ë¼ ìžˆì–´ì•¼ 합니다. </target> <source>Include</source> @@ -903,20 +963,20 @@ Note: File names must be relative to base directories. <source>Fail-safe file copy</source> <target>실패 - ì•ˆì „ íŒŒì¼ ë³µì‚¬</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>ìž„ì‹œ íŒŒì¼ (*.ffs_tmp)ë¡œ ìš°ì„ ìž‘ì„± 후, 파ì¼ëª…ì„ ë³€ê²½í•©ë‹ˆë‹¤. ì´ë ‡ê²Œ í• ê²½ìš° 치명ì ì¸ ì˜¤ë¥˜ê°€ ë°œìƒí•˜ë”ë¼ë„ ì¼ê´€ëœ ìƒíƒœë¥¼ ë³´ìž¥í• ìˆ˜ 있습니다.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>ì¼ë‹¨ 임시파ì¼(*.ffs_tmp)ë¡œ 복사한 후 ì´ë¦„ 바꾸기. ì´ ê°™ì´ í•¨ìœ¼ë¡œì¨ ì¹˜ëª…ì ì¸ ì˜¤ë¥˜ ë°œìƒì‹œì—ë„ ì¼ê´€ëœ ìƒíƒœ ìœ ì§€ë¥¼ 보장합니다.</target> <source>Copy locked files</source> <target>ë½ ê±¸ë¦° íŒŒì¼ ë³µì‚¬</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Volume Shadow Copy Service를 사용하여 ê³µìœ ë˜ëŠ” ë½ ê±¸ë¦° 파ì¼ì„ 복사 (ê´€ë¦¬ìž ê¶Œí•œ í•„ìš”)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>Volume Shadow Copy Service를 사용하여 ê³µìœ ë˜ëŠ” ìž ê¸´ íŒŒì¼ ë³µì‚¬ (ê´€ë¦¬ìž ê¶Œí•œ í•„ìš”)</target> <source>Copy file access permissions</source> <target>íŒŒì¼ ì ‘ê·¼ 권한 복사</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>íŒŒì¼ ë° í´ë” 사용 권한 ì „ì†¡ (ê´€ë¦¬ìž ê¶Œí•œ í•„ìš”)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>íŒŒì¼ ë° í´ë” 권한 ì „ì†¡ (ê´€ë¦¬ìž ê¶Œí•œ í•„ìš”)</target> <source>Restore hidden dialogs</source> <target>숨겨진 대화 ì°½ ë³µì›</target> @@ -930,17 +990,8 @@ Note: File names must be relative to base directories. <source>&Default</source> <target>기본 ì„¤ì •/ê°’(&D)</target> -<source>Variant</source> -<target>ë² ì–´ë¦¬ì–¸íŠ¸</target> - -<source>Statistics</source> -<target>통계</target> - -<source>Don't show this dialog again</source> -<target>ì´ ëŒ€í™” ì°½ì„ ë‹¤ì‹œ 표시하지 ì•ŠìŒ</target> - <source>Find what:</source> -<target>검색어 :</target> +<target>검색어:</target> <source>Match case</source> <target>대문ìž/ì†Œë¬¸ìž êµ¬ë¶„</target> @@ -948,15 +999,15 @@ Note: File names must be relative to base directories. <source>&Find next</source> <target>ë‹¤ìŒ ê²€ìƒ‰(&F)</target> +<source>Start synchronization</source> +<target>ë™ê¸°í™” 시작</target> + <source>Delete</source> <target>ì‚ì œ</target> <source>Configure filter</source> <target>í•„í„° ì„¤ì •</target> -<source>Start synchronization</source> -<target>ë™ê¸°í™” 시작</target> - <source>Find</source> <target>검색</target> @@ -991,6 +1042,20 @@ Note: File names must be relative to base directories. <target>양측 비êµ</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>ì •ë§ë¡œ %x í•ëª©ì„ 위해 %y ëª…ë ¹ì„ ì‹¤í–‰í•˜ê¸°ë¥¼ ì›í•˜ì‹ë‹ˆê¹Œ?</pluralform> +</target> + +<source>Confirm</source> +<target>확ì¸</target> + +<source>&Execute</source> +<target>실행(&E)</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1015,7 +1080,7 @@ Note: File names must be relative to base directories. </target> <source>Set direction:</source> -<target>ë°©í–¥ ì„¤ì • :</target> +<target>ë°©í–¥ ì„¤ì •:</target> <source>Exclude temporarily</source> <target>ìž„ì‹œ ì œì™¸</target> @@ -1023,12 +1088,15 @@ Note: File names must be relative to base directories. <source>Include temporarily</source> <target>ìž„ì‹œ í¬í•¨</target> -<source>Exclude via filter:</source> -<target>필터를 통하여 ì œì™¸</target> - <source>multiple selection</source> <target>복수 ì„ íƒ</target> +<source>Include via filter:</source> +<target>필터를 통해 다ìŒì„ í¬í•¨:</target> + +<source>Exclude via filter:</source> +<target>필터를 통하여 ì œì™¸</target> + <source>Include all</source> <target>ëª¨ë‘ í¬í•¨</target> @@ -1036,7 +1104,7 @@ Note: File names must be relative to base directories. <target>ëª¨ë‘ ì œì™¸</target> <source>Show icons:</source> -<target>ì•„ì´ì½˜ 표시 :</target> +<target>ì•„ì´ì½˜ 표시:</target> <source>Small</source> <target>작게</target> @@ -1074,8 +1142,8 @@ Note: File names must be relative to base directories. <source>Do&n't save</source> <target>ì €ìž¥í•˜ê¸° 않기(&n)</target> -<source>Never save changes</source> -<target>ë³€ê²½ì‚¬í• ì ˆëŒ€ ì €ìž¥ 안 함.</target> +<source>Never save &changes</source> +<target>변경사í•ì„ ì ˆëŒ€ ì €ìž¥í•˜ê¸° 않기(&c)</target> <source>Show files that exist on left side only</source> <target>좌측ì—만 존재하는 íŒŒì¼ í‘œì‹œ</target> @@ -1128,8 +1196,8 @@ Note: File names must be relative to base directories. <source>All folders are in sync</source> <target>ëª¨ë“ í´ë”ê°€ ë™ê¸°í™” ë˜ì—ˆìŒ</target> -<source>Comma separated list</source> -<target>콤마 분리 목ë¡</target> +<source>Comma-separated values</source> +<target>쉼표로 êµ¬ë¶„ëœ ê°’</target> <source>File list exported</source> <target>íŒŒì¼ ë¦¬ìŠ¤íŠ¸ 내보내기 완료</target> @@ -1137,8 +1205,8 @@ Note: File names must be relative to base directories. <source>Searching for program updates...</source> <target>프로그램 ì—…ë°ì´íŠ¸ 검색 중...</target> -<source>Ignore further errors</source> -<target>ë” ì´ìƒì˜ 오류는 무시</target> +<source>&Ignore subsequent errors</source> +<target>ì´í›„ 오류 무시(&I)</target> <source>&Ignore</source> <target>무시(&I)</target> @@ -1146,8 +1214,8 @@ Note: File names must be relative to base directories. <source>Fatal Error</source> <target>치명ì 오류</target> -<source>Don't show this warning again</source> -<target>ì´ ê²½ê³ ë¥¼ 다시 표시하지 ì•ŠìŒ</target> +<source>&Don't show this warning again</source> +<target>ì´ ê²½ê³ ë¥¼ 다시 표시하지 ì•ŠìŒ(&D)</target> <source>&Switch</source> <target>스위치[ì „í™˜](&S)</target> @@ -1182,17 +1250,14 @@ Note: File names must be relative to base directories. <source>Completed</source> <target>완료</target> -<source>Continue</source> -<target>계ì†</target> - -<source>Pause</source> -<target>ì¼ì‹œì •ì§€</target> +<source>&Continue</source> +<target>계ì†(&C)</target> -<source>Logging</source> -<target>로깅</target> +<source>Log</source> +<target>로그</target> <source>Cannot find %x</source> -<target>%x ì„(를) ì°¾ì„ ìˆ˜ 없습니다.</target> +<target>%xì„(를) ì°¾ì„ ìˆ˜ 없습니다.</target> <source>Inactive</source> <target>비활성화</target> @@ -1225,11 +1290,11 @@ Note: File names must be relative to base directories. <target>í•„í„°</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>ì •ë§ë¡œ ë‹¤ìŒ %x í•ëª©(들)ì„ íœ´ì§€í†µìœ¼ë¡œ ì´ë™í•˜ì‹œê² 습니까?</pluralform> +<pluralform>ë‹¤ìŒ %x í•ëª©ì„ ì •ë§ë¡œ 휴지통으로 ì´ë™í•˜ê¸°ë¥¼ ì›í•˜ì‹ë‹ˆê¹Œ?</pluralform> </target> <source> @@ -1250,7 +1315,7 @@ Note: File names must be relative to base directories. <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 folder name</source> <target>- ì „ì²´ íŒŒì¼ ë˜ëŠ” í´ë” ì´ë¦„</target> @@ -1282,9 +1347,6 @@ Note: File names must be relative to base directories. <source>Append a timestamp to each file name</source> <target>ê° íŒŒì¼ ì´ë¦„마다 타임스탬프 추가</target> -<source>Folder</source> -<target>í´ë”</target> - <source>File</source> <target>파ì¼</target> @@ -1301,22 +1363,22 @@ Note: File names must be relative to base directories. <target>백분율(%)</target> <source>Cannot monitor directory %x.</source> -<target>ë””ë ‰í† ë¦¬ %x ì„(를) ëª¨ë‹ˆí„°ë§ í• ìˆ˜ 없습니다.</target> +<target>ë””ë ‰í† ë¦¬ %xì„(를) ëª¨ë‹ˆí„°ë§ í• ìˆ˜ 없습니다.</target> <source>Conversion error:</source> -<target>변환 오류 :</target> +<target>변환 오류:</target> <source>Cannot delete file %x.</source> -<target>íŒŒì¼ %x ì„(를) ì‚ì œí• ìˆ˜ 없습니다.</target> +<target>íŒŒì¼ %xì„(를) ì‚ì œí• ìˆ˜ 없습니다.</target> <source>The file is locked by another process:</source> -<target>파ì¼ì´ 다른 í”„ë¡œì„¸ìŠ¤ì— ì˜í•´ ìž ê²¨ 있습니다 :</target> +<target>파ì¼ì´ 다른 í”„ë¡œì„¸ìŠ¤ì— ì˜í•´ ìž ê²¨ 있습니다:</target> <source>Cannot move file %x to %y.</source> -<target>íŒŒì¼ %x ì„(를) %y (으)ë¡œ ì´ë™í• 수 없습니다.</target> +<target>íŒŒì¼ %xì„(를) %y(으)ë¡œ ì´ë™í• 수 없습니다.</target> <source>Cannot delete directory %x.</source> -<target>ë””ë ‰í† ë¦¬ %x ì„(를) ì‚ì œí• ìˆ˜ 없습니다.</target> +<target>ë””ë ‰í† ë¦¬ %xì„(를) ì‚ì œí• ìˆ˜ 없습니다.</target> <source>Cannot write file attributes of %x.</source> <target>%xì˜ íŒŒì¼ ì†ì„±ì„ 쓸 수 없습니다.</target> @@ -1337,28 +1399,28 @@ Note: File names must be relative to base directories. <target>%xì˜ ê¶Œí•œì„ ì“¸ 수 없습니다.</target> <source>Cannot create directory %x.</source> -<target>ë””ë ‰í† ë¦¬ %x ì„(를) ìƒì„±í• 수 없습니다.</target> +<target>ë””ë ‰í† ë¦¬ %xì„(를) ìƒì„±í• 수 없습니다.</target> <source>Cannot create symbolic link %x.</source> -<target>ì‹¬ë³¼ë¦ ë§í¬ %x ì„(를) ìƒì„±í• 수 없습니다.</target> +<target>ì‹¬ë³¼ë¦ ë§í¬ %xì„(를) ìƒì„±í• 수 없습니다.</target> <source>Cannot find system function %x.</source> -<target>시스템 함수 %x ì„(를) ì°¾ì„ ìˆ˜ 없습니다.</target> +<target>시스템 함수 %xì„(를) ì°¾ì„ ìˆ˜ 없습니다.</target> <source>Cannot copy file %x to %y.</source> -<target>íŒŒì¼ %x ì„(를) %y (으)ë¡œ ë³µì‚¬í• ìˆ˜ 없습니다.</target> +<target>íŒŒì¼ %xì„(를) %y(으)ë¡œ ë³µì‚¬í• ìˆ˜ 없습니다.</target> <source>Type of item %x is not supported:</source> -<target>í•ëª© %xì˜ í˜•ì‹ì€ 지ì›ë˜ì§€ 않습니다 :</target> +<target>í•ëª© %xì˜ í˜•ì‹ì€ 지ì›ë˜ì§€ 않습니다:</target> <source>Cannot resolve symbolic link %x.</source> -<target>ì‹¬ë³¼ë¦ ë§í¬ %x ì„(를) í•´ê²°í• ìˆ˜ 없습니다.</target> +<target>ì‹¬ë³¼ë¦ ë§í¬ %xì„(를) í•´ê²°í• ìˆ˜ 없습니다.</target> <source>Cannot open directory %x.</source> -<target>ë””ë ‰í† ë¦¬ %x ì„(를) ì—´ 수 없습니다.</target> +<target>ë””ë ‰í† ë¦¬ %xì„(를) ì—´ 수 없습니다.</target> <source>Cannot enumerate directory %x.</source> -<target>ë””ë ‰í† ë¦¬ %x ì„(를) ì—´ê±°í• ìˆ˜ 없습니다.</target> +<target>ë””ë ‰í† ë¦¬ %xì„(를) ì—´ê±°í• ìˆ˜ 없습니다.</target> <source>%x TB</source> <target>%x TB</target> @@ -1394,7 +1456,7 @@ Note: File names must be relative to base directories. <target>시스템 메시지를 받기 위한 등ë¡ì— 실패하였습니다.</target> <source>Cannot set privilege %x.</source> -<target>권한 %x ì„(를) ì„¤ì •í• ìˆ˜ 없습니다.</target> +<target>권한 %xì„(를) ì„¤ì •í• ìˆ˜ 없습니다.</target> <source>Failed to suspend system sleep mode.</source> <target>시스템 ì ˆì „ëª¨ë“œ 중지 실패</target> @@ -1402,8 +1464,8 @@ Note: File names must be relative to base directories. <source>Cannot change process I/O priorities.</source> <target>I/O ìš°ì„ ìˆœìœ„ 프로세스 변경 불가</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>%x ì„(를) 휴지통으로 ì´ë™í• 수 없습니다.</target> +<source>Unable to move %x to the recycle bin.</source> +<target>휴지통으로 %xì„(를) ì´ë™í• 수 없습니다.</target> <source>Cannot determine final path for %x.</source> <target>%x ì— ëŒ€í•œ 최종 경로를 ê²°ì •í• ìˆ˜ 없습니다.</target> diff --git a/BUILD/Languages/lithuanian.lng b/BUILD/Languages/lithuanian.lng index e3bfed10..032b8ee6 100644 --- a/BUILD/Languages/lithuanian.lng +++ b/BUILD/Languages/lithuanian.lng @@ -1,61 +1,38 @@ <header> <language>Lietuvių</language> - <translator>Liudas AliÅ¡auskas</translator> + <translator>Tadas Norbutas</translator> <locale>lt_LT</locale> <flag_image>flag_lithuania.png</flag_image> <plural_form_count>4</plural_form_count> <plural_definition>n==1 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : n%10==0 || (n%100>10 && n%100<20) ? 2 : 3</plural_definition> </header> -<source>Cannot determine final path for %x.</source> -<target></target> - -<source>Failed to register to receive system messages.</source> -<target></target> - -<source>Cannot resolve symbolic link %x.</source> -<target></target> - -<source>Cannot create symbolic link %x.</source> +<source>&Continue</source> <target></target> -<source>Items</source> +<source>&Don't show this warning again</source> <target></target> -<source>Log</source> +<source>&Ignore subsequent errors</source> <target></target> -<source>&Continue</source> -<target></target> - -<source>Comma-separated values</source> +<source>Never save &changes</source> <target></target> <source> <pluralform>%y of 1 row in view</pluralform> <pluralform>%y of %x rows in view</pluralform> </source> -<target></target> - -<source>&Don't show this dialog again</source> -<target></target> +<target> +</target> <source>&Execute</source> <target></target> -<source>Confirm</source> -<target></target> - -<source> -<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> -<pluralform>Do you really want to execute the command %y for %x items?</pluralform> -</source> +<source>&Don't show this dialog again</source> <target></target> -<source>Select a variant</source> -<target></target> - -<source>Minimize to notification area</source> +<source>Close search bar</source> <target></target> <source>Check for new &version</source> @@ -64,110 +41,25 @@ <source>&Tools</source> <target></target> -<source>Cannot find current FreeFileSync version number online. Do you want to check manually?</source> -<target></target> - <source>&Download</source> <target></target> -<source>New version found</source> -<target></target> - -<source>Retrying operation after error:</source> -<target></target> - -<source>Switching to FreeFileSync main dialog</source> -<target></target> - -<source>Data verification error: %x and %y have different content.</source> -<target></target> - -<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> -<target></target> - <source>&Show error</source> <target></target> -<source>Waiting until all directories are available...</source> -<target></target> - -<source>Directory monitoring active</source> -<target></target> - -<source>Volume name %x is not part of file path %y.</source> -<target></target> - -<source>Cannot determine volume name for %x.</source> -<target></target> - -<source>%x items</source> -<target></target> - <source> <pluralform>1 thread</pluralform> <pluralform>%x threads</pluralform> </source> -<target></target> +<target> +</target> <source> <pluralform>1 byte</pluralform> <pluralform>%x bytes</pluralform> </source> -<target></target> - -<source>Cannot read file attributes of %x.</source> -<target></target> - -<source>Starting comparison</source> -<target></target> - -<source>Resolving symbolic link %x</source> -<target></target> - -<source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> -<target></target> - -<source>You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.</source> -<target></target> - -<source>Any number of alternative directories for at most one config file.</source> -<target></target> - -<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> -<target></target> - -<source>directory</source> -<target></target> - -<source>config files</source> -<target></target> - -<source>Syntax:</source> -<target></target> - -<source>Directories cannot be set for more than one configuration file.</source> -<target></target> - -<source>The config file must not contain settings at folder pair level when directories are set via command line.</source> -<target></target> - -<source>Unequal number of left and right directories specified.</source> -<target></target> - -<source>Cannot open file %x.</source> -<target></target> - -<source>Syntax error</source> -<target></target> - -<source>A directory path is expected after %x.</source> -<target></target> - -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target></target> - -<source>The database entry is not in sync considering current settings.</source> -<target></target> +<target> +</target> <source>Both sides have changed since last synchronization.</source> <target>Abi pusÄ—s buvo pakeistos nuo paskutinio sinchronizavimo.</target> @@ -178,20 +70,23 @@ <source>No change since last synchronization.</source> <target>NÄ—ra pakitimo nuo pakutinio sinchronizavimo.</target> +<source>The database entry is not in sync considering current settings.</source> +<target>Duomenų bazÄ—s įraÅ¡as nesinchronizuotas remiantis Å¡iais nustatymais.</target> + <source>Setting default synchronization directions: Old files will be overwritten with newer files.</source> <target>Nustatomos numatytos sinchronizavimo kryptys: Seni failai bus perraÅ¡yti naujesniais failais.</target> <source>Checking recycle bin availability for folder %x...</source> <target>Tikrinamas Å¡iukÅ¡liadėžės prieinamumas aplankui %x...</target> -<source>Moving file %x to recycle bin</source> -<target>Perkeliamas failas %x į Å¡iukÅ¡liadėžę</target> +<source>Moving file %x to the recycle bin</source> +<target>%x failas perkeliamas į Å¡iukÅ¡liadėžę</target> -<source>Moving folder %x to recycle bin</source> -<target>Perkeliamas aplankas %x į Å¡iukÅ¡liadėžę</target> +<source>Moving folder %x to the recycle bin</source> +<target>%x katalogas perkeliamas į Å¡iukÅ¡liadėžę</target> -<source>Moving symbolic link %x to recycle bin</source> -<target>Perkeliama simbolinÄ— nuoroda %x į Å¡iukÅ¡liadėžę</target> +<source>Moving symbolic link %x to the recycle bin</source> +<target>SimbolinÄ— nuoroda %x perkeliama į Å¡iukÅ¡liadėžę</target> <source>Deleting file %x</source> <target>Trinamas failas %x</target> @@ -202,18 +97,54 @@ <source>Deleting symbolic link %x</source> <target>Tinama simbolinÄ— nuoroda %x</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>Å iuklÅ¡lių dėžė Å¡iems katalogams yra nepasiekiama. Failai bus negrįžtamai iÅ¡trinti:</target> + <source>An exception occurred</source> <target>Atsirado iÅ¡imtis</target> +<source>A directory path is expected after %x.</source> +<target>Reikalingas katalogo kelias po %x</target> + +<source>Syntax error</source> +<target>SintaksÄ—s klaida</target> + +<source>Cannot open file %x.</source> +<target>%x failo nepavyko atidaryti.</target> + <source>Error</source> <target>Klaida</target> <source>File %x does not contain a valid configuration.</source> <target>Failas %x neturi tinkamų nustatymų.</target> +<source>Unequal number of left and right directories specified.</source> +<target>Nustatytas nevienodas skaiÄius katalogų kairÄ—je ir deÅ¡inÄ—je.</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>Config failas negali turÄ—ti katalogų poros lygio nustatymų kai katalogai nustatomi per komandinÄ™ eilutÄ™.</target> + <source>Warning</source> <target>PerspÄ—jimas</target> +<source>Directories cannot be set for more than one configuration file.</source> +<target>Katalogai negali bÅ«ti nustatyti daugiau nei viename konfigÅ«racijos faile.</target> + +<source>Syntax:</source> +<target>SintaksÄ—:</target> + +<source>config files</source> +<target>config failai</target> + +<source>directory</source> +<target>katalogas</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>Keletas FreeFileSync .ffs_gui ir/arba .ffs_batch configÅ«racijos failų</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>Daugiausia vienam config failui, n alternatyvių katalogų</target> + <source>Command line</source> <target>KomandinÄ— eilutÄ—</target> @@ -226,6 +157,12 @@ <source>Cannot find the following folders:</source> <target>Nepavyksta rasti Å¡ių aplankų:</target> +<source>You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.</source> +<target>Jei žinote, kad kiekvienas katalogas yra tuÅ¡Äias, Å¡iÄ… klaidÄ… galite ignoruoti. Katalogai bus automatiÅ¡kai sukurti sinchronizacijos metu.</target> + +<source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> +<target>Å ie katalogai turi tarpusavyje susijusių kelių. BÅ«kite atsargÅ«s nustatydami sinchronizacijos taisykles:</target> + <source>File %x has an invalid date.</source> <target>Failas %x turi netinkamÄ… datÄ….</target> @@ -241,12 +178,18 @@ <source>Items differ in attributes only</source> <target>Elementai skiriasi tik atributais</target> +<source>Resolving symbolic link %x</source> +<target>IeÅ¡koma simbolinÄ—s nuorodos %x</target> + <source>Comparing content of files %x</source> <target>Sulyginamas failų turinys %x</target> <source>Generating file list...</source> <target>Generuojamas failų sÄ…raÅ¡as...</target> +<source>Starting comparison</source> +<target>Pradedamas palyginimas</target> + <source>Calculating sync directions...</source> <target>ApskaiÄiuojamos sinchrinizacijos kryptys...</target> @@ -331,6 +274,9 @@ <source>Searching for folder %x...</source> <target>IeÅ¡koma aplanko %x...</target> +<source>Cannot read file attributes of %x.</source> +<target>Nepavyko perskaityti failo %x atributų</target> + <source>Cannot get process information.</source> <target>Nepavyksta gauti eigos informacijos.</target> @@ -384,6 +330,9 @@ <source>/sec</source> <target>/sek.</target> +<source>%x items</source> +<target>%x pozicijos</target> + <source>Configuration file %x loaded partially only.</source> <target>Nustatymų failas %x įkeltas tik dalinai.</target> @@ -396,8 +345,8 @@ <source>Browse directory</source> <target>NarÅ¡yti katalogÄ…</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Nepavyksta apsiekti tomo Å¡Ä—Å¡Ä—linio kopijavimo tarnybos.</target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target>Volume Shadow Copy paslauga nepasiekiama.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>PraÅ¡ome naudoti 64-bit FreeFileSync versijÄ…, kad sukurti Å¡Ä—Å¡Ä—lines kopijas Å¡ioje sistemoje.</target> @@ -405,6 +354,12 @@ <source>Cannot load file %x.</source> <target>Nepavyksta įkelti failo %x.</target> +<source>Cannot determine volume name for %x.</source> +<target>Vietos vardo %x nustatyti nepavyko</target> + +<source>Volume name %x is not part of file path %y.</source> +<target>Vietos vardas %x nÄ—ra failo kelio %y dalis.</target> + <source>Abort requested: Waiting for current operation to finish...</source> <target>Nutraukti: laukiama kol baigsis esama operacija...</target> @@ -503,6 +458,12 @@ Komanda inicijuojama jei: <source>All files</source> <target>Visi failai</target> +<source>Directory monitoring active</source> +<target>Katalogų stebÄ—jimas yra aktyvus</target> + +<source>Waiting until all directories are available...</source> +<target>Laukiama kol katalogai bus prieinami...</target> + <source>&Restore</source> <target>&Atstatyti</target> @@ -581,6 +542,9 @@ Komanda inicijuojama jei: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>Å ie elementai turi neiÅ¡sprÄ™stų konfliktų ir nebus sinchronizuoti:</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>Å ie katalogai yra labai skirtingi. Ä®sitikinkite, kad sinchronizacijai pasirinkote teisingus katalogus.</target> + <source>Not enough free disk space available in:</source> <target>Nepakanka laisvos disko vietos:</target> @@ -599,8 +563,14 @@ Komanda inicijuojama jei: <source>Generating database...</source> <target>Generuojama duomenų bazÄ—...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>Kuriama vietos Å¡Ä—Å¡Ä—linÄ— kopija dÄ—l %x...</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>%x kuriamas Volume Shadow Copy...</target> + +<source>Data verification error: %x and %y have different content.</source> +<target>Duomenų patikros klaida: %x ir %y turinys yra skirtingas.</target> + +<source>job name</source> +<target>Užduoties pavadinimas</target> <source>Synchronization aborted</source> <target>Synchronizavimas nutrauktas</target> @@ -623,12 +593,21 @@ Komanda inicijuojama jei: <source>Press "Switch" to resolve issues in FreeFileSync main dialog.</source> <target>Spauskite „Perjungti“, kad iÅ¡sprÄ™sti problemas pagrindiniame FreeFileSync lange.</target> +<source>Switching to FreeFileSync main dialog</source> +<target>KeiÄiama į pagrindinį FreeFileSync langÄ…</target> + +<source>Retrying operation after error:</source> +<target>Po klaidos kartojama operacija:</target> + <source>A new version of FreeFileSync is available:</source> <target>Yra nauja FreeFileSync versija:</target> <source>Download now?</source> <target>Atsiųsti dabar?</target> +<source>New version found</source> +<target>Rasta nauja versija</target> + <source>FreeFileSync is up to date.</source> <target>FreeFileSync yra naujausia.</target> @@ -638,11 +617,14 @@ Komanda inicijuojama jei: <source>Unable to connect to sourceforge.net.</source> <target>Nepavyksta prisijungti prie sourceforge.net.</target> +<source>Cannot find current FreeFileSync version number online. Do you want to check manually?</source> +<target>DabartinÄ—s FreeFileSync versijos numeris internete nerastas. Ar norÄ—tumÄ—te patikrinti rankiniu bÅ«du?</target> + <source>Symlink</source> <target>SimbolinÄ— nuoroda</target> <source>Folder</source> -<target>Aplankas</target> +<target>Katalogas</target> <source>Full path</source> <target>Pilnas kelias</target> @@ -651,10 +633,10 @@ Komanda inicijuojama jei: <target>Pavadinimas</target> <source>Relative path</source> -<target>Atitinkamas kelias</target> +<target>Elemento kelias</target> <source>Base folder</source> -<target>Bazinis aplankas</target> +<target>Bazinis katalogas</target> <source>Size</source> <target>Dydis</target> @@ -737,8 +719,8 @@ Komanda inicijuojama jei: <source>&Export file list...</source> <target>&Eksportuoti failų sÄ…raÅ¡Ä…...</target> -<source>&Global settings...</source> -<target>&Bendri nustatymai...</target> +<source>&Global settings</source> +<target>&Bendri nustatymai</target> <source>&Check now</source> <target>&Tikrinti dabar</target> @@ -749,12 +731,6 @@ Komanda inicijuojama jei: <source>Compare</source> <target>Sulyginti</target> -<source>Comparison settings</source> -<target>Sulyginimo nustatymai</target> - -<source>Synchronization settings</source> -<target>Sinchronizavimo nustatymai</target> - <source>Synchronize</source> <target>Sinchronizuoti</target> @@ -767,6 +743,12 @@ Komanda inicijuojama jei: <source>Swap sides</source> <target>Sukeisti puses</target> +<source>Find what:</source> +<target>Rasti kas:</target> + +<source>Match case</source> +<target>Atitikti atvejÄ…</target> + <source>Save as batch job</source> <target>IÅ¡saugoti kaip paketinį darbÄ…</target> @@ -803,6 +785,9 @@ Komanda inicijuojama jei: <source>Synchronizing...</source> <target>Sinchronizuojama...</target> +<source>Minimize to notification area</source> +<target>Nuleisti į apaÄiÄ… deÅ¡inÄ—je</target> + <source>On completion</source> <target>Baigus</target> @@ -818,8 +803,8 @@ Komanda inicijuojama jei: <source>Statistics</source> <target>Statistika</target> -<source>Don't show this dialog again</source> -<target>Daugiau nerodyti Å¡io dialogo</target> +<source>Select a variant</source> +<target>Pasirinkti</target> <source> Files are found equal if @@ -866,6 +851,12 @@ yra toks pats <source>Configure your own synchronization rules.</source> <target>Nustatyti JÅ«sų paÄių sinchronizavimo taisykles.</target> +<source>Detect moved files</source> +<target>Rasti perkeltus failus</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Reikalauja duomenų bazÄ—s failų. Visų failų sistemų nÄ—ra palaikoma.</target> + <source>Error handling</source> <target>Klaidų valdymas</target> @@ -890,17 +881,17 @@ yra toks pats <source>Delete or overwrite files permanently</source> <target>Trinti ar perraÅ¡yti failus visam laikui</target> -<source>Recycle Bin</source> -<target>Å iukÅ¡liadėžė</target> +<source>Recycle bin</source> +<target>Å iukÅ¡lių dėžė</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Naudoti Å¡iukÅ¡liadėžę iÅ¡trintiems ir perraÅ¡ytiems failams</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Padaryti Å¡iukÅ¡lių dėžėje esanÄių iÅ¡trintų ar perraÅ¡ytų failų atsarginÄ™ kopijÄ…</target> <source>Versioning</source> <target>Versijavimas</target> -<source>Move files to user-defined folder</source> -<target>Perkelti failus į naudotojo nurodytÄ… aplankÄ…</target> +<source>Move files to a user-defined folder</source> +<target>Perkelti failus į vartotojo nustatytÄ… katalogÄ…</target> <source>Naming convention:</source> <target>Pavadinimų taisyklÄ—s:</target> @@ -908,8 +899,8 @@ yra toks pats <source>Batch job</source> <target>PaketinÄ— užduotis</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Sukurkite paketinÄ—s užduoties failÄ…, kad automatizuoti sinchronizacijÄ…. SpragtelÄ—kite du kartus šį failÄ… arba nustatykite JÅ«sų sistemos užduoÄių planuoklÄ—je: FreeFileSync.exe <užduoties pavadinimas>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Sukurti paleidimo failÄ… sinchronizacijai be priežiÅ«ros. Norint jį paleisti reikia paspausti and failo du kartus pele arba nustatyti su užduoÄių planuotoju: %x</target> <source>Exit</source> <target>IÅ¡eiti</target> @@ -932,30 +923,6 @@ yra toks pats <source>Limit maximum number of log files</source> <target>Apriboti ataskaitų failų skaiÄių</target> -<source>Source code written in C++ using:</source> -<target>Å altinio kodas paraÅ¡ytas su C++ naudojant:</target> - -<source>If you like FreeFileSync</source> -<target>Jei Jums patinka FreeFileSync</target> - -<source>Donate with PayPal</source> -<target>Paremkite per PayPal</target> - -<source>Many thanks for localization:</source> -<target>Labai dÄ—kojame už vertimÄ…:</target> - -<source>Feedback and suggestions are welcome</source> -<target>NuomonÄ— ir patarimai laukiami</target> - -<source>Homepage</source> -<target>Namų puslapis</target> - -<source>Email</source> -<target>El. paÅ¡tas</target> - -<source>Published under the GNU General Public License</source> -<target>Platinama su GNU General Public licenzija</target> - <source>Delete on both sides</source> <target>IÅ¡trinti abiejose pusÄ—se</target> @@ -963,12 +930,12 @@ yra toks pats <target>IÅ¡trinti abiejose pusÄ—se net jei failas yra pažymÄ—tas tik vienoje pusÄ—je</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -Tik failai, kurie atitinka visus filtro nustatymus bus sinchronizuoti. -Pastaba: Failų pavadinimai privalo atitikti bazinius katalogus. +Failai gali bÅ«ti sinchronizuoti tik tada, kai atitinka filtrų taisykles +Pastaba: Failų keliai turi bÅ«ti nurodyti tik iki pagrindinių katalogų </target> <source>Include</source> @@ -998,20 +965,20 @@ Pastaba: Failų pavadinimai privalo atitikti bazinius katalogus. <source>Fail-safe file copy</source> <target>ApsauginÄ— failo kopija</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>Pirmiausiai raÅ¡yti į laikinÄ…jį failÄ… (*.ffs_tmp), tada pervardinti jį. Tai garantuoja pastovumÄ… net ir kritinÄ—s klaidos atveju.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>Kopijuoti į laikinÄ… failÄ… (*.ffs_tmp), o tik po to pervadinti. Tai garantuojÄ… stabiliÄ… bÅ«senÄ… net įvykus nepataisomai klaidai.</target> <source>Copy locked files</source> <target>Kopijuoti užrakintus failus</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Kopijuoti vieÅ¡inamus ar užrakintus failus naudojant tomo Å¡Ä—Å¡Ä—linio kopijavimo tarnybÄ… (Reikalingos administratoriaus teisÄ—s)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>Kopijuoti bendrintus ar užrakintus failus naudojant Volume Shadow Copy paslaugÄ… (administratoriaus teisÄ—s privalomos)</target> <source>Copy file access permissions</source> <target>Kopijuoti failo leidimus</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Perkelti failo ir aplanko leidimus (Reikalauja administratoriaus teisų)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>IÅ¡saugoti failų ir katalogų teises (administratoriaus teisÄ—s privalomos)</target> <source>Restore hidden dialogs</source> <target>Atstatyti paslÄ—ptus langus</target> @@ -1025,33 +992,54 @@ Pastaba: Failų pavadinimai privalo atitikti bazinius katalogus. <source>&Default</source> <target>&Numatyta</target> -<source>Find what:</source> -<target>Rasti kas:</target> +<source>Source code written in C++ using:</source> +<target>Å altinio kodas paraÅ¡ytas su C++ naudojant:</target> -<source>Match case</source> -<target>Atitikti atvejÄ…</target> +<source>If you like FreeFileSync</source> +<target>Jei Jums patinka FreeFileSync</target> + +<source>Donate with PayPal</source> +<target>Paremkite per PayPal</target> + +<source>Feedback and suggestions are welcome</source> +<target>NuomonÄ— ir patarimai laukiami</target> + +<source>Homepage</source> +<target>Namų puslapis</target> + +<source>Email</source> +<target>El. paÅ¡tas</target> + +<source>Published under the GNU General Public License</source> +<target>Platinama su GNU General Public licenzija</target> -<source>&Find next</source> -<target>&Rasti kitÄ…</target> +<source>Many thanks for localization:</source> +<target>Labai dÄ—kojame už vertimÄ…:</target> <source>Start synchronization</source> <target>PradÄ—ti sinchronizavimÄ…</target> +<source>Comparison settings</source> +<target>Sulyginimo nustatymai</target> + +<source>Synchronization settings</source> +<target>Sinchronizavimo nustatymai</target> + <source>Delete</source> <target>Trinti</target> <source>Configure filter</source> <target>Nustatyti filtrÄ…</target> -<source>Find</source> -<target>Rasti</target> - <source>Select time span</source> <target>PažymÄ—ti laiko trukmÄ™</target> <source>Folder pairs</source> <target>Aplankų poros</target> +<source>Find</source> +<target>Rasti</target> + <source>Overview</source> <target>Apžvalga</target> @@ -1077,6 +1065,20 @@ Pastaba: Failų pavadinimai privalo atitikti bazinius katalogus. <target>Sulyginti abi puses</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>Ar tikrai norite paleisti %y komandÄ… 1-ai pozicijai?</pluralform> +<pluralform>Ar tikrai norite paleisti %y komandÄ… %x pozicijoms?</pluralform> +<pluralform>Ar tikrai norite paleisti %y komandÄ… %x pozicijų?</pluralform> +<pluralform>Ar tikrai norite paleisti %y komandÄ… %x pozicijai?</pluralform> +</target> + +<source>Confirm</source> +<target>Patvirtinti</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1101,17 +1103,20 @@ Pastaba: Failų pavadinimai privalo atitikti bazinius katalogus. <source>Set direction:</source> <target>Nustatyti kryptį:</target> -<source>Exclude temporarily</source> -<target>Neįtraukti laikinai</target> +<source>multiple selection</source> +<target>keletos pažymÄ—jimas</target> -<source>Include temporarily</source> -<target>Ä®traukti laikinai</target> +<source>Include via filter:</source> +<target>Ä®traukti naudojant filtrÄ…:</target> <source>Exclude via filter:</source> <target>Neįtraukti per filtrÄ…:</target> -<source>multiple selection</source> -<target>keletos pažymÄ—jimas</target> +<source>Exclude temporarily</source> +<target>Neįtraukti laikinai</target> + +<source>Include temporarily</source> +<target>Ä®traukti laikinai</target> <source>Include all</source> <target>Ä®traukti visus</target> @@ -1158,9 +1163,6 @@ Pastaba: Failų pavadinimai privalo atitikti bazinius katalogus. <source>Do&n't save</source> <target>&Nesaugoti</target> -<source>Never save changes</source> -<target>Niekada nesaugoti pakeitimų</target> - <source>Show files that exist on left side only</source> <target>Rodyti failus, kurie egzistuoja tik kairÄ—je pusÄ—je</target> @@ -1212,24 +1214,24 @@ Pastaba: Failų pavadinimai privalo atitikti bazinius katalogus. <source>All folders are in sync</source> <target>Visi aplankai susinchronizuoti</target> +<source>Cannot find %x</source> +<target>Nepavyksta rasti %x</target> + +<source>Comma-separated values</source> +<target>Kableliu atskirtos reikÅ¡mÄ—s</target> + <source>File list exported</source> <target>Failų sÄ…raÅ¡as eksportuotas</target> <source>Searching for program updates...</source> <target>IeÅ¡koma programos atnaujinimų...</target> -<source>Ignore further errors</source> -<target>Ignoruoti tolimesnes klaidas</target> - <source>&Ignore</source> <target>&Ignoruoti</target> <source>Fatal Error</source> <target>KritinÄ— klaida</target> -<source>Don't show this warning again</source> -<target>Neberodyti daugiau Å¡io perspÄ—jimo</target> - <source>&Switch</source> <target>&Perjungti</target> @@ -1263,8 +1265,8 @@ Pastaba: Failų pavadinimai privalo atitikti bazinius katalogus. <source>Completed</source> <target>Baigta</target> -<source>Cannot find %x</source> -<target>Nepavyksta rasti %x</target> +<source>Log</source> +<target>Archyvas</target> <source>Inactive</source> <target>Neaktyvus</target> @@ -1297,14 +1299,14 @@ Pastaba: Failų pavadinimai privalo atitikti bazinius katalogus. <target>Filtras</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>Ar tikrai norite perkelti šį elementÄ… į Å¡iukÅ¡liadėžę?</pluralform> -<pluralform>Ar tikrai norite perkelti Å¡iuos %x elementus į Å¡iukÅ¡liadėžę?</pluralform> -<pluralform>Ar tikrai norite perkelti Å¡iuos %x elementų į Å¡iukÅ¡liadėžę?</pluralform> -<pluralform>Ar tikrai norite perkelti šį %x elementÄ… į Å¡iukÅ¡liadėžę?</pluralform> +<pluralform>Ar tikrai norite perkelti pozicijÄ… į Å¡iukÅ¡klių dėžę?</pluralform> +<pluralform>Ar tikrai norite perkelti Å¡ias %x pozicijas į Å¡iukÅ¡klių dėžę?</pluralform> +<pluralform>Ar tikrai norite perkelti Å¡ias %x pozicijų į Å¡iukÅ¡klių dėžę?</pluralform> +<pluralform>Ar tikrai norite perkelti pozicijÄ… %x į Å¡iukÅ¡klių dėžę?</pluralform> </target> <source> @@ -1369,6 +1371,9 @@ Pastaba: Failų pavadinimai privalo atitikti bazinius katalogus. <source>Files</source> <target>Failai</target> +<source>Items</source> +<target>Pozicijos</target> + <source>Percentage</source> <target>Procentai</target> @@ -1411,6 +1416,9 @@ Pastaba: Failų pavadinimai privalo atitikti bazinius katalogus. <source>Cannot create directory %x.</source> <target>Nepavyksta sukurti katalogo %x.</target> +<source>Cannot create symbolic link %x.</source> +<target>Nepavyko sukurti simbolinÄ—s nuorodos %x</target> + <source>Cannot find system function %x.</source> <target>Nepavyksta rasti sistemos funkcijos %x.</target> @@ -1420,6 +1428,9 @@ Pastaba: Failų pavadinimai privalo atitikti bazinius katalogus. <source>Type of item %x is not supported:</source> <target>Element tipas %x nepalaikomas:</target> +<source>Cannot resolve symbolic link %x.</source> +<target>Nepavyko rasti simbolinÄ—s nuorodos %x reikÅ¡mÄ—s</target> + <source>Cannot open directory %x.</source> <target>Nepavyksta atverti direktorijos %x.</target> @@ -1465,6 +1476,9 @@ Pastaba: Failų pavadinimai privalo atitikti bazinius katalogus. <pluralform>%x diena</pluralform> </target> +<source>Failed to register to receive system messages.</source> +<target>Užregistruoti sistemos praneÅ¡imų gavimui nepavyko</target> + <source>Cannot set privilege %x.</source> <target>Nepavyksta nustatyti privilegijos %x.</target> @@ -1474,8 +1488,11 @@ Pastaba: Failų pavadinimai privalo atitikti bazinius katalogus. <source>Cannot change process I/O priorities.</source> <target>Nepavyksta pakeisti proceso I/O prioritetų.</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>Nepavyksta perkelti %x į Å¡iukÅ¡liadėžę.</target> +<source>Unable to move %x to the recycle bin.</source> +<target>%x į Å¡iukÅ¡linÄ™ perkelti nepavyko</target> + +<source>Cannot determine final path for %x.</source> +<target>Galutinio %x kelio rasti nepavyko</target> <source>Error Code %x:</source> <target>Klaidos kodas %x:</target> diff --git a/BUILD/Languages/norwegian.lng b/BUILD/Languages/outdated/norwegian.lng index 4ebcd3a5..2e50c49d 100644 --- a/BUILD/Languages/norwegian.lng +++ b/BUILD/Languages/outdated/norwegian.lng @@ -10,6 +10,9 @@ <source>Cannot determine final path for %x.</source> <target></target> +<source>Unable to move %x to the recycle bin.</source> +<target></target> + <source>Failed to register to receive system messages.</source> <target></target> @@ -26,30 +29,94 @@ <pluralform>Do you really want to delete the following item?</pluralform> <pluralform>Do you really want to delete the following %x items?</pluralform> </source> -<target></target> +<target> +</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> +<target> +</target> + +<source>Log</source> +<target></target> + +<source>&Continue</source> +<target></target> + +<source>&Don't show this warning again</source> <target></target> -<source>Don't show this warning again</source> +<source>&Ignore subsequent errors</source> <target></target> <source>Searching for program updates...</source> <target></target> +<source>Comma-separated values</source> +<target></target> + +<source>Never save &changes</source> +<target></target> + +<source>Include via filter:</source> +<target></target> + <source> <pluralform>%y of 1 row in view</pluralform> <pluralform>%y of %x rows in view</pluralform> </source> +<target> +</target> + +<source>&Execute</source> +<target></target> + +<source>Confirm</source> +<target></target> + +<source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +</target> + +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target></target> + +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target></target> + +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> <target></target> <source>&Clear</source> <target></target> -<source>Move files to user-defined folder</source> +<source> +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. +</source> +<target></target> + +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target></target> + +<source>Move files to a user-defined folder</source> +<target></target> + +<source>Back up deleted and overwritten files in the recycle bin</source> +<target></target> + +<source>Recycle bin</source> +<target></target> + +<source>Requires database files. Not supported by all file systems.</source> +<target></target> + +<source>Detect moved files</source> <target></target> <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> @@ -58,6 +125,12 @@ <source>Select a variant</source> <target></target> +<source>&Don't show this dialog again</source> +<target></target> + +<source>Minimize to notification area</source> +<target></target> + <source>Check for new &version</source> <target></target> @@ -82,21 +155,62 @@ <source>New version found</source> <target></target> +<source>Retrying operation after error:</source> +<target></target> + <source>Switching to FreeFileSync main dialog</source> <target></target> +<source>job name</source> +<target></target> + <source>Data verification error: %x and %y have different content.</source> <target></target> -<source>Creating Volume Shadow Copy for %x...</source> +<source>Creating a Volume Shadow Copy for %x...</source> +<target></target> + +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target></target> + +<source>&Show error</source> +<target></target> + +<source>Waiting until all directories are available...</source> +<target></target> + +<source>Directory monitoring active</source> +<target></target> + +<source>Volume name %x is not part of file path %y.</source> <target></target> <source>Cannot determine volume name for %x.</source> <target></target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target></target> + +<source>%x items</source> +<target></target> + +<source> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> +</source> +<target> +</target> + <source>Cannot set directory lock for %x.</source> <target></target> +<source> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> +</source> +<target> +</target> + <source>Calculating sync directions...</source> <target></target> @@ -115,7 +229,49 @@ <source>The corresponding folder will be considered as empty.</source> <target></target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> +<source>Any number of alternative directories for at most one config file.</source> +<target></target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target></target> + +<source>directory</source> +<target></target> + +<source>config files</source> +<target></target> + +<source>Syntax:</source> +<target></target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target></target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target></target> + +<source>Unequal number of left and right directories specified.</source> +<target></target> + +<source>Cannot open file %x.</source> +<target></target> + +<source>Syntax error</source> +<target></target> + +<source>A directory path is expected after %x.</source> +<target></target> + +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target></target> + +<source>Moving symbolic link %x to the recycle bin</source> +<target></target> + +<source>Moving folder %x to the recycle bin</source> +<target></target> + +<source>Moving file %x to the recycle bin</source> <target></target> <source>The database entry is not in sync considering current settings.</source> @@ -136,15 +292,6 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Sjekker søppelbøtte for tilgjengelig mappe %x...</target> -<source>Moving file %x to recycle bin</source> -<target>Flytter fil %x til papirkurv</target> - -<source>Moving folder %x to recycle bin</source> -<target>Flytter mappe %x til papirkurv</target> - -<source>Moving symbolic link %x to recycle bin</source> -<target>Flytter symbolsk lenke %x til papirkurv</target> - <source>Deleting file %x</source> <target>Sletter fil %x</target> @@ -157,15 +304,18 @@ <source>An exception occurred</source> <target>Et avvik har oppstÃ¥tt</target> -<source>Cannot find file %x.</source> -<target>Kan ikke finne filen %x.</target> - <source>Error</source> <target>Feil</target> <source>File %x does not contain a valid configuration.</source> <target>Filen %x inneholder en ugyldig innstilling.</target> +<source>Warning</source> +<target>Advarsel</target> + +<source>Command line</source> +<target>Kommandolinje</target> + <source>A folder input field is empty.</source> <target>Et mappefelt er tomt.</target> @@ -304,15 +454,6 @@ <source>Total time:</source> <target>Total tid:</target> -<source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> -</source> -<target> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> -</target> - <source>%x MB</source> <target>%x MB</target> @@ -328,15 +469,6 @@ <source>Scanning:</source> <target>Skanner:</target> -<source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> -</source> -<target> -<pluralform>[1 TrÃ¥d]</pluralform> -<pluralform>[%x TrÃ¥der]</pluralform> -</target> - <source>Encoding extended time information: %x</source> <target>Koder utvided tidsinformasjon: %x</target> @@ -355,18 +487,12 @@ <source>Browse directory</source> <target>Utforsk mappe</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Kan ikke fÃ¥ adgang til Volume Shadow Copy Service.</target> - <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>Bruk FreeFileSync 64-bit-versjon til Ã¥ opprette skyggekopier pÃ¥ dette systemet.</target> <source>Cannot load file %x.</source> <target>Kan ikke laste filen %x.</target> -<source>Volume name %x not part of file name %y.</source> -<target>Volumnavn %x ikke del av filnavn %y.</target> - <source>Abort requested: Waiting for current operation to finish...</source> <target>Handling avbrutt: Venter pÃ¥ at nÃ¥værende handling fullføres...</target> @@ -433,9 +559,6 @@ <source>Idle time between last detected change and execution of command</source> <target>Inaktiv tid mellom forrige endring og utførelse av kommando</target> -<source>Command line</source> -<target>Kommandolinje</target> - <source> The command is triggered if: - files or subfolders change @@ -459,9 +582,6 @@ Kommandoen utløses hvis: <source>RealtimeSync - Automated Synchronization</source> <target>RealtimeSync - Automatisk synkronisering</target> -<source>Warning</source> -<target>Advarsel</target> - <source>Build: %x</source> <target>Build: %x</target> @@ -477,9 +597,6 @@ Kommandoen utløses hvis: <source>&Exit</source> <target>&Avslutt</target> -<source>Waiting for missing directories...</source> -<target>Venter pÃ¥ manglende mapper...</target> - <source>Invalid command line:</source> <target>Ugyldig kommando:</target> @@ -489,14 +606,14 @@ Kommandoen utløses hvis: <source>File time and size</source> <target>Filtid og størrelse</target> -<source> Two way </source> -<target> Toveis </target> +<source>Two way</source> +<target>Toveis</target> <source>Mirror</source> -<target>Speile </target> +<target>Speile</target> <source>Update</source> -<target>Oppdatere </target> +<target>Oppdatere</target> <source>Custom</source> <target>Brukerdefinert</target> @@ -552,12 +669,6 @@ Kommandoen utløses hvis: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>De følgende elementene har uoppklarte konflikter og vil ikke bli synkroniserte:</target> -<source>Significant difference detected:</source> -<target>Betydelig forskjell oppdaget:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>Mer enn 50% av det totale antall filer blir kopiert eller slettet.</target> - <source>Not enough free disk space available in:</source> <target>Ikke nok ledig diskplass tilgjengelig pÃ¥:</target> @@ -708,8 +819,8 @@ Kommandoen utløses hvis: <source>&Export file list...</source> <target>&Eksporter filliste...</target> -<source>&Global settings...</source> -<target>&Felles innstillinger...</target> +<source>&Global settings</source> +<target>&Felles innstillinger</target> <source>Compare</source> <target>Sammenlign</target> @@ -777,6 +888,12 @@ Kommandoen utløses hvis: <source>&Pause</source> <target>&Pause</target> +<source>Variant</source> +<target>Variant</target> + +<source>Statistics</source> +<target>Statistikk</target> + <source> Files are found equal if - last write time and date @@ -843,12 +960,6 @@ er det samme <source>Delete or overwrite files permanently</source> <target>Slett eller overskriv filer permanent</target> -<source>Recycle Bin</source> -<target>Papirkurv</target> - -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Bruk papirkurv for slettede og overskrevne filer</target> - <source>Versioning</source> <target>VersjonshÃ¥ndtering</target> @@ -858,9 +969,6 @@ er det samme <source>Batch job</source> <target>Batch-jobb</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Lag en batch-fil for Ã¥ automatisere synkronisering. Dobbelklikk denne filen eller legg til i ditt systems planlegger: FreFileSync.exe <job name>.ffs_batch</target> - <source>Exit</source> <target>Avslutt</target> @@ -912,15 +1020,6 @@ er det samme <source>Delete on both sides even if the file is selected on one side only</source> <target>Slett pÃ¥ begge sider selv om filen bare er valgt pÃ¥ en side</target> -<source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. -</source> -<target> -Synkroniserer kun filer som passer til alle filterinnstillinger. -Merk: Filnavn mÃ¥ være relative til basismapper. -</target> - <source>Include</source> <target>Inkluder</target> @@ -945,21 +1044,12 @@ Merk: Filnavn mÃ¥ være relative til basismapper. <source>Fail-safe file copy</source> <target>Trygg filkopi</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>Skriv til en midlertidig fil (*.ffs_tmp) først sÃ¥ endre navn pÃ¥ den. Dette garanterer en konsistent tilstand selv ved alvorlige feil.</target> - <source>Copy locked files</source> <target>Kopier lÃ¥ste filer</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Kopier delte eller lÃ¥ste filer ved Ã¥ bruke Volume Shadow Copy Service (Krever administratorrettigheter)</target> - <source>Copy file access permissions</source> <target>Kopier filadgangstillatelser</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Overfør tilgangspreferanser for filer og mapper (krever administratortilgang)</target> - <source>Restore hidden dialogs</source> <target>Gjenopprett skjulte dialoger</target> @@ -972,15 +1062,6 @@ Merk: Filnavn mÃ¥ være relative til basismapper. <source>&Default</source> <target>&Standard</target> -<source>Variant</source> -<target>Variant</target> - -<source>Statistics</source> -<target>Statistikk</target> - -<source>Don't show this dialog again</source> -<target>Ikke vis dette vinduet igjen</target> - <source>Find what:</source> <target>Søk hva:</target> @@ -990,15 +1071,15 @@ Merk: Filnavn mÃ¥ være relative til basismapper. <source>&Find next</source> <target>&Søk neste</target> +<source>Start synchronization</source> +<target>Start synkronisering</target> + <source>Delete</source> <target>Slett</target> <source>Configure filter</source> <target>Still inn filter</target> -<source>Start synchronization</source> -<target>Start synkronisering</target> - <source>Find</source> <target>Søk</target> @@ -1059,12 +1140,12 @@ Merk: Filnavn mÃ¥ være relative til basismapper. <source>Include temporarily</source> <target>Inkluder midlertidig</target> -<source>Exclude via filter:</source> -<target>Ekskluder via filter:</target> - <source>multiple selection</source> <target>flervalg</target> +<source>Exclude via filter:</source> +<target>Ekskluder via filter:</target> + <source>Include all</source> <target>Inkluder alle</target> @@ -1110,9 +1191,6 @@ Merk: Filnavn mÃ¥ være relative til basismapper. <source>Do&n't save</source> <target>&Ikke lagre</target> -<source>Never save changes</source> -<target>Aldri lagre endringer</target> - <source>Show files that exist on left side only</source> <target>Vis filer som bare finnes pÃ¥ venstre side</target> @@ -1164,15 +1242,9 @@ Merk: Filnavn mÃ¥ være relative til basismapper. <source>All folders are in sync</source> <target>Alle mapper er synkroniserte</target> -<source>Comma separated list</source> -<target>Komma-separert liste</target> - <source>File list exported</source> <target>Filliste eksportert</target> -<source>Ignore further errors</source> -<target>Ignorer ytterligere feil</target> - <source>&Ignore</source> <target>&Ignorer</target> @@ -1212,15 +1284,6 @@ Merk: Filnavn mÃ¥ være relative til basismapper. <source>Completed</source> <target>Fullført</target> -<source>Continue</source> -<target>Fortsett</target> - -<source>Pause</source> -<target>Pause</target> - -<source>Logging</source> -<target>Logging</target> - <source>Cannot find %x</source> <target>Kan ikke finne %x</target> @@ -1293,9 +1356,6 @@ Merk: Filnavn mÃ¥ være relative til basismapper. <source>Append a timestamp to each file name</source> <target>Legg til et tidsstempel til hvert filnavn</target> -<source>Folder</source> -<target>Mappe</target> - <source>File</source> <target>Fil</target> @@ -1407,9 +1467,6 @@ Merk: Filnavn mÃ¥ være relative til basismapper. <source>Cannot change process I/O priorities.</source> <target>Kan ikke endre I/O prioriet pÃ¥ prosess</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>Ikke i stand til Ã¥ flytte %x til papirkurven.</target> - <source>Error Code %x:</source> <target>Feil kode %x:</target> diff --git a/BUILD/Languages/polish.lng b/BUILD/Languages/polish.lng index 78b97d59..8e0ead7f 100644 --- a/BUILD/Languages/polish.lng +++ b/BUILD/Languages/polish.lng @@ -7,7 +7,7 @@ <plural_definition>n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2</plural_definition> </header> -<source>Retrying operation after error:</source> +<source>Close search bar</source> <target></target> <source>Both sides have changed since last synchronization.</source> @@ -28,13 +28,13 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Sprawdzanie dostÄ™pnoÅ›ci kosza dla katalogu %x...</target> -<source>Moving file %x to recycle bin</source> +<source>Moving file %x to the recycle bin</source> <target>Przenoszenie pliku %x do kosza</target> -<source>Moving folder %x to recycle bin</source> +<source>Moving folder %x to the recycle bin</source> <target>Przenoszenie katalogu %x do kosza</target> -<source>Moving symbolic link %x to recycle bin</source> +<source>Moving symbolic link %x to the recycle bin</source> <target>Przenoszenie dowiÄ…zania symbolicznego %x do kosza</target> <source>Deleting file %x</source> @@ -46,14 +46,20 @@ <source>Deleting symbolic link %x</source> <target>Usuwanie dowiÄ…zania symbolicznego %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>Kosz systemowy nie jest dostÄ™pny dla podanych katalogów. Katalogi zostanÄ… usuniÄ™te permanentnie:</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>Dla nastÄ™pujÄ…cych katalogów kosz nie jest dostÄ™pny. Pliki zostanÄ… usuniÄ™te bez możliwoÅ›ci ich przywrócenia:</target> <source>An exception occurred</source> <target>WystÄ…piÅ‚ wyjÄ…tek</target> -<source>Cannot find file %x.</source> -<target>Nie można znaleźć pliku %x.</target> +<source>A directory path is expected after %x.</source> +<target>Za %x oczekiwana jest Å›cieżka katalogu.</target> + +<source>Syntax error</source> +<target>BÅ‚Ä…d skÅ‚adni</target> + +<source>Cannot open file %x.</source> +<target>Nie można otworzyć pliku %x.</target> <source>Error</source> <target>BÅ‚Ä…d</target> @@ -61,6 +67,36 @@ <source>File %x does not contain a valid configuration.</source> <target>Plik %x nie zawiera prawidÅ‚owej konfiguracji</target> +<source>Unequal number of left and right directories specified.</source> +<target>Wprowadzona liczba katalogów do synchronizacji jest nierówna.</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>Plik konfiguracyjny nie może zawierać informacji o synchronizowanych katalogach gdy nazwy Å›cieżek przekazywane sÄ… w linii poleceÅ„.</target> + +<source>Warning</source> +<target>Ostrzeżenie</target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target>Dla wiÄ™cej niż jednego pliku konfiguracyjnego, nie można ustawić wielu katalogów.</target> + +<source>Syntax:</source> +<target>SkÅ‚adnia:</target> + +<source>config files</source> +<target>pliki konfiguracyjne</target> + +<source>directory</source> +<target>katalog</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>Dowolna ilość plików konfiguracyjnych FreeFileSync .ffs_gui/.ffs_batch.</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>Dowolna liczba katalogów w przypadku użycia jednego pliku konfiguracyjnego.</target> + +<source>Command line</source> +<target>Linia komend</target> + <source>A folder input field is empty.</source> <target>Pole katalog źródÅ‚owy jest puste.</target> @@ -219,13 +255,13 @@ <target>CaÅ‚kowity czas:</target> <source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </source> <target> -<pluralform>1 Bajt</pluralform> -<pluralform>%x Bajty</pluralform> -<pluralform>%x Bajtów</pluralform> +<pluralform>1 bajt</pluralform> +<pluralform>%x bajty</pluralform> +<pluralform>%x bajtów</pluralform> </target> <source>%x MB</source> @@ -247,13 +283,13 @@ <target>Skanowanie:</target> <source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </source> <target> -<pluralform>[1 WÄ…tek]</pluralform> -<pluralform>[%x WÄ…tki]</pluralform> -<pluralform>[%x WÄ…tków]</pluralform> +<pluralform>1 wÄ…tek</pluralform> +<pluralform>%x wÄ…tki</pluralform> +<pluralform>%x wÄ…tków</pluralform> </target> <source>Encoding extended time information: %x</source> @@ -262,6 +298,9 @@ <source>/sec</source> <target>/sekundÄ™</target> +<source>%x items</source> +<target>%x elementy</target> + <source>Configuration file %x loaded partially only.</source> <target>Plik konfiguracyjny %x zostaÅ‚ wczytany tylko częściowo.</target> @@ -274,7 +313,7 @@ <source>Browse directory</source> <target>PrzeglÄ…daj katalog</target> -<source>Cannot access Volume Shadow Copy Service.</source> +<source>Cannot access the Volume Shadow Copy Service.</source> <target>Nie można uzyskać dostÄ™pu do usÅ‚ugi Volume Shadow Copy.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> @@ -286,8 +325,8 @@ <source>Cannot determine volume name for %x.</source> <target>Nie można okreÅ›lić nazwy dysku dla %x.</target> -<source>Volume name %x not part of file name %y.</source> -<target>Dysk %x nie jest częściÄ… pliku %y.</target> +<source>Volume name %x is not part of file path %y.</source> +<target>Nazwa zasobu %x ni jest częściÄ… Å›cieżki %y.</target> <source>Abort requested: Waiting for current operation to finish...</source> <target>Żądanie przerwania: Oczekiwanie na koniec aktualnie wykonywanego zadania...</target> @@ -355,9 +394,6 @@ <source>Idle time between last detected change and execution of command</source> <target>Czas pomiÄ™dzy ostatniÄ… wykrytÄ… zmianÄ…, a uruchomieniem komendy</target> -<source>Command line</source> -<target>Linia komend</target> - <source> The command is triggered if: - files or subfolders change @@ -381,9 +417,6 @@ Komenda jest wykonywana gdy: <source>RealtimeSync - Automated Synchronization</source> <target>RealtimeSync - Automatyczna Synchronizacja</target> -<source>Warning</source> -<target>Ostrzeżenie</target> - <source>Build: %x</source> <target>Zbudowano: %x</target> @@ -393,15 +426,21 @@ Komenda jest wykonywana gdy: <source>All files</source> <target>Wszystkie pliki</target> +<source>Directory monitoring active</source> +<target>Monitorowanie katalogów aktywne</target> + +<source>Waiting until all directories are available...</source> +<target>Oczekiwanie na dostÄ™pność wszystkich katalogów...</target> + <source>&Restore</source> <target>&Przywróć</target> +<source>&Show error</source> +<target>Pokaż &bÅ‚Ä™dy</target> + <source>&Exit</source> <target>&WyjÅ›cie</target> -<source>Waiting for missing directories...</source> -<target>Oczekiwanie na brakujÄ…ce katalogi...</target> - <source>Invalid command line:</source> <target>NieprawidÅ‚owa komenda:</target> @@ -411,14 +450,14 @@ Komenda jest wykonywana gdy: <source>File time and size</source> <target>Czas modyfikacji i rozmiar</target> -<source> Two way </source> -<target> Obustronna </target> +<source>Two way</source> +<target>Obustronna</target> <source>Mirror</source> -<target>Lustrzana </target> +<target>Lustrzana</target> <source>Update</source> -<target>Uaktualnij </target> +<target>Uaktualnij</target> <source>Custom</source> <target>WÅ‚asne</target> @@ -474,11 +513,8 @@ Komenda jest wykonywana gdy: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>Te elementy znajdujÄ… siÄ™ w konflikcie, którego nie można rozwiÄ…zać. Pliki nie zostanÄ… zsynchronizowane:</target> -<source>Significant difference detected:</source> -<target>Wykryto znaczÄ…ce zmiany:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>Ponad 50% plików zostanie skopiowanych lub usuniÄ™tych.</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>Poniższe katalogi znacznie siÄ™ różniÄ…. Upewnij siÄ™, że okreÅ›lone zostaÅ‚y prawiÅ‚owe katalogi.</target> <source>Not enough free disk space available in:</source> <target>Brak wystarczajÄ…cej przestrzeni dyskowej na:</target> @@ -498,12 +534,15 @@ Komenda jest wykonywana gdy: <source>Generating database...</source> <target>Generowanie bazy danych...</target> -<source>Creating Volume Shadow Copy for %x...</source> +<source>Creating a Volume Shadow Copy for %x...</source> <target>Tworzenie Volume Shadow Copy dla %x...</target> <source>Data verification error: %x and %y have different content.</source> <target>NastÄ…piÅ‚ bÅ‚Ä…d weryfikacji: %x oraz %y różniÄ… siÄ™ zawartoÅ›ciÄ….</target> +<source>job name</source> +<target>nazwa zadania</target> + <source>Synchronization aborted</source> <target>Synchronizacja przerwana</target> @@ -528,6 +567,9 @@ Komenda jest wykonywana gdy: <source>Switching to FreeFileSync main dialog</source> <target>PrzeÅ‚Ä…czanie do głównego okna FreeFileSync</target> +<source>Retrying operation after error:</source> +<target>Ponawianie czynnoÅ›ci po bÅ‚Ä™dzie:</target> + <source>A new version of FreeFileSync is available:</source> <target>DostÄ™pna jest nowa wersja FreeFileSync:</target> @@ -651,8 +693,8 @@ Komenda jest wykonywana gdy: <source>&Export file list...</source> <target>&Eksportuj listÄ™ plików...</target> -<source>&Global settings...</source> -<target>&Ustawienia programu...</target> +<source>&Global settings</source> +<target>&Ustawienia programu</target> <source>&Tools</source> <target>&NarzÄ™dzia</target> @@ -669,12 +711,6 @@ Komenda jest wykonywana gdy: <source>Compare</source> <target>Porównaj</target> -<source>Comparison settings</source> -<target>Ustawienia porównywania</target> - -<source>Synchronization settings</source> -<target>Ustawienia synchronizacji</target> - <source>Synchronize</source> <target>Synchronizuj</target> @@ -687,6 +723,12 @@ Komenda jest wykonywana gdy: <source>Swap sides</source> <target>ZamieÅ„ stronami</target> +<source>Find what:</source> +<target>Co:</target> + +<source>Match case</source> +<target>UwzglÄ™dnij wielkość liter</target> + <source>Save as batch job</source> <target>Zapisz w trybie wsadowym</target> @@ -723,6 +765,9 @@ Komenda jest wykonywana gdy: <source>Synchronizing...</source> <target>SynchronizujÄ™...</target> +<source>Minimize to notification area</source> +<target>Minimalizuj do obszaru powiadomiÅ„</target> + <source>On completion</source> <target>Po zakoÅ„czeniu</target> @@ -732,6 +777,15 @@ Komenda jest wykonywana gdy: <source>&Pause</source> <target>&Pauza</target> +<source>Variant</source> +<target>Wariant</target> + +<source>Statistics</source> +<target>Statystyki</target> + +<source>&Don't show this dialog again</source> +<target>&Nie pokazuj wiÄ™cej tego okna</target> + <source>Select a variant</source> <target>OkreÅ›l wariant</target> @@ -780,6 +834,12 @@ jest identyczna <source>Configure your own synchronization rules.</source> <target>Skonfiguruj swoje wÅ‚asne reguÅ‚y synchronizacji.</target> +<source>Detect moved files</source> +<target>Wykryj przeniesione pliki.</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Wymaga plików bazy danych. Nie wspierane przez wszystkie systemy plików.</target> + <source>Error handling</source> <target>ObsÅ‚uga bÅ‚Ä™dów</target> @@ -804,17 +864,17 @@ jest identyczna <source>Delete or overwrite files permanently</source> <target>UsuÅ„ lub nadpisz pliki na staÅ‚e</target> -<source>Recycle Bin</source> +<source>Recycle bin</source> <target>Kosz</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Użyj Kosza dla plików usuwanych i nadpisywanych</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Przechowuj pliki, które zostaÅ‚y usuniÄ™te lub nadpisane w koszu.</target> <source>Versioning</source> <target>Wersjonowanie</target> -<source>Move files to user-defined folder</source> -<target>PrzenieÅ› pliki do katalogu wskazanego przez użytkownika</target> +<source>Move files to a user-defined folder</source> +<target>PrzenieÅ› pliki do katalogu zdefiniowanego przez użytkownika</target> <source>Naming convention:</source> <target>Konwencja nazewnictwa:</target> @@ -822,8 +882,8 @@ jest identyczna <source>Batch job</source> <target>Plik wsadowy</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Utwórz plik wsadowy aby zautomatyzować proces synchronizacji. Kliknij dwa razy na ten plik lub dodaj go do menadżera zadaÅ„ w Twoim systemie: FreeFileSync.exe <nazwa_pliku>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Utwórz plik wsadowy do zautomatyzowania procesu synchronizacji. Aby rozpocząć, klknij dwa razy plik lub zaplanuj zadanie w: %x</target> <source>Exit</source> <target>WyjÅ›cie</target> @@ -846,30 +906,6 @@ jest identyczna <source>Limit maximum number of log files</source> <target>OkreÅ›l maksymalnÄ… liczbÄ™ plików z logami</target> -<source>Source code written in C++ using:</source> -<target>Kod stworzony w C++ z wykorzystaniem:</target> - -<source>If you like FreeFileSync</source> -<target>Podoba Ci siÄ™ FreeFileSync?</target> - -<source>Donate with PayPal</source> -<target>Wesprzyj z PayPal</target> - -<source>Many thanks for localization:</source> -<target>PodziÄ™kowania za tÅ‚umaczenia:</target> - -<source>Feedback and suggestions are welcome</source> -<target>Wszelkie opinie i sugestie mile widziane</target> - -<source>Homepage</source> -<target>Strona domowa</target> - -<source>Email</source> -<target>Poczta</target> - -<source>Published under the GNU General Public License</source> -<target>UdostÄ™pnione na zasadach licencji GNU General Public License</target> - <source>Delete on both sides</source> <target>UsuÅ„ po obu stronach</target> @@ -877,12 +913,12 @@ jest identyczna <target>UsuÅ„ po obu stronach nawet jeżeli plik zaznaczony jest tylko po jednej stronie</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -Tylko pliki pasujÄ…ce do wszystkich filtrów bÄ™dÄ… synchronizowane. -Uwaga: Nazwy plików muszÄ… być podane jako relatywne wzglÄ™dem katalogu bazowego. +Pliki zostanÄ… zsynchronizowane tylko w przypadku przejÅ›cia przez wszystkie regóły filtra. +Uwaga: Åšcieżki plików muszÄ… być wzglÄ™dne do katalogów bazowych. </target> <source>Include</source> @@ -912,20 +948,20 @@ Uwaga: Nazwy plików muszÄ… być podane jako relatywne wzglÄ™dem katalogu bazowe <source>Fail-safe file copy</source> <target>Bezpieczne kopiowanie</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>Stwórz tymczasowy plik (*.ffs_tmp) nastÄ™pnie zamieÅ„ jego nazwÄ™. Gwarantuje to spójność nawet po wystÄ…pieniu bÅ‚Ä™du.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>Aby zagwarantować spójność synchronizacji nawet podczas bÅ‚Ä™du, program kopiuje zawartość do pliku tymczasowego (*.ffs_tmp) po czym zmienia nazwÄ™ pliku na docelowÄ….</target> <source>Copy locked files</source> <target>Kopiuj zablokowane pliki</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Kopiuj udostÄ™pnione lub zablokowane pliki używajÄ…c usÅ‚ugi Volume Shadow Copy (Wymaga uprawnieÅ„ administratora)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>Kopiuj współdzielone lub zablokowane pliki używajÄ…c Volume Shadow Copy Service (wymaga uprawnieÅ„ administratora)</target> <source>Copy file access permissions</source> <target>Kopiuj uprawnienia plików</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Kopiuj uprawnienia plików i katalogów (Wymaga uprawnieÅ„ Administratora)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>Kopiuj uprawnienia plików i katalogów (wymaga uprawnieÅ„ administratora)</target> <source>Restore hidden dialogs</source> <target>Przywróc ukryte dialogi</target> @@ -939,35 +975,44 @@ Uwaga: Nazwy plików muszÄ… być podane jako relatywne wzglÄ™dem katalogu bazowe <source>&Default</source> <target>&DomyÅ›lne</target> -<source>Variant</source> -<target>Wariant</target> +<source>Source code written in C++ using:</source> +<target>Kod stworzony w C++ z wykorzystaniem:</target> -<source>Statistics</source> -<target>Statystyki</target> +<source>If you like FreeFileSync</source> +<target>Podoba Ci siÄ™ FreeFileSync?</target> -<source>Don't show this dialog again</source> -<target>Nie pokazuj wiÄ™cej tego okna</target> +<source>Donate with PayPal</source> +<target>Wesprzyj z PayPal</target> -<source>Find what:</source> -<target>Co:</target> +<source>Feedback and suggestions are welcome</source> +<target>Wszelkie opinie i sugestie mile widziane</target> -<source>Match case</source> -<target>UwzglÄ™dnij wielkość liter</target> +<source>Homepage</source> +<target>Strona domowa</target> -<source>&Find next</source> -<target>&Znajdź nastÄ™pny</target> +<source>Email</source> +<target>Poczta</target> -<source>Delete</source> -<target>UsuÅ„</target> +<source>Published under the GNU General Public License</source> +<target>UdostÄ™pnione na zasadach licencji GNU General Public License</target> -<source>Configure filter</source> -<target>Konfiguruj filtr</target> +<source>Many thanks for localization:</source> +<target>PodziÄ™kowania za tÅ‚umaczenia:</target> <source>Start synchronization</source> <target>Rozpocznij synchronizacjÄ™</target> -<source>Find</source> -<target>Znajdź</target> +<source>Comparison settings</source> +<target>Ustawienia porównywania</target> + +<source>Synchronization settings</source> +<target>Ustawienia synchronizacji</target> + +<source>Delete</source> +<target>UsuÅ„</target> + +<source>Configure filter</source> +<target>Konfiguruj filtr</target> <source>Select time span</source> <target>OkreÅ›l przedziaÅ‚ czasowy</target> @@ -975,6 +1020,9 @@ Uwaga: Nazwy plików muszÄ… być podane jako relatywne wzglÄ™dem katalogu bazowe <source>Folder pairs</source> <target>Pary folderów</target> +<source>Find</source> +<target>Znajdź</target> + <source>Overview</source> <target>PrzeglÄ…d</target> @@ -1000,6 +1048,22 @@ Uwaga: Nazwy plików muszÄ… być podane jako relatywne wzglÄ™dem katalogu bazowe <target>Porównaj foldery</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>Czy na pewno chcesz wykonać polecenie %y dla 1 elementu?</pluralform> +<pluralform>Czy na pewno chcesz wykonać polecenie %y dla %x elementów?</pluralform> +<pluralform>Czy na pewno chcesz wykonać polecenie %y dla %x elementów?</pluralform> +</target> + +<source>Confirm</source> +<target>Potwierdź</target> + +<source>&Execute</source> +<target>&Wykonaj</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1032,17 +1096,20 @@ Uwaga: Nazwy plików muszÄ… być podane jako relatywne wzglÄ™dem katalogu bazowe <source>Set direction:</source> <target>Kierunek synchronizacji:</target> -<source>Exclude temporarily</source> -<target>Wyklucz tymczasowo</target> +<source>multiple selection</source> +<target>zaznaczone elementy</target> -<source>Include temporarily</source> -<target>DoÅ‚Ä…cz tymczasowo</target> +<source>Include via filter:</source> +<target>Dodaj pliki:</target> <source>Exclude via filter:</source> <target>Dodaj filtr:</target> -<source>multiple selection</source> -<target>zaznaczone elementy</target> +<source>Exclude temporarily</source> +<target>Wyklucz tymczasowo</target> + +<source>Include temporarily</source> +<target>DoÅ‚Ä…cz tymczasowo</target> <source>Include all</source> <target>Zaznacz wszystko</target> @@ -1089,8 +1156,8 @@ Uwaga: Nazwy plików muszÄ… być podane jako relatywne wzglÄ™dem katalogu bazowe <source>Do&n't save</source> <target>&Nie zapisuj</target> -<source>Never save changes</source> -<target>Nigdy nie zapisuj zmian</target> +<source>Never save &changes</source> +<target>Nigdy nie zapisuj &zmian</target> <source>Show files that exist on left side only</source> <target>Pokaż pliki istniejÄ…ce tylko po lewej stronie</target> @@ -1143,8 +1210,11 @@ Uwaga: Nazwy plików muszÄ… być podane jako relatywne wzglÄ™dem katalogu bazowe <source>All folders are in sync</source> <target>Wszystkie katalogi sÄ… zsynchronizowane</target> -<source>Comma separated list</source> -<target>Lista oddzielona przecinkami</target> +<source>Cannot find %x</source> +<target>Nie można znaleźć %x</target> + +<source>Comma-separated values</source> +<target>WartoÅ›ci rozdzielone przecinkiem</target> <source>File list exported</source> <target>Lista plików wyeksportowana</target> @@ -1152,8 +1222,8 @@ Uwaga: Nazwy plików muszÄ… być podane jako relatywne wzglÄ™dem katalogu bazowe <source>Searching for program updates...</source> <target>Wyszukiwanie aktualizacji...</target> -<source>Ignore further errors</source> -<target>Ignoruj kolejne bÅ‚Ä™dy</target> +<source>&Ignore subsequent errors</source> +<target>&Ignoruj kolejne bÅ‚Ä™dy</target> <source>&Ignore</source> <target>&Ignoruj</target> @@ -1161,8 +1231,8 @@ Uwaga: Nazwy plików muszÄ… być podane jako relatywne wzglÄ™dem katalogu bazowe <source>Fatal Error</source> <target>BÅ‚Ä…d krytyczny</target> -<source>Don't show this warning again</source> -<target>Nie pokazuj wiÄ™cej tego ostrzeżenia</target> +<source>&Don't show this warning again</source> +<target>&Nie pokazuj ponownie tego ostrzeżenia</target> <source>&Switch</source> <target>&ZamieÅ„</target> @@ -1197,17 +1267,11 @@ Uwaga: Nazwy plików muszÄ… być podane jako relatywne wzglÄ™dem katalogu bazowe <source>Completed</source> <target>ZakoÅ„czono</target> -<source>Continue</source> -<target>Kontynuuj</target> - -<source>Pause</source> -<target>Pauza</target> +<source>&Continue</source> +<target>&Kontynuuj</target> -<source>Logging</source> -<target>Tworzenie logów</target> - -<source>Cannot find %x</source> -<target>Nie można znaleźć %x</target> +<source>Log</source> +<target>Log</target> <source>Inactive</source> <target>Nieaktywny</target> @@ -1240,13 +1304,13 @@ Uwaga: Nazwy plików muszÄ… być podane jako relatywne wzglÄ™dem katalogu bazowe <target>Filtr</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>Czy na pewno chcesz przenieść do kosza nastÄ™pujÄ…cy element?</pluralform> -<pluralform>Czy na pewno chcesz przenieść do kosza %x nastÄ™pujÄ…ce elementy?</pluralform> -<pluralform>Czy na pewno chcesz przenieść do kosza %x nastÄ™pujÄ…cych elementów?</pluralform> +<pluralform>Czy na pewno chcesz przenieść ten element do kosza?</pluralform> +<pluralform>Czy na pewno chcesz przenieść te %x elementy do kosza?</pluralform> +<pluralform>Czy na pewno chcesz przenieść te %x elemntów do kosza?</pluralform> </target> <source> @@ -1301,9 +1365,6 @@ Uwaga: Nazwy plików muszÄ… być podane jako relatywne wzglÄ™dem katalogu bazowe <source>Append a timestamp to each file name</source> <target>DoÅ‚Ä…cz znacznik czasu do nazwy każdego pliku</target> -<source>Folder</source> -<target>Katalog</target> - <source>File</source> <target>Plik</target> @@ -1427,7 +1488,7 @@ Uwaga: Nazwy plików muszÄ… być podane jako relatywne wzglÄ™dem katalogu bazowe <source>Cannot change process I/O priorities.</source> <target>Nie można zmienić priorytetu I/O procesu.</target> -<source>Unable to move %x to the Recycle Bin.</source> +<source>Unable to move %x to the recycle bin.</source> <target>Nie można przenieść %x do kosza.</target> <source>Cannot determine final path for %x.</source> diff --git a/BUILD/Languages/portuguese.lng b/BUILD/Languages/portuguese.lng index e7529706..5557ada4 100644 --- a/BUILD/Languages/portuguese.lng +++ b/BUILD/Languages/portuguese.lng @@ -7,9 +7,6 @@ <plural_definition>n == 1 ? 0 : 1</plural_definition> </header> -<source>Retrying operation after error:</source> -<target></target> - <source>Both sides have changed since last synchronization.</source> <target>Ambos os lados tiveram alterações desde a última sincronização.</target> @@ -28,14 +25,14 @@ <source>Checking recycle bin availability for folder %x...</source> <target>A verificar a disponibilidade da reciclagem para a pasta %x...</target> -<source>Moving file %x to recycle bin</source> -<target>Mover ficheiro %x para a Reciclagem</target> +<source>Moving file %x to the recycle bin</source> +<target>Mover ficheiro %x para a reciclagem</target> -<source>Moving folder %x to recycle bin</source> -<target>Mover pasta %x para a Reciclagem</target> +<source>Moving folder %x to the recycle bin</source> +<target>Mover pasta %x para a reciclagem</target> -<source>Moving symbolic link %x to recycle bin</source> -<target>Mover link simbólico %x para a Reciclagem</target> +<source>Moving symbolic link %x to the recycle bin</source> +<target>Mover link simbólico %x para a reciclagem</target> <source>Deleting file %x</source> <target>Eliminar ficheiro %x</target> @@ -46,14 +43,20 @@ <source>Deleting symbolic link %x</source> <target>Eliminar link simbólico %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>A Reciclagem não está disponÃvel para as seguintes pastas. Os ficheiros serão eliminados permanentemente:</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>A reciclagem não está disponÃvel para as seguintes pastas. Os ficheiros serão, em alternativa, eliminados permanentemente:</target> <source>An exception occurred</source> <target>Ocorreu uma excepção</target> -<source>Cannot find file %x.</source> -<target>Não é possÃvel encontrar o ficheiro %x.</target> +<source>A directory path is expected after %x.</source> +<target>É esperado um caminho de directório após %x.</target> + +<source>Syntax error</source> +<target>Erro de sintaxe</target> + +<source>Cannot open file %x.</source> +<target>Não é possÃvel abrir o ficheiro %x.</target> <source>Error</source> <target>Erro</target> @@ -61,6 +64,36 @@ <source>File %x does not contain a valid configuration.</source> <target>Ficheiro %x não tem uma configuração válida.</target> +<source>Unequal number of left and right directories specified.</source> +<target>Número desigual de directórios à esquerda e à direita.</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>O ficheiro de configuração não deve conter configurações ao nÃvel de par-directório quando os directórios são definidos pela linha de comandos.</target> + +<source>Warning</source> +<target>Atenção</target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target>Os directórios não podem ser definidos em mais do que um ficheiro de configuração.</target> + +<source>Syntax:</source> +<target>Sintaxe:</target> + +<source>config files</source> +<target>ficheiros de configuração</target> + +<source>directory</source> +<target>directório</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>Qualquer número de ficheiros de configuração .ffs_gui e/ou .ffs_batch do FreeFileSync.</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>Qualquer número de directórios alternativos para apenas um ficheiro de configuração.</target> + +<source>Command line</source> +<target>Linha de comandos</target> + <source>A folder input field is empty.</source> <target>Um dos campos de directório para comparar está vazio.</target> @@ -218,12 +251,12 @@ <target>Tempo total:</target> <source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </source> <target> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </target> <source>%x MB</source> @@ -245,12 +278,12 @@ <target>A pesquisar:</target> <source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </source> <target> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </target> <source>Encoding extended time information: %x</source> @@ -259,6 +292,9 @@ <source>/sec</source> <target>/seg</target> +<source>%x items</source> +<target>%x itens</target> + <source>Configuration file %x loaded partially only.</source> <target>Ficheiro de configuração %x carregado parcialmente.</target> @@ -271,7 +307,7 @@ <source>Browse directory</source> <target>Procurar directório</target> -<source>Cannot access Volume Shadow Copy Service.</source> +<source>Cannot access the Volume Shadow Copy Service.</source> <target>Não é possÃvel aceder ao serviço Volume Shadow Copy.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> @@ -283,8 +319,8 @@ <source>Cannot determine volume name for %x.</source> <target>Não é possÃvel determinar o nome do volume para %x.</target> -<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>Volume name %x is not part of file path %y.</source> +<target>Nome de volume %x não faz parte do caminho do ficheiro %y.</target> <source>Abort requested: Waiting for current operation to finish...</source> <target>Abortar pedido: À espera do fim da operação atual...</target> @@ -352,9 +388,6 @@ <source>Idle time between last detected change and execution of command</source> <target>Tempo de espera entre a última alteração detetada e a execução do comando</target> -<source>Command line</source> -<target>Linha de comandos</target> - <source> The command is triggered if: - files or subfolders change @@ -378,9 +411,6 @@ O comando é executado se: <source>RealtimeSync - Automated Synchronization</source> <target>RealtimeSync - Sincronização Automatizada</target> -<source>Warning</source> -<target>Atenção</target> - <source>Build: %x</source> <target>Build: %x</target> @@ -390,15 +420,21 @@ O comando é executado se: <source>All files</source> <target>Todos os ficheiros</target> +<source>Directory monitoring active</source> +<target>Monitorização de directório activa</target> + +<source>Waiting until all directories are available...</source> +<target>A aguardar que todos os directórios fiquem disponÃveis...</target> + <source>&Restore</source> <target>&Restaurar</target> +<source>&Show error</source> +<target>Mostrar &erro</target> + <source>&Exit</source> <target>&Sair</target> -<source>Waiting for missing directories...</source> -<target>A aguardar pelos directórios em falta...</target> - <source>Invalid command line:</source> <target>Linha de comando inválida:</target> @@ -408,14 +444,14 @@ O comando é executado se: <source>File time and size</source> <target>Data e tamanho do ficheiro</target> -<source> Two way </source> -<target> Duas vias </target> +<source>Two way</source> +<target>Duas vias</target> <source>Mirror</source> -<target>Espelhar </target> +<target>Espelhar</target> <source>Update</source> -<target>Actualizar </target> +<target>Actualizar</target> <source>Custom</source> <target>Personalizado</target> @@ -471,11 +507,8 @@ O comando é executado se: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>Os seguintes itens têm conflitos não resolvidos, e não serão sincronizados:</target> -<source>Significant difference detected:</source> -<target>Diferença significativa detectada:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>Mais de 50% dos ficheiros vai ser copiado ou apagado.</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>As seguintes pastas são significativamente diferentes. Verifique se está a usar as pastas correctas na sincronização.</target> <source>Not enough free disk space available in:</source> <target>Não há espaço livre suficiente em:</target> @@ -495,12 +528,15 @@ O comando é executado se: <source>Generating database...</source> <target>A gerar base de dados...</target> -<source>Creating Volume Shadow Copy for %x...</source> +<source>Creating a Volume Shadow Copy for %x...</source> <target>A criar Volume Shadow Copy para %x...</target> <source>Data verification error: %x and %y have different content.</source> <target>Erro de verificação de dados: %x e %y têm conteúdo diferente.</target> +<source>job name</source> +<target>nome da tarefa</target> + <source>Synchronization aborted</source> <target>Sincronização abortada</target> @@ -525,6 +561,9 @@ O comando é executado se: <source>Switching to FreeFileSync main dialog</source> <target>A mudar para o diálogo principal do FreeFileSync</target> +<source>Retrying operation after error:</source> +<target>A tentar novamente a operação após erro:</target> + <source>A new version of FreeFileSync is available:</source> <target>Uma nova versão do FreeFileSync está disponÃvel:</target> @@ -648,8 +687,8 @@ O comando é executado se: <source>&Export file list...</source> <target>&Exportar lista de ficheiros...</target> -<source>&Global settings...</source> -<target>&Opções...</target> +<source>&Global settings</source> +<target>&Opções</target> <source>&Tools</source> <target>&Ferramentas</target> @@ -720,6 +759,9 @@ O comando é executado se: <source>Synchronizing...</source> <target>A sincronizar...</target> +<source>Minimize to notification area</source> +<target>Minimizar para a área de notificação</target> + <source>On completion</source> <target>Ao terminar</target> @@ -729,6 +771,15 @@ O comando é executado se: <source>&Pause</source> <target>&Pausa</target> +<source>Variant</source> +<target>Variável</target> + +<source>Statistics</source> +<target>EstatÃsticas</target> + +<source>&Don't show this dialog again</source> +<target>&Não mostrar este diálogo novamente</target> + <source>Select a variant</source> <target>Seleccione uma variante</target> @@ -776,6 +827,12 @@ Os ficheiros são considerados iguais se <source>Configure your own synchronization rules.</source> <target>Configure as suas regras de sincronização.</target> +<source>Detect moved files</source> +<target>Detectar ficheiros movidos</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Requer base de dados. Não é suportado por todos os sistemas de ficheiros.</target> + <source>Error handling</source> <target>Controlador de erros</target> @@ -800,17 +857,17 @@ Os ficheiros são considerados iguais se <source>Delete or overwrite files permanently</source> <target>Apagar ou substituir ficheiros permanentemente</target> -<source>Recycle Bin</source> +<source>Recycle bin</source> <target>Reciclagem</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Usar Reciclagem para ficheiros eliminados ou substituidos</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Fazer backup dos ficheiros apagados e substituidos na reciclagem</target> <source>Versioning</source> <target>Manter versões anteriores</target> -<source>Move files to user-defined folder</source> -<target>Mover ficheiros para directório definido pelo utilizador</target> +<source>Move files to a user-defined folder</source> +<target>Mover ficheiros para uma pasta definida pelo utilizador</target> <source>Naming convention:</source> <target>Convenção de nomes:</target> @@ -818,8 +875,8 @@ Os ficheiros são considerados iguais se <source>Batch job</source> <target>Ficheiro Batch</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Criar ficheiro batch para automatizar a sincronização. Faça duplo-clique no ficheiro ou adicione ao planeador de tarefas do sistema: FreeFileSync.exe <nome>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Criar ficheiro batch para sincronização automática. Para iniciar, fazer duplo clique no ficheiro ou acrescentar ao planeador de tarefas: %x</target> <source>Exit</source> <target>Sair</target> @@ -873,12 +930,12 @@ Os ficheiros são considerados iguais se <target>Eliminar em ambos os lados mesmo se o ficheiro só está seleccionado num lado</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -Apenas ficheiros que condigam com todos os filtros serão sincronizados. -Nota: Nome dos ficheiros tem que ser relativo aos diretórios base. +Os ficheiros só serão sincronizados se passarem todos os filtros. +Nota: O caminho dos ficheiros deve ser relativo ao directório raiz. </target> <source>Include</source> @@ -908,20 +965,20 @@ Nota: Nome dos ficheiros tem que ser relativo aos diretórios base. <source>Fail-safe file copy</source> <target>Cópia à prova de falhas</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>Escrever para um ficheiro temporário (*.ffs_tmp) primeiro e depois renomear. Isto garante consistência mesmo em caso de erro fatal.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>Copiar para um ficheiro temporário (*.ffs_tmp) e depois renomear. Isto garante consistência mesmo em caso de erro fatal.</target> <source>Copy locked files</source> <target>Copiar ficheiros bloqueados</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Copiar ficheiros partilhados ou bloqueados usando o serviço Volume Shadow Copy (Requer direitos de administrador)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>Copiar ficheiros partilhados ou bloqueados usando o serviço Volume Shadow Copy(necessita direitos de administrador)</target> <source>Copy file access permissions</source> <target>Copiar permissões de acesso do ficheiro</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Transferir ficheiro e permissões (precisa de direitos de Administrador)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>Transferir permissões de ficheiros e pastas (necessita direitos de administrador)</target> <source>Restore hidden dialogs</source> <target>Restaurar diálogos escondidos</target> @@ -935,15 +992,6 @@ Nota: Nome dos ficheiros tem que ser relativo aos diretórios base. <source>&Default</source> <target>&Config. Iniciais</target> -<source>Variant</source> -<target>Variável</target> - -<source>Statistics</source> -<target>EstatÃsticas</target> - -<source>Don't show this dialog again</source> -<target>Não mostrar este diálogo novamente</target> - <source>Find what:</source> <target>Procurar:</target> @@ -953,15 +1001,15 @@ Nota: Nome dos ficheiros tem que ser relativo aos diretórios base. <source>&Find next</source> <target>&Procurar seguinte</target> +<source>Start synchronization</source> +<target>Iniciar a sincronização</target> + <source>Delete</source> <target>Eliminar</target> <source>Configure filter</source> <target>Configurar filtros</target> -<source>Start synchronization</source> -<target>Iniciar a sincronização</target> - <source>Find</source> <target>Procurar</target> @@ -996,6 +1044,21 @@ Nota: Nome dos ficheiros tem que ser relativo aos diretórios base. <target>Comparar listas</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>Deseja mesmo executar o comando %y para 1 item?</pluralform> +<pluralform>Deseja mesmo executar o comando %y para %x itens?</pluralform> +</target> + +<source>Confirm</source> +<target>Confirmar</target> + +<source>&Execute</source> +<target>&Executar</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1031,12 +1094,15 @@ Nota: Nome dos ficheiros tem que ser relativo aos diretórios base. <source>Include temporarily</source> <target>Incluir temporariamente</target> -<source>Exclude via filter:</source> -<target>Excluir por filtro:</target> - <source>multiple selection</source> <target>seleção múltipla</target> +<source>Include via filter:</source> +<target>Incluir via filtro:</target> + +<source>Exclude via filter:</source> +<target>Excluir por filtro:</target> + <source>Include all</source> <target>Incluir tudo</target> @@ -1082,8 +1148,8 @@ Nota: Nome dos ficheiros tem que ser relativo aos diretórios base. <source>Do&n't save</source> <target>Não g&uardar</target> -<source>Never save changes</source> -<target>Nunca guardar alterações</target> +<source>Never save &changes</source> +<target>Nunca guardar &alterações</target> <source>Show files that exist on left side only</source> <target>Mostrar ficheiros existentes somente à esquerda</target> @@ -1136,8 +1202,8 @@ Nota: Nome dos ficheiros tem que ser relativo aos diretórios base. <source>All folders are in sync</source> <target>Todas as pastas estão sincronizadas</target> -<source>Comma separated list</source> -<target>Lista de itens separados por vÃrgulas</target> +<source>Comma-separated values</source> +<target>Valores separados por virgula</target> <source>File list exported</source> <target>Lista dos ficheiros exportada</target> @@ -1145,8 +1211,8 @@ Nota: Nome dos ficheiros tem que ser relativo aos diretórios base. <source>Searching for program updates...</source> <target>A procurar actualizações do programa...</target> -<source>Ignore further errors</source> -<target>Ignorar próximos erros</target> +<source>&Ignore subsequent errors</source> +<target>&Ignorar erros subsequentes</target> <source>&Ignore</source> <target>&Ignorar</target> @@ -1154,8 +1220,8 @@ Nota: Nome dos ficheiros tem que ser relativo aos diretórios base. <source>Fatal Error</source> <target>Erro crÃtico</target> -<source>Don't show this warning again</source> -<target>Não mostrar este aviso novamente</target> +<source>&Don't show this warning again</source> +<target>&Não mostrar este aviso novamente</target> <source>&Switch</source> <target>&Trocar</target> @@ -1190,14 +1256,11 @@ Nota: Nome dos ficheiros tem que ser relativo aos diretórios base. <source>Completed</source> <target>Terminado</target> -<source>Continue</source> -<target>Continuar</target> +<source>&Continue</source> +<target>&Continuar</target> -<source>Pause</source> -<target>Pausa</target> - -<source>Logging</source> -<target>A escrever em log</target> +<source>Log</source> +<target>Registo</target> <source>Cannot find %x</source> <target>Não é possÃvel descobrir %x</target> @@ -1233,12 +1296,12 @@ Nota: Nome dos ficheiros tem que ser relativo aos diretórios base. <target>Filtro</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>Deseja mesmo mover o seguinte item para a Reciclagem?</pluralform> -<pluralform>Deseja mesmo mover os seguintes %x itens para a Reciclagem?</pluralform> +<pluralform>Deseja mesmo mover o seguinte item para a reciclagem?</pluralform> +<pluralform>Deseja mesmo mover os seguintes %x itens para a reciclagem?</pluralform> </target> <source> @@ -1292,9 +1355,6 @@ Nota: Nome dos ficheiros tem que ser relativo aos diretórios base. <source>Append a timestamp to each file name</source> <target>Juntar selo temporal a cada nome de ficheiro</target> -<source>Folder</source> -<target>Pasta</target> - <source>File</source> <target>Ficheiro</target> @@ -1415,8 +1475,8 @@ Nota: Nome dos ficheiros tem que ser relativo aos diretórios base. <source>Cannot change process I/O priorities.</source> <target>Não é possÃvel alterar as prioridades de E / S do processo.</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>Não é possÃvel mover %x para a Reciclagem.</target> +<source>Unable to move %x to the recycle bin.</source> +<target>Não é possÃvel mover %x para a reciclagem.</target> <source>Cannot determine final path for %x.</source> <target>Não é possÃvel determinar o caminho final de %x.</target> diff --git a/BUILD/Languages/portuguese_br.lng b/BUILD/Languages/portuguese_br.lng index a4d44140..1c503315 100644 --- a/BUILD/Languages/portuguese_br.lng +++ b/BUILD/Languages/portuguese_br.lng @@ -25,14 +25,14 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Verificando a disponibilidade da lixeira para a pasta %x...</target> -<source>Moving file %x to recycle bin</source> -<target>Movendo arquivo %x para a lixeira</target> +<source>Moving file %x to the recycle bin</source> +<target>Movendo arquivo %x para a Lixeira</target> -<source>Moving folder %x to recycle bin</source> -<target>Movendo pasta %x para a lixeira</target> +<source>Moving folder %x to the recycle bin</source> +<target>Movendo pasta %x para a Lixeira</target> -<source>Moving symbolic link %x to recycle bin</source> -<target>Movendo link simbólico %x para a lixeira</target> +<source>Moving symbolic link %x to the recycle bin</source> +<target>Movendo link simbólico %x para a Lixeira</target> <source>Deleting file %x</source> <target>Apagando arquivo %x</target> @@ -43,14 +43,20 @@ <source>Deleting symbolic link %x</source> <target>Apagando link simbólico %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> <target>A Lixeira não está disponÃvel para as seguintes pastas. Os arquivos serão apagados permanentemente:</target> <source>An exception occurred</source> <target>Ocorreu uma exceção</target> -<source>Cannot find file %x.</source> -<target>Não foi possÃvel localizar o aquivo %x.</target> +<source>A directory path is expected after %x.</source> +<target>Um caminho de diretório é esperado após %x.</target> + +<source>Syntax error</source> +<target>Erro de sintaxe</target> + +<source>Cannot open file %x.</source> +<target>Não foi possÃvel abrir o arquivo %x.</target> <source>Error</source> <target>Erro</target> @@ -58,6 +64,36 @@ <source>File %x does not contain a valid configuration.</source> <target>O arquivo %x não contém uma configuração válida.</target> +<source>Unequal number of left and right directories specified.</source> +<target>Número de diretórios especificados na esquerda e na direita são diferentes.</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>O arquivo de configuração não deve conter configurações de diretórios quando os diretórios são definidos via linha de comando.</target> + +<source>Warning</source> +<target>Avisos</target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target>Os diretórios não podem ser definidos para mais de um arquivo de configuração.</target> + +<source>Syntax:</source> +<target>Sintaxe:</target> + +<source>config files</source> +<target>arquivos de configuração</target> + +<source>directory</source> +<target>diretório</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>Qualquer número de arquivos FreeFileSync .ffs e/ou de tarefa em lote .ffs_batch.</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>Qualquer número de alternativas de diretórios para pelo menos um arquivo de configuração.</target> + +<source>Command line</source> +<target>Linha de comando</target> + <source>A folder input field is empty.</source> <target>Um campo de entrada de pasta está vazio.</target> @@ -215,12 +251,12 @@ <target>Tempo total:</target> <source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </source> <target> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </target> <source>%x MB</source> @@ -242,12 +278,12 @@ <target>Pesquisando:</target> <source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </source> <target> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </target> <source>Encoding extended time information: %x</source> @@ -256,6 +292,9 @@ <source>/sec</source> <target>/seg</target> +<source>%x items</source> +<target>%x itens</target> + <source>Configuration file %x loaded partially only.</source> <target>O arquivo de configuração %x foi carregado parcialmente.</target> @@ -268,8 +307,8 @@ <source>Browse directory</source> <target>Procurar diretório</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Não foi possÃvel acessar o Serviço Cópia de Sombra de Volume.</target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target>Não foi possÃvel acessar o Serviço de Cópia de Sombra de Volume.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>Por favor, utilize a versão 64 bits do FreeFileSync para criar cópias de sombra neste sistema.</target> @@ -280,8 +319,8 @@ <source>Cannot determine volume name for %x.</source> <target>Não foi possÃvel determinar o nome do volume para %x.</target> -<source>Volume name %x not part of file name %y.</source> -<target>Nome do volume %x não é parte do arquivo %y.</target> +<source>Volume name %x is not part of file path %y.</source> +<target>O nome do volume %x não faz parte do caminho do arquivo %y.</target> <source>Abort requested: Waiting for current operation to finish...</source> <target>Cancelar solicitado: Esperando fim da operação...</target> @@ -349,9 +388,6 @@ <source>Idle time between last detected change and execution of command</source> <target>Tempo de espera entre última mudança detectada e execução do comando</target> -<source>Command line</source> -<target>Linha de comando</target> - <source> The command is triggered if: - files or subfolders change @@ -375,9 +411,6 @@ O comando é disparado se: <source>RealtimeSync - Automated Synchronization</source> <target>RealtimeSync - Sincronização Automatizada</target> -<source>Warning</source> -<target>Avisos</target> - <source>Build: %x</source> <target>Versão: %x</target> @@ -387,15 +420,21 @@ O comando é disparado se: <source>All files</source> <target>Todos os arquivos</target> +<source>Directory monitoring active</source> +<target>Monitoramento de diretórios ativado</target> + +<source>Waiting until all directories are available...</source> +<target>Aguardando até todos os diretórios estarem disponÃveis...</target> + <source>&Restore</source> <target>&Restaurar</target> +<source>&Show error</source> +<target>&Mostrar erro</target> + <source>&Exit</source> <target>&Sair</target> -<source>Waiting for missing directories...</source> -<target>Esperando por diretórios faltantes...</target> - <source>Invalid command line:</source> <target>Linha de comando inválida:</target> @@ -405,14 +444,14 @@ O comando é disparado se: <source>File time and size</source> <target>Data e tamanho do arquivo</target> -<source> Two way </source> -<target> Dois sentidos </target> +<source>Two way</source> +<target>Dois sentidos</target> <source>Mirror</source> -<target>Espelhar </target> +<target>Espelhar</target> <source>Update</source> -<target>Atualizar </target> +<target>Atualizar</target> <source>Custom</source> <target>Personalizado</target> @@ -468,11 +507,8 @@ O comando é disparado se: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>Os seguintes itens possuem conflitos não resolvidos e não serão sincronizados:</target> -<source>Significant difference detected:</source> -<target>Diferença significativa detectada:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>Mais de 50% do número total de arquivos será copiado ou apagado.</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>As seguintes pastas são significativamente diferentes. Tenha certeza que está comparando as pastas corretas para sincronização.</target> <source>Not enough free disk space available in:</source> <target>Espaço em disco insuficiente em:</target> @@ -492,12 +528,15 @@ O comando é disparado se: <source>Generating database...</source> <target>Gerando banco de dados...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>Criando Cópia de Sombra de Volume para %x...</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>Criando uma Cópia de Sombra de Volume para %x...</target> <source>Data verification error: %x and %y have different content.</source> <target>Erro na verificação dos dados: %x e %y têm conteúdo diferente.</target> +<source>job name</source> +<target>nome da tarefa</target> + <source>Synchronization aborted</source> <target>Sincronização cancelada</target> @@ -522,6 +561,9 @@ O comando é disparado se: <source>Switching to FreeFileSync main dialog</source> <target>Mudando para a caixa de diálogo principal do FreeFileSync</target> +<source>Retrying operation after error:</source> +<target>Tentando operação novamente após erro:</target> + <source>A new version of FreeFileSync is available:</source> <target>Uma nova versão do FreeFileSync está disponÃvel:</target> @@ -645,8 +687,8 @@ O comando é disparado se: <source>&Export file list...</source> <target>&Exportar lista de arquivos...</target> -<source>&Global settings...</source> -<target>&Configurações...</target> +<source>&Global settings</source> +<target>&Configurações</target> <source>&Tools</source> <target>&Ferramentas</target> @@ -663,12 +705,6 @@ O comando é disparado se: <source>Compare</source> <target>Comparar</target> -<source>Comparison settings</source> -<target>Parâmetros de comparação</target> - -<source>Synchronization settings</source> -<target>Parâmetros de sincronização</target> - <source>Synchronize</source> <target>Sincronizar</target> @@ -717,6 +753,9 @@ O comando é disparado se: <source>Synchronizing...</source> <target>Sincronizando...</target> +<source>Minimize to notification area</source> +<target>Minimizar para a área de notificação</target> + <source>On completion</source> <target>Ao finalizar</target> @@ -726,6 +765,15 @@ O comando é disparado se: <source>&Pause</source> <target>&Pausar</target> +<source>Variant</source> +<target>Modo</target> + +<source>Statistics</source> +<target>EstatÃsticas</target> + +<source>&Don't show this dialog again</source> +<target>&Não mostrar este diálogo novamente</target> + <source>Select a variant</source> <target>Selecione uma variante</target> @@ -769,11 +817,17 @@ Os arquivos são considerados iguais se <target>Cópia espelho da pasta da esquerda. A pasta da direita será modificada para ficar exatamente igual à pasta da esquerda após a sincronização.</target> <source>Copy new or updated files to right folder.</source> -<target>Copia arquivos novos ou atualizados para a pasta da direita</target> +<target>Copia arquivos novos ou atualizados para a pasta da direita.</target> <source>Configure your own synchronization rules.</source> <target>Configure as suas próprias regras de sincronização.</target> +<source>Detect moved files</source> +<target>Detectar arquivos movidos</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Requer um arquivo de banco de dados. Não é suportado por todos os sistemas de arquivos.</target> + <source>Error handling</source> <target>Tratamento de erros</target> @@ -793,21 +847,21 @@ Os arquivos são considerados iguais se <target>Tratamento da exclusão</target> <source>Permanent</source> -<target>Permante</target> +<target>Permanente</target> <source>Delete or overwrite files permanently</source> -<target>Apaga ou substitui arquivos permanentemente</target> +<target>Apaga ou substitui os arquivos permanentemente</target> -<source>Recycle Bin</source> +<source>Recycle bin</source> <target>Lixeira</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Utiliza a Lixeira para arquivos apagados ou sobrescritos</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Faz uma cópia dos arquivos apagados ou substituÃdos na Lixeira</target> <source>Versioning</source> <target>Controle de versões</target> -<source>Move files to user-defined folder</source> +<source>Move files to a user-defined folder</source> <target>Move os arquivos para uma pasta definida pelo usuário</target> <source>Naming convention:</source> @@ -816,8 +870,8 @@ Os arquivos são considerados iguais se <source>Batch job</source> <target>Tarefa em lote</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Cria um arquivo de lote para automatizar a sincronização. Dê um clique duplo ou agende no Agendador de Tarefas do sistema operacional: FreeFileSync.exe <nome>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Cria um arquivo de tarefa em lote para sincronização desatendida. Para iniciar, dê um clique duplo neste arquivo ou agende no agendador de tarefas: %x</target> <source>Exit</source> <target>Sair</target> @@ -840,30 +894,6 @@ Os arquivos são considerados iguais se <source>Limit maximum number of log files</source> <target>Limita número máximo de arquivos de log</target> -<source>Source code written in C++ using:</source> -<target>Código-fonte escrito em C++ utilizando:</target> - -<source>If you like FreeFileSync</source> -<target>Se você gosta do FreeFileSync</target> - -<source>Donate with PayPal</source> -<target>Doar usando PayPal</target> - -<source>Many thanks for localization:</source> -<target>Pela tradução, um agradecimento a:</target> - -<source>Feedback and suggestions are welcome</source> -<target>CrÃticas e sugestões são bem-vindas</target> - -<source>Homepage</source> -<target>Homepage</target> - -<source>Email</source> -<target>E-mail</target> - -<source>Published under the GNU General Public License</source> -<target>Publicado sobre a GNU General Public License</target> - <source>Delete on both sides</source> <target>Apagar em ambos os lados</target> @@ -871,12 +901,12 @@ Os arquivos são considerados iguais se <target>Apaga em ambos os lados mesmo se o arquivo está selecionado só em um lado</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -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. +Os arquivos só serão sincronizados se passarem por todas as regras do filtro. +Nota: os caminhos dos arquivos devem ser relativos aos diretórios base. </target> <source>Include</source> @@ -906,20 +936,20 @@ Nota: Os nomes dos arquivos devem ser relativos aos diretórios base. <source>Fail-safe file copy</source> <target>Cópia de arquivos a prova de falhas</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>Escreve para um arquivo temporário primeiro (*.ffs_tmp) e depois o renomeia. Isto garante um estado consistente mesmo em caso de erro fatal.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>Copia primeiro para um arquivo temporário (*.ffs_tmp) e depois o renomeia. Isto garante um estado consistente mesmo em caso de erro fatal.</target> <source>Copy locked files</source> <target>Copiar arquivos bloqueados (em uso)</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Copia os arquivos compartilhados ou bloqueados (em uso) usando o Serviço de Cópia de Sombra de Volume (Requer direitos de Administrador)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>Copia arquivos compartilhados ou bloqueados usando o Serviço de Cópia de Sombra de Volume (requer direitos de administrador.</target> <source>Copy file access permissions</source> <target>Copiar permissões de acesso aos arquivos</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Tranfere as permissões dos arquivos e pastas (requer direitos de Administrador)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>Transfere permissões de arquivos e pastas (requer direitos de administrador).</target> <source>Restore hidden dialogs</source> <target>Restaurar diálogos ocultados</target> @@ -933,15 +963,6 @@ Nota: Os nomes dos arquivos devem ser relativos aos diretórios base. <source>&Default</source> <target>&Config. Padrão</target> -<source>Variant</source> -<target>Modo</target> - -<source>Statistics</source> -<target>EstatÃsticas</target> - -<source>Don't show this dialog again</source> -<target>Não mostrar esta caixa de diálogo novamente</target> - <source>Find what:</source> <target>Localizar o que:</target> @@ -951,15 +972,45 @@ Nota: Os nomes dos arquivos devem ser relativos aos diretórios base. <source>&Find next</source> <target>&Localizar próxima</target> +<source>Source code written in C++ using:</source> +<target>Código-fonte escrito em C++ utilizando:</target> + +<source>If you like FreeFileSync</source> +<target>Se você gosta do FreeFileSync</target> + +<source>Donate with PayPal</source> +<target>Doar usando PayPal</target> + +<source>Feedback and suggestions are welcome</source> +<target>CrÃticas e sugestões são bem-vindas</target> + +<source>Homepage</source> +<target>Homepage</target> + +<source>Email</source> +<target>E-mail</target> + +<source>Published under the GNU General Public License</source> +<target>Publicado sobre a GNU General Public License</target> + +<source>Many thanks for localization:</source> +<target>Pela tradução, um agradecimento a:</target> + +<source>Start synchronization</source> +<target>Iniciar a sincronização</target> + +<source>Comparison settings</source> +<target>Parâmetros de comparação</target> + +<source>Synchronization settings</source> +<target>Parâmetros de sincronização</target> + <source>Delete</source> <target>Apagar</target> <source>Configure filter</source> <target>Configurar filtros</target> -<source>Start synchronization</source> -<target>Iniciar a sincronização</target> - <source>Find</source> <target>Localizar</target> @@ -994,6 +1045,21 @@ Nota: Os nomes dos arquivos devem ser relativos aos diretórios base. <target>Comparar os dois lados</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>Você realmente deseja executar o comando %y para 1 item?</pluralform> +<pluralform>Você realmente deseja executar o comando %y para %x itens?</pluralform> +</target> + +<source>Confirm</source> +<target>Confirmar</target> + +<source>&Execute</source> +<target>&Executar</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1029,12 +1095,15 @@ Nota: Os nomes dos arquivos devem ser relativos aos diretórios base. <source>Include temporarily</source> <target>Incluir temporariamente</target> -<source>Exclude via filter:</source> -<target>Excluir via filtro:</target> - <source>multiple selection</source> <target>seleção múltipla</target> +<source>Include via filter:</source> +<target>Incluir via filtro:</target> + +<source>Exclude via filter:</source> +<target>Excluir via filtro:</target> + <source>Include all</source> <target>Incluir todos</target> @@ -1080,8 +1149,8 @@ Nota: Os nomes dos arquivos devem ser relativos aos diretórios base. <source>Do&n't save</source> <target>&Não salvar</target> -<source>Never save changes</source> -<target>Nunca salvar alterações</target> +<source>Never save &changes</source> +<target>Nunca salvar as &modificações</target> <source>Show files that exist on left side only</source> <target>Mostrar arquivos que existem somente à esquerda</target> @@ -1134,8 +1203,8 @@ Nota: Os nomes dos arquivos devem ser relativos aos diretórios base. <source>All folders are in sync</source> <target>Todas as pastas estão sincronizadas</target> -<source>Comma separated list</source> -<target>Lista de itens separados por vÃrgulas</target> +<source>Comma-separated values</source> +<target>Valores separados por vÃrgula</target> <source>File list exported</source> <target>Lista de arquivos exportada</target> @@ -1143,8 +1212,8 @@ Nota: Os nomes dos arquivos devem ser relativos aos diretórios base. <source>Searching for program updates...</source> <target>Procurando atualizações do programa...</target> -<source>Ignore further errors</source> -<target>Ignorar erros subsequentes</target> +<source>&Ignore subsequent errors</source> +<target>&Ignorar erros subsequentes</target> <source>&Ignore</source> <target>&Ignorar</target> @@ -1152,8 +1221,8 @@ Nota: Os nomes dos arquivos devem ser relativos aos diretórios base. <source>Fatal Error</source> <target>Erro fatal</target> -<source>Don't show this warning again</source> -<target>Não mostrar este aviso novamente</target> +<source>&Don't show this warning again</source> +<target>&Não mostrar este aviso novamente</target> <source>&Switch</source> <target>&Alterar</target> @@ -1188,14 +1257,11 @@ Nota: Os nomes dos arquivos devem ser relativos aos diretórios base. <source>Completed</source> <target>Finalizado</target> -<source>Continue</source> -<target>Continuar</target> +<source>&Continue</source> +<target>&Continuar</target> -<source>Pause</source> -<target>Pausar</target> - -<source>Logging</source> -<target>Ver Log</target> +<source>Log</source> +<target>Log</target> <source>Cannot find %x</source> <target>Não foi possÃvel localizar %x</target> @@ -1231,8 +1297,8 @@ Nota: Os nomes dos arquivos devem ser relativos aos diretórios base. <target>Filtro</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> <pluralform>Você realmente deseja mover o seguinte item para a Lixeira?</pluralform> @@ -1290,9 +1356,6 @@ Nota: Os nomes dos arquivos devem ser relativos aos diretórios base. <source>Append a timestamp to each file name</source> <target>Atribuir uma estampa de tempo para cada nome de arquivo</target> -<source>Folder</source> -<target>Pasta</target> - <source>File</source> <target>Arquivo</target> @@ -1413,7 +1476,7 @@ Nota: Os nomes dos arquivos devem ser relativos aos diretórios base. <source>Cannot change process I/O priorities.</source> <target>Não foi possÃvel mudar a prioridade de E/S do processo.</target> -<source>Unable to move %x to the Recycle Bin.</source> +<source>Unable to move %x to the recycle bin.</source> <target>Não foi possÃvel mover %x para a Lixeira.</target> <source>Cannot determine final path for %x.</source> diff --git a/BUILD/Languages/romanian.lng b/BUILD/Languages/romanian.lng index 1e4efa96..dd30e917 100644 --- a/BUILD/Languages/romanian.lng +++ b/BUILD/Languages/romanian.lng @@ -25,13 +25,13 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Verific dacă Reciclatorul e disponibil pentru dosarul %x...</target> -<source>Moving file %x to recycle bin</source> +<source>Moving file %x to the recycle bin</source> <target>Mut fila %x în Reciclator</target> -<source>Moving folder %x to recycle bin</source> +<source>Moving folder %x to the recycle bin</source> <target>Mut dosarul %x în Reciclator</target> -<source>Moving symbolic link %x to recycle bin</source> +<source>Moving symbolic link %x to the recycle bin</source> <target>Mut legătura simbolică %x în Reciclator</target> <source>Deleting file %x</source> @@ -43,14 +43,20 @@ <source>Deleting symbolic link %x</source> <target>Șterg legătura simbolică %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>Reciclatorul nu este disponibil pentru dosarele următoare. Filele È™terse de acolo vor fi È™terse în mod definitiv:</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>Reciclatorul nu este disponibil pentru dosarele următoare. Filele È™terse de acolo vor dispărea în mod definitiv:</target> <source>An exception occurred</source> <target>A apărut o excepÈ›ie</target> -<source>Cannot find file %x.</source> -<target>Nu pot găsi fila %x.</target> +<source>A directory path is expected after %x.</source> +<target>Este aÈ™teptată o cale de dosar după %x.</target> + +<source>Syntax error</source> +<target>Eroare de sintaxă</target> + +<source>Cannot open file %x.</source> +<target>Nu pot deschide fila %x.</target> <source>Error</source> <target>Eroare</target> @@ -58,6 +64,36 @@ <source>File %x does not contain a valid configuration.</source> <target>Fila %x nu conÈ›ine o configuraÈ›ie validă.</target> +<source>Unequal number of left and right directories specified.</source> +<target>Numărul de dosare specificat pentru părÈ›ile stîngă È™i dreaptă este inegal.</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>Fila de configurare nu trebuie să conÈ›ină setări la nivelul perechii de dosare, cînd dosarele sînt setate prin linia de comandă.</target> + +<source>Warning</source> +<target>AtenÈ›ie</target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target>Dosarele nu pot fi setate pentru mai mult de o singură filă de configurare.</target> + +<source>Syntax:</source> +<target>Sintaxă:</target> + +<source>config files</source> +<target>file de configurare</target> + +<source>directory</source> +<target>dosar</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>Orice număr de file de configurare pentru FreeFileSync, de tipul .ffs_gui sau/È™i .ffs_batch.</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>Orice număr de dosare alternative pentru cel mult o filă de configurare.</target> + +<source>Command line</source> +<target>Linie de comandă</target> + <source>A folder input field is empty.</source> <target>Un cîmp de introducere a dosarului este gol.</target> @@ -152,7 +188,7 @@ <target>Suprascrie elementul drept cu cel stîng</target> <source>Do nothing</source> -<target>Nici o AcÈ›iune</target> +<target>Nici o acÈ›iune</target> <source>Update attributes on left</source> <target>Actualizează atributele în partea stîngă</target> @@ -216,13 +252,13 @@ <target>Timp Total:</target> <source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </source> <target> -<pluralform>1 Bait</pluralform> -<pluralform>%x BaiÈ›i</pluralform> -<pluralform>%x de BaiÈ›i</pluralform> +<pluralform>1 bait</pluralform> +<pluralform>%x baiÈ›i</pluralform> +<pluralform>%x de baiÈ›i</pluralform> </target> <source>%x MB</source> @@ -244,13 +280,13 @@ <target>Scanez:</target> <source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </source> <target> -<pluralform>[1 Fir]</pluralform> -<pluralform>[%x Fire]</pluralform> -<pluralform>[%x de Fire]</pluralform> +<pluralform>1 fir</pluralform> +<pluralform>%x fire</pluralform> +<pluralform>%x de fire</pluralform> </target> <source>Encoding extended time information: %x</source> @@ -259,6 +295,9 @@ <source>/sec</source> <target>/sec</target> +<source>%x items</source> +<target>%x itemuri</target> + <source>Configuration file %x loaded partially only.</source> <target>Fila de configuraÈ›ie %x a fost deschisă doar parÈ›ial.</target> @@ -271,7 +310,7 @@ <source>Browse directory</source> <target>Explorează Dosarul</target> -<source>Cannot access Volume Shadow Copy Service.</source> +<source>Cannot access the Volume Shadow Copy Service.</source> <target>Nu pot accesa Serviciul de Conservare a Volumelor [Volume Shadow Copy].</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> @@ -283,8 +322,8 @@ <source>Cannot determine volume name for %x.</source> <target>Nu pot determina numele volumului pentru %x.</target> -<source>Volume name %x not part of file name %y.</source> -<target>Numele volumului %x nu face parte din numele filei %y.</target> +<source>Volume name %x is not part of file path %y.</source> +<target>Numele volumului %x nu face parte din calea filei %y.</target> <source>Abort requested: Waiting for current operation to finish...</source> <target>Abandonare solicitată: Se aÈ™teaptă terminarea operaÈ›iei în curs...</target> @@ -352,9 +391,6 @@ <source>Idle time between last detected change and execution of command</source> <target>Timpul de inactivitate între ultima schimbare detectată È™i executarea comenzii</target> -<source>Command line</source> -<target>Linie de comandă</target> - <source> The command is triggered if: - files or subfolders change @@ -378,9 +414,6 @@ Comanda este declanÈ™ată dacă: <source>RealtimeSync - Automated Synchronization</source> <target>RealtimeSync - Sincronizare Inteligentă</target> -<source>Warning</source> -<target>AtenÈ›ie</target> - <source>Build: %x</source> <target>CompilaÈ›ia: %x</target> @@ -390,15 +423,21 @@ Comanda este declanÈ™ată dacă: <source>All files</source> <target>Toate Filele</target> +<source>Directory monitoring active</source> +<target>Monitorizarea dosarelor este activă</target> + +<source>Waiting until all directories are available...</source> +<target>AÈ™tept pînă cînd toate dosarele vor fi disponibile...</target> + <source>&Restore</source> <target>&Restaurează</target> +<source>&Show error</source> +<target>A&rată eroarea</target> + <source>&Exit</source> <target>&IeÈ™i</target> -<source>Waiting for missing directories...</source> -<target>AÈ™tept ca dosarele lipsă să devină disponibile...</target> - <source>Invalid command line:</source> <target>Linie de comandă nevalidă:</target> @@ -408,14 +447,14 @@ Comanda este declanÈ™ată dacă: <source>File time and size</source> <target>Timpul È™i Mărimea Filelor</target> -<source> Two way </source> -<target> BidirecÈ›ională </target> +<source>Two way</source> +<target>BidirecÈ›ională</target> <source>Mirror</source> -<target>Clonare </target> +<target>Clonare</target> <source>Update</source> -<target>Actualizare </target> +<target>Actualizare</target> <source>Custom</source> <target>Sincronizare Personalizată</target> @@ -471,11 +510,8 @@ Comanda este declanÈ™ată dacă: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>Există conflicte nerezolvate la elementele listate mai jos, deci ele nu vor fi sincronizate:</target> -<source>Significant difference detected:</source> -<target>Diferență semnificativă detectată:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>Peste 50% din numărul total de file vor fi copiate sau distruse.</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>Dosarele următoare diferă foarte mult. Asigură-te că ai potrivit pentru sincronizare dosarele corecte.</target> <source>Not enough free disk space available in:</source> <target>SpaÈ›iu de stocare insuficient pe:</target> @@ -495,12 +531,15 @@ Comanda este declanÈ™ată dacă: <source>Generating database...</source> <target>Generez baza de date...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>Creez Conservare a Volumului [Volume Shadow Copy] pentru %x...</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>Creez o Conservare a Volumului [Volume Shadow Copy] pentru %x...</target> <source>Data verification error: %x and %y have different content.</source> <target>Eroare la verificarea datelor: %x È™i %y au conÈ›inut diferit.</target> +<source>job name</source> +<target>numele sarcinii</target> + <source>Synchronization aborted</source> <target>Sincronizare abandonată</target> @@ -525,6 +564,9 @@ Comanda este declanÈ™ată dacă: <source>Switching to FreeFileSync main dialog</source> <target>Comut la dialogul principal FreeFileSync</target> +<source>Retrying operation after error:</source> +<target>Reîncerc operaÈ›ia după eroare:</target> + <source>A new version of FreeFileSync is available:</source> <target>Este disponibilă o versiune nouă a softului:</target> @@ -648,8 +690,8 @@ Comanda este declanÈ™ată dacă: <source>&Export file list...</source> <target>&Exportă Lista de File...</target> -<source>&Global settings...</source> -<target>&Setări Globale...</target> +<source>&Global settings</source> +<target>&Setări Globale</target> <source>&Tools</source> <target>&Unelte</target> @@ -666,12 +708,6 @@ Comanda este declanÈ™ată dacă: <source>Compare</source> <target>Compară</target> -<source>Comparison settings</source> -<target>Setările Comparării</target> - -<source>Synchronization settings</source> -<target>Setările Sincronizării</target> - <source>Synchronize</source> <target>Sincronizează</target> @@ -720,6 +756,9 @@ Comanda este declanÈ™ată dacă: <source>Synchronizing...</source> <target>Sincronizare Aflată în Curs...</target> +<source>Minimize to notification area</source> +<target>Minimizează în aria de notificare (sertar)</target> + <source>On completion</source> <target>La Terminare</target> @@ -729,6 +768,15 @@ Comanda este declanÈ™ată dacă: <source>&Pause</source> <target>&Pauzează</target> +<source>Variant</source> +<target>Varianta Sincronizării</target> + +<source>Statistics</source> +<target>Statistici</target> + +<source>&Don't show this dialog again</source> +<target>Nu arăta acest &dialog din nou</target> + <source>Select a variant</source> <target>Selectează o variantă</target> @@ -777,6 +825,12 @@ este acelaÈ™i <source>Configure your own synchronization rules.</source> <target>Reguli de sincronizare definite de utilizator pentru fiecare situaÈ›ie.</target> +<source>Detect moved files</source> +<target>Detectează filele mutate</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Necesită file cu baze de date. Nu e suportat de toate sistemele de file.</target> + <source>Error handling</source> <target>Gestionarea Erorilor</target> @@ -801,17 +855,17 @@ este acelaÈ™i <source>Delete or overwrite files permanently</source> <target>Filele sînt È™terse sau suprascrise în mod definitiv, fără a mai putea fi recuperate</target> -<source>Recycle Bin</source> +<source>Recycle bin</source> <target>Reciclator</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Filele È™terse sau suprascrise sînt puse în Reciclator [Recycle Bin], de unde pot fi recuperate la nevoie</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Conservă [back up] în Reciclator filele È™terse sau suprascrise</target> <source>Versioning</source> <target>Versionare</target> -<source>Move files to user-defined folder</source> -<target>Mută filele în dosarul stabilit de utilizator</target> +<source>Move files to a user-defined folder</source> +<target>Mută filele într-un dosar stabilit de utilizator</target> <source>Naming convention:</source> <target>ConvenÈ›ie de numire:</target> @@ -819,8 +873,8 @@ este acelaÈ™i <source>Batch job</source> <target>Sarcină Set</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Automatizează sincronizarea prin crearea unei file set [batch file]. Pentru efectuarea sincronizării, dublu-clichează această filă sau programează sarcina următoare în Planificatorul de Sarcini [Task Scheduler] al SO: FreeFileSync.exe <numele filei>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Creează o filă set [batch file] pentru sincronizarea neasistată. Pentru efectuarea sincronizării, dublu-clichează această filă sau programează rularea ei folosind un Planificator de Sarcini [Task Scheduler]: %x</target> <source>Exit</source> <target>IeÈ™ire</target> @@ -852,9 +906,6 @@ este acelaÈ™i <source>Donate with PayPal</source> <target>Donează prin PayPal</target> -<source>Many thanks for localization:</source> -<target>Multe mulÈ›umiri pentru localizare:</target> - <source>Feedback and suggestions are welcome</source> <target>Opiniile È™i sugestiile despre program sînt binevenite.</target> @@ -867,6 +918,9 @@ este acelaÈ™i <source>Published under the GNU General Public License</source> <target>Publicat sub licenÈ›a GNU GPL</target> +<source>Many thanks for localization:</source> +<target>Multe mulÈ›umiri pentru localizare:</target> + <source>Delete on both sides</source> <target>Șterge din ambele părÈ›i</target> @@ -874,12 +928,12 @@ este acelaÈ™i <target>Șterge din ambele părÈ›i, chiar dacă fila e selecÈ›ionată într-o singură parte</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -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ă). +Filele vor fi sincronizate doar dacă îndeplinesc toate regulile filtrului. +Notă: Căile filelor trebuie să fie relative la dosarele bază (rădăcină). </target> <source>Include</source> @@ -909,19 +963,19 @@ Notă: Numele filelor trebuie să fie relative la dosarele bază (rădăcină). <source>Fail-safe file copy</source> <target>Copiază filele în modul protejat la eÈ™ec [fail-safe]</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>Scrierea se face mai întîi într-o filă temporară (*.ffs_tmp), care e apoi renumită. Se garantează astfel consecvenÈ›a stării filelor chiar È™i în cazul apariÈ›iei de erori fatale.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>Copierea se face mai întîi într-o filă temporară (*.ffs_tmp), care e apoi renumită. Se garantează astfel consecvenÈ›a stării filelor chiar È™i în cazul apariÈ›iei de erori fatale.</target> <source>Copy locked files</source> <target>Copiază filele partajate [shared] sau zăvorîte [locked]</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> <target>Filele partajate sau zăvorîte sînt copiate folosind Serviciul de Conservare a Volumelor din Windows [Volume Shadow Copy] (necesită drepturi de Administrator)</target> <source>Copy file access permissions</source> <target>Copiază permisiunile de acces ale filelor</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> +<source>Transfer file and folder permissions (requires administrator rights)</source> <target>Permisiunile filelor È™i dosarelor sînt È™i ele transferate (necesită drepturi de Administrator)</target> <source>Restore hidden dialogs</source> @@ -936,15 +990,6 @@ Notă: Numele filelor trebuie să fie relative la dosarele bază (rădăcină). <source>&Default</source> <target>Coloanele &Implicite</target> -<source>Variant</source> -<target>Varianta Sincronizării</target> - -<source>Statistics</source> -<target>Statistici</target> - -<source>Don't show this dialog again</source> -<target>Nu arăta fereastra asta din nou</target> - <source>Find what:</source> <target>GăseÈ™te Asta:</target> @@ -954,15 +999,21 @@ Notă: Numele filelor trebuie să fie relative la dosarele bază (rădăcină). <source>&Find next</source> <target>&GăseÈ™te Următorul</target> +<source>Start synchronization</source> +<target>PorneÈ™te Sincronizarea</target> + +<source>Comparison settings</source> +<target>Setările Comparării</target> + +<source>Synchronization settings</source> +<target>Setările Sincronizării</target> + <source>Delete</source> <target>Șterge</target> <source>Configure filter</source> <target>Configurează Filtrul</target> -<source>Start synchronization</source> -<target>PorneÈ™te Sincronizarea</target> - <source>Find</source> <target>GăseÈ™te</target> @@ -997,6 +1048,22 @@ Notă: Numele filelor trebuie să fie relative la dosarele bază (rădăcină). <target>Compară PărÈ›ile Stîngă È™i Dreaptă</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>Sigur vrei să execuÈ›i comanda %y pentru 1 element?</pluralform> +<pluralform>Sigur vrei să execuÈ›i comanda %y pentru %x elemente?</pluralform> +<pluralform>Sigur vrei să execuÈ›i comanda %y pentru %x de elemente?</pluralform> +</target> + +<source>Confirm</source> +<target>Confirmă</target> + +<source>&Execute</source> +<target>&Execută</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1035,12 +1102,15 @@ Notă: Numele filelor trebuie să fie relative la dosarele bază (rădăcină). <source>Include temporarily</source> <target>Include Temporar</target> -<source>Exclude via filter:</source> -<target>Exclude prin Filtru:</target> - <source>multiple selection</source> <target>selectare multiplă</target> +<source>Include via filter:</source> +<target>Include prin Filtrul:</target> + +<source>Exclude via filter:</source> +<target>Exclude prin Filtrul:</target> + <source>Include all</source> <target>Include Tot</target> @@ -1086,8 +1156,8 @@ Notă: Numele filelor trebuie să fie relative la dosarele bază (rădăcină). <source>Do&n't save</source> <target>&Nu salva</target> -<source>Never save changes</source> -<target>Nu salva niciodată modificările</target> +<source>Never save &changes</source> +<target>Nu salva ni&ciodată modificările</target> <source>Show files that exist on left side only</source> <target>Arată filele care există doar în stînga</target> @@ -1140,8 +1210,8 @@ Notă: Numele filelor trebuie să fie relative la dosarele bază (rădăcină). <source>All folders are in sync</source> <target>Toate dosarele sînt sincronizate</target> -<source>Comma separated list</source> -<target>Listă de elemente separate prin virgulă</target> +<source>Comma-separated values</source> +<target>Valori separate prin virgulă</target> <source>File list exported</source> <target>Lista de file a fost exportată</target> @@ -1149,8 +1219,8 @@ Notă: Numele filelor trebuie să fie relative la dosarele bază (rădăcină). <source>Searching for program updates...</source> <target>Caut actualizări ale programului...</target> -<source>Ignore further errors</source> -<target>Ignoră erorile ulterioare</target> +<source>&Ignore subsequent errors</source> +<target>&Ignoră erorile ulterioare</target> <source>&Ignore</source> <target>&OK</target> @@ -1158,8 +1228,8 @@ Notă: Numele filelor trebuie să fie relative la dosarele bază (rădăcină). <source>Fatal Error</source> <target>Eroare Fatală</target> -<source>Don't show this warning again</source> -<target>Nu arăta această atenÈ›ionare din nou</target> +<source>&Don't show this warning again</source> +<target>&Nu arăta din nou această atenÈ›ionare</target> <source>&Switch</source> <target>&Comută</target> @@ -1194,13 +1264,10 @@ Notă: Numele filelor trebuie să fie relative la dosarele bază (rădăcină). <source>Completed</source> <target>Sincronizare Terminată</target> -<source>Continue</source> -<target>Continuă</target> - -<source>Pause</source> -<target>Pauzează</target> +<source>&Continue</source> +<target>&Continuă</target> -<source>Logging</source> +<source>Log</source> <target>Jurnal</target> <source>Cannot find %x</source> @@ -1237,8 +1304,8 @@ Notă: Numele filelor trebuie să fie relative la dosarele bază (rădăcină). <target>Filtru</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> <pluralform>Sigur vrei să muÈ›i în Reciclator elementul următor?</pluralform> @@ -1284,7 +1351,7 @@ Notă: Numele filelor trebuie să fie relative la dosarele bază (rădăcină). <target>Vrei ca dialogurile ascunse È™i mesajele de avertizare să fie vizibile din nou?</target> <source>Leave as unresolved conflict</source> -<target>Lasă ca Conflict Nerezolvat</target> +<target>Lasă ca conflict nerezolvat</target> <source>Replace</source> <target>ÃŽnlocuieÈ™te</target> @@ -1298,9 +1365,6 @@ Notă: Numele filelor trebuie să fie relative la dosarele bază (rădăcină). <source>Append a timestamp to each file name</source> <target>Adaugă un marcaj temporal la numele fiecărei file</target> -<source>Folder</source> -<target>Dosar</target> - <source>File</source> <target>Filă</target> @@ -1424,7 +1488,7 @@ Notă: Numele filelor trebuie să fie relative la dosarele bază (rădăcină). <source>Cannot change process I/O priorities.</source> <target>Nu pot schimba prioritățile I/O ale procesului.</target> -<source>Unable to move %x to the Recycle Bin.</source> +<source>Unable to move %x to the recycle bin.</source> <target>Nu pot muta %x în Reciclator.</target> <source>Cannot determine final path for %x.</source> diff --git a/BUILD/Languages/russian.lng b/BUILD/Languages/russian.lng index 4d7b5f09..8ef22f8c 100644 --- a/BUILD/Languages/russian.lng +++ b/BUILD/Languages/russian.lng @@ -7,6 +7,178 @@ <plural_definition>n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<11 || n%100>14) ? 1 : 2</plural_definition> </header> +<source>Unable to move %x to the recycle bin.</source> +<target></target> + +<source> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> +</source> +<target> +</target> + +<source>Log</source> +<target></target> + +<source>&Continue</source> +<target></target> + +<source>&Don't show this warning again</source> +<target></target> + +<source>&Ignore subsequent errors</source> +<target></target> + +<source>Comma-separated values</source> +<target></target> + +<source>Never save &changes</source> +<target></target> + +<source>Include via filter:</source> +<target></target> + +<source>&Execute</source> +<target></target> + +<source>Confirm</source> +<target></target> + +<source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +</target> + +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target></target> + +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target></target> + +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target></target> + +<source> +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. +</source> +<target></target> + +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target></target> + +<source>Move files to a user-defined folder</source> +<target></target> + +<source>Back up deleted and overwritten files in the recycle bin</source> +<target></target> + +<source>Recycle bin</source> +<target></target> + +<source>Requires database files. Not supported by all file systems.</source> +<target></target> + +<source>Detect moved files</source> +<target></target> + +<source>&Don't show this dialog again</source> +<target></target> + +<source>Minimize to notification area</source> +<target></target> + +<source>Retrying operation after error:</source> +<target></target> + +<source>job name</source> +<target></target> + +<source>Creating a Volume Shadow Copy for %x...</source> +<target></target> + +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target></target> + +<source>&Show error</source> +<target></target> + +<source>Waiting until all directories are available...</source> +<target></target> + +<source>Directory monitoring active</source> +<target></target> + +<source>Volume name %x is not part of file path %y.</source> +<target></target> + +<source>Cannot access the Volume Shadow Copy Service.</source> +<target></target> + +<source>%x items</source> +<target></target> + +<source> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> +</source> +<target> +</target> + +<source> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> +</source> +<target> +</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target></target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target></target> + +<source>directory</source> +<target></target> + +<source>config files</source> +<target></target> + +<source>Syntax:</source> +<target></target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target></target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target></target> + +<source>Unequal number of left and right directories specified.</source> +<target></target> + +<source>Cannot open file %x.</source> +<target></target> + +<source>Syntax error</source> +<target></target> + +<source>A directory path is expected after %x.</source> +<target></target> + +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target></target> + +<source>Moving symbolic link %x to the recycle bin</source> +<target></target> + +<source>Moving folder %x to the recycle bin</source> +<target></target> + +<source>Moving file %x to the recycle bin</source> +<target></target> + <source>Both sides have changed since last synchronization.</source> <target>Со времени поÑледней Ñинхронизации Ñ Ð¾Ð±ÐµÐ¸Ñ… Ñторон произошли изменениÑ.</target> @@ -28,15 +200,6 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Проверка доÑтупноÑти "Корзины" Ð´Ð»Ñ Ð¿Ð°Ð¿ÐºÐ¸ %x...</target> -<source>Moving file %x to recycle bin</source> -<target>Перемещение файла %x в "Корзину"</target> - -<source>Moving folder %x to recycle bin</source> -<target>Перемещение папки %x в "Корзину"</target> - -<source>Moving symbolic link %x to recycle bin</source> -<target>Перемещение Ñимвольной ÑÑылки %x в "Корзину"</target> - <source>Deleting file %x</source> <target>Удаление файла %x</target> @@ -46,21 +209,21 @@ <source>Deleting symbolic link %x</source> <target>Удаление Ñимвольной ÑÑылки %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>Ð”Ð»Ñ Ñтого пути "Корзина" недоÑтупна! Файлы будут удалены безвозвратно:</target> - <source>An exception occurred</source> <target>ИÑключение произошло</target> -<source>Cannot find file %x.</source> -<target>Ðевозможно найти файл %x.</target> - <source>Error</source> <target>Ошибка</target> <source>File %x does not contain a valid configuration.</source> <target>Файл %x не Ñодержит дейÑтвительной конфигурации.</target> +<source>Warning</source> +<target>Внимание</target> + +<source>Command line</source> +<target>ÐšÐ¾Ð¼Ð°Ð½Ð´Ð½Ð°Ñ Ñтрока</target> + <source>A folder input field is empty.</source> <target>Поле ввода папки пуÑтое.</target> @@ -218,16 +381,6 @@ <source>Total time:</source> <target>Общее времÑ:</target> -<source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> -</source> -<target> -<pluralform>%x Байт</pluralform> -<pluralform>%x Байта</pluralform> -<pluralform>%x Байт</pluralform> -</target> - <source>%x MB</source> <target>%x МБ</target> @@ -246,16 +399,6 @@ <source>Scanning:</source> <target>Сканирую:</target> -<source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> -</source> -<target> -<pluralform>[%x поток]</pluralform> -<pluralform>[%x потока]</pluralform> -<pluralform>[%x потоков]</pluralform> -</target> - <source>Encoding extended time information: %x</source> <target>Кодирование раÑширенной информации о времени: %x</target> @@ -274,9 +417,6 @@ <source>Browse directory</source> <target>Обзор папок</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Ðевозможно получить доÑтуп к Ñлужбе Теневого ÐšÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¢Ð¾Ð¼Ð°.</target> - <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>ПожалуйÑта, иÑпользуйте 64-разрÑдную верÑию FreeFileSync Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ‚ÐµÐ½ÐµÐ²Ñ‹Ñ… копий на Ñтой ÑиÑтеме.</target> @@ -286,9 +426,6 @@ <source>Cannot determine volume name for %x.</source> <target>Ðевозможно определить Ð¸Ð¼Ñ Ñ‚Ð¾Ð¼Ð° Ð´Ð»Ñ %x.</target> -<source>Volume name %x not part of file name %y.</source> -<target>Ð˜Ð¼Ñ Ñ‚Ð¾Ð¼Ð° %x не ÑвлÑетÑÑ Ñ‡Ð°Ñтью имени файла %y.</target> - <source>Abort requested: Waiting for current operation to finish...</source> <target>Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ñ‹: Ожидайте, пока Ñ‚ÐµÐºÑƒÑ‰Ð°Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐ¸Ñ‚ÑÑ...</target> @@ -355,9 +492,6 @@ <source>Idle time between last detected change and execution of command</source> <target>Ð’Ñ€ÐµÐ¼Ñ Ð·Ð°Ð´ÐµÑ€Ð¶ÐºÐ¸ между поÑледним обнаруженным изменением и выполнением командной Ñтроки в Ñекундах</target> -<source>Command line</source> -<target>ÐšÐ¾Ð¼Ð°Ð½Ð´Ð½Ð°Ñ Ñтрока</target> - <source> The command is triggered if: - files or subfolders change @@ -381,9 +515,6 @@ The command is triggered if: <source>RealtimeSync - Automated Synchronization</source> <target>RealtimeSync - ÐвтоматичеÑÐºÐ°Ñ ÑинхронизациÑ</target> -<source>Warning</source> -<target>Внимание</target> - <source>Build: %x</source> <target>Ñборка %x</target> @@ -399,9 +530,6 @@ The command is triggered if: <source>&Exit</source> <target>&Выход</target> -<source>Waiting for missing directories...</source> -<target>Ожидание пропущенных папок...</target> - <source>Invalid command line:</source> <target>ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð½Ð°Ñ Ñтрока:</target> @@ -411,14 +539,14 @@ The command is triggered if: <source>File time and size</source> <target>Дата и размер файла</target> -<source> Two way </source> -<target> Ð’ обе Ñтороны </target> +<source>Two way</source> +<target>Ð’ обе Ñтороны</target> <source>Mirror</source> -<target>Зеркало </target> +<target>Зеркало</target> <source>Update</source> -<target>Обновить </target> +<target>Обновить</target> <source>Custom</source> <target>Выборочно</target> @@ -474,12 +602,6 @@ The command is triggered if: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>Следующие Ñлементы имеют неурегулированные конфликты и не будут Ñинхронизированы:</target> -<source>Significant difference detected:</source> -<target>Обнаружено ÑущеÑтвенное различие:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>Более 50% общего количеÑтва файлов будет Ñкопировано или удалено.</target> - <source>Not enough free disk space available in:</source> <target>Ðе доÑтаточно Ñвободного меÑта в:</target> @@ -498,9 +620,6 @@ The command is triggered if: <source>Generating database...</source> <target>Создание базы данных...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>Создание Тома Теневого ÐšÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ %x...</target> - <source>Data verification error: %x and %y have different content.</source> <target>Ошибка проверки данных: %x и %y имеют разное Ñодержание!</target> @@ -651,8 +770,8 @@ The command is triggered if: <source>&Export file list...</source> <target>&ÐкÑпортировать ÑпиÑок файлов...</target> -<source>&Global settings...</source> -<target>&Глобальные наÑтройки...</target> +<source>&Global settings</source> +<target>&Глобальные наÑтройки</target> <source>&Tools</source> <target>&Опции</target> @@ -732,6 +851,12 @@ The command is triggered if: <source>&Pause</source> <target>&Пауза</target> +<source>Variant</source> +<target>Вариант</target> + +<source>Statistics</source> +<target>СтатиÑтика</target> + <source>Select a variant</source> <target>Выберите вариант</target> @@ -799,27 +924,15 @@ is the same <source>Delete or overwrite files permanently</source> <target>Удалить или перезапиÑать файлы, не Ð¿Ð¾Ð¼ÐµÑ‰Ð°Ñ Ð² "Корзину"</target> -<source>Recycle Bin</source> -<target>ПеремеÑтить в "Корзину"</target> - -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>ИÑпользовать "Корзину" Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð½Ñ‹Ñ… и перезапиÑанных файлов</target> - <source>Versioning</source> <target>Ðрхивировать</target> -<source>Move files to user-defined folder</source> -<target>ПеремеÑтить файлы в пользовательÑкую папку</target> - <source>Naming convention:</source> <target>УÑловие переименованиÑ:</target> <source>Batch job</source> <target>Пакетное задание</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Создайте файл пакетного Ð·Ð°Ð´Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑкой Ñинхронизации. Ð”Ð»Ñ Ð·Ð°Ð¿ÑƒÑка дважды кликните на файле или Ñоздайте раÑпиÑание в планировщике вашей ÑиÑтемы: FreeFileSync.exe <название>.ffs_batch</target> - <source>Exit</source> <target>Выход</target> @@ -871,15 +984,6 @@ is the same <source>Delete on both sides even if the file is selected on one side only</source> <target>Удалить Ñ Ð¾Ð±ÐµÐ¸Ñ… Ñторон, даже еÑли файл выделен только на одной Ñтороне</target> -<source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. -</source> -<target> -Только файлы, ÑоответÑтвующие вÑем наÑтройкам фильтра, будут Ñинхронизированы. -Примечание: Файлы должны отноÑитьÑÑ Ðº Ñинхронизируемым папкам. -</target> - <source>Include</source> <target>Включить</target> @@ -907,21 +1011,12 @@ Note: File names must be relative to base directories. <source>Fail-safe file copy</source> <target>ОтказоуÑтойчивое копирование файла</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>Сначала копировать во временные файлы (*.ffs_tmp), затем переименовывать их. Ðто гарантирует целоÑтноÑÑ‚ÑŒ заменÑемых файлов в Ñлучае Ð²Ð¾Ð·Ð½Ð¸ÐºÐ½Ð¾Ð²ÐµÐ½Ð¸Ñ Ñ„Ð°Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ð¹ ошибки копированиÑ.</target> - <source>Copy locked files</source> <target>Копирование заблокированных файлов</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Копирование общих или заблокированных файлов Ñ Ð¸Ñпользованием Ñлужбы Теневого ÐšÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¢Ð¾Ð¼Ð° (требуютÑÑ Ð¿Ñ€Ð°Ð²Ð° ÐдминиÑтратора)</target> - <source>Copy file access permissions</source> <target>Копирование прав доÑтупа к файлам</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Передача прав доÑтупа к файлам/папкам (требуютÑÑ Ð¿Ñ€Ð°Ð²Ð° ÐдминиÑтратора)</target> - <source>Restore hidden dialogs</source> <target>ВоÑÑтановить Ñкрытые диалоговые окна?</target> @@ -934,15 +1029,6 @@ Note: File names must be relative to base directories. <source>&Default</source> <target>&По умолчанию</target> -<source>Variant</source> -<target>Вариант</target> - -<source>Statistics</source> -<target>СтатиÑтика</target> - -<source>Don't show this dialog again</source> -<target>Больше не показывать Ñто окно</target> - <source>Find what:</source> <target>Ðайти:</target> @@ -952,15 +1038,15 @@ Note: File names must be relative to base directories. <source>&Find next</source> <target>&Ðайти далее</target> +<source>Start synchronization</source> +<target>Ðачать Ñинхронизацию</target> + <source>Delete</source> <target>Удалить</target> <source>Configure filter</source> <target>ÐаÑтройки фильтра</target> -<source>Start synchronization</source> -<target>Ðачать Ñинхронизацию</target> - <source>Find</source> <target>Ðайти</target> @@ -1033,12 +1119,12 @@ Note: File names must be relative to base directories. <source>Include temporarily</source> <target>Временно включить</target> -<source>Exclude via filter:</source> -<target>ИÑключить через фильтр:</target> - <source>multiple selection</source> <target>групповое выделение</target> +<source>Exclude via filter:</source> +<target>ИÑключить через фильтр:</target> + <source>Include all</source> <target>Включить вÑе</target> @@ -1084,9 +1170,6 @@ Note: File names must be relative to base directories. <source>Do&n't save</source> <target>&Ðе ÑохранÑÑ‚ÑŒ</target> -<source>Never save changes</source> -<target>Ðикогда не ÑохранÑÑ‚ÑŒ изменениÑ</target> - <source>Show files that exist on left side only</source> <target>Показать файлы, ÑущеÑтвующие только Ñлева</target> @@ -1138,27 +1221,18 @@ Note: File names must be relative to base directories. <source>All folders are in sync</source> <target>Ð’Ñе папки Ñинхронизированы</target> -<source>Comma separated list</source> -<target>СпиÑок, разделÑемый запÑтыми</target> - <source>File list exported</source> <target>СпиÑок файлов ÑкÑпортирован</target> <source>Searching for program updates...</source> <target>Проверка обновлений программы...</target> -<source>Ignore further errors</source> -<target>Игнорировать поÑледующие ошибки</target> - <source>&Ignore</source> <target>&Игнорировать</target> <source>Fatal Error</source> <target>КритичеÑÐºÐ°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°</target> -<source>Don't show this warning again</source> -<target>Больше не показывать Ñто предупреждение</target> - <source>&Switch</source> <target>&Переключить</target> @@ -1192,15 +1266,6 @@ Note: File names must be relative to base directories. <source>Completed</source> <target>Завершено</target> -<source>Continue</source> -<target>Продолжить</target> - -<source>Pause</source> -<target>Пауза</target> - -<source>Logging</source> -<target>Лог-файлы</target> - <source>Cannot find %x</source> <target>Ðевозможно найти %x</target> @@ -1235,16 +1300,6 @@ Note: File names must be relative to base directories. <target>Фильтр</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> -</source> -<target> -<pluralform>Ð’Ñ‹ точно хотите перемеÑтить Ñледующий %x Ñлемент в "Корзину"?</pluralform> -<pluralform>Ð’Ñ‹ точно хотите перемеÑтить Ñледующие %x Ñлемента в "Корзину"?</pluralform> -<pluralform>Ð’Ñ‹ точно хотите перемеÑтить Ñледующие %x Ñлементов в "Корзину"?</pluralform> -</target> - -<source> <pluralform>Do you really want to delete the following item?</pluralform> <pluralform>Do you really want to delete the following %x items?</pluralform> </source> @@ -1299,9 +1354,6 @@ Note: File names must be relative to base directories. <source>Append a timestamp to each file name</source> <target>Добавить отметку времени Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ имени файла</target> -<source>Folder</source> -<target>Папка</target> - <source>File</source> <target>Файл</target> @@ -1425,9 +1477,6 @@ Note: File names must be relative to base directories. <source>Cannot change process I/O priorities.</source> <target>Ðевозможно изменить приоритет процеÑÑа.</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>Ðевозможно перемеÑтить %x в "Корзину".</target> - <source>Cannot determine final path for %x.</source> <target>Ðевозможно определить конечный путь Ð´Ð»Ñ %x.</target> diff --git a/BUILD/Languages/scottish_gaelic.lng b/BUILD/Languages/scottish_gaelic.lng index 80d0a971..a68e9d6a 100644 --- a/BUILD/Languages/scottish_gaelic.lng +++ b/BUILD/Languages/scottish_gaelic.lng @@ -25,14 +25,14 @@ <source>Checking recycle bin availability for folder %x...</source> <target>A' toirt sùil a bheil am biona ri fhaighin airson a' phasgain %x...</target> -<source>Moving file %x to recycle bin</source> -<target>A' gluasad an fhaidhle %x dhan bhiona ath-chuairteachaidh</target> +<source>Moving file %x to the recycle bin</source> +<target>A' gluasad an fhaidhle %x dhan bhiona</target> -<source>Moving folder %x to recycle bin</source> -<target>A' gluasad a' phasgain %x dhan bhiona ath-chuairteachaidh</target> +<source>Moving folder %x to the recycle bin</source> +<target>A' gluasad a' phasgain %x dhan bhiona</target> -<source>Moving symbolic link %x to recycle bin</source> -<target>A' gluasad an symbolic link %x dhan bhiona ath-chuairteachaidh</target> +<source>Moving symbolic link %x to the recycle bin</source> +<target>A' gluasad an symbolic link %x dhan bhiona</target> <source>Deleting file %x</source> <target>A' sguabadh à s an fhaidhle %x</target> @@ -43,14 +43,20 @@ <source>Deleting symbolic link %x</source> <target>A' sguabadh à s an symbolic link %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>Chan eil am biona ri là imh nam pasganan a leanas. Thèid na faidhlichean a sguabadh à s gu buan an à ite sin:</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>Chan eil am biona ri là imh airson nam pasganan a leanas. Thèid an sguabadh à s gu buan an à ite sin:</target> <source>An exception occurred</source> <target>Thachair eisgeachd</target> -<source>Cannot find file %x.</source> -<target>Cha deach am faidhle %x a lorg.</target> +<source>A directory path is expected after %x.</source> +<target>Tha dùil ri slighe pasgain an dèidh %x</target> + +<source>Syntax error</source> +<target>Mearachd co-chà raidh</target> + +<source>Cannot open file %x.</source> +<target>Cha ghabh am faidhle %x fhosgladh.</target> <source>Error</source> <target>Mearachd</target> @@ -58,6 +64,36 @@ <source>File %x does not contain a valid configuration.</source> <target>Chan eil rèiteachadh dligheach san fhaidhle %x.</target> +<source>Unequal number of left and right directories specified.</source> +<target>Chan eil à ireamh nam pasganan air an taobh chlì 's an taobh deas co-ionnann</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>Chan fhaod roghainnean aig ìre paidhrichean nam pasganan a bhith san fhaidhle rèiteachaidh nuair a thathar a' cur pasganan slighe na loidhne-à ithne.</target> + +<source>Warning</source> +<target>Rabhadh</target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target>Cha ghabh pasganan a shuidheachadh airson barrachd air aon fhaidhle rèiteachaidh.</target> + +<source>Syntax:</source> +<target>Co-chà radh:</target> + +<source>config files</source> +<target>faidhlichean rèiteachaidh</target> + +<source>directory</source> +<target>pasgan</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>Àireamh sam bith de dh'fhaidhlichean rèiteachaidh FreeFileSync .ffs_gui agus/no .ffs_batch</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>Àireamh sam bith de phasganan eile airson aon fhaidhle rèiteachaidh air a' char as fhaide.</target> + +<source>Command line</source> +<target>Loidhne-à ithne</target> + <source>A folder input field is empty.</source> <target>Tha co-dhiù aon raon pasgain ann a tha falamh.</target> @@ -217,14 +253,14 @@ <target>An ùine gu lèir:</target> <source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </source> <target> -<pluralform>%x bhaidht</pluralform> -<pluralform>%x bhaidht</pluralform> -<pluralform>%x baidht</pluralform> -<pluralform>%x baidht</pluralform> +<pluralform>%x byte</pluralform> +<pluralform>%x bytes</pluralform> +<pluralform>%x bytes</pluralform> +<pluralform>%x bytes</pluralform> </target> <source>%x MB</source> @@ -246,14 +282,14 @@ <target>'Ga sganadh:</target> <source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </source> <target> -<pluralform>[%x snà ithlean]</pluralform> -<pluralform>[%x shnà ithlean]</pluralform> -<pluralform>[%x snà ithleanan]</pluralform> -<pluralform>[%x snà ithlean]</pluralform> +<pluralform>%x shnà ithlean</pluralform> +<pluralform>%x shnà ithlean</pluralform> +<pluralform>%x snà ithleanan</pluralform> +<pluralform>%x snà ithlean</pluralform> </target> <source>Encoding extended time information: %x</source> @@ -262,6 +298,9 @@ <source>/sec</source> <target>/diog</target> +<source>%x items</source> +<target>%x nithean</target> + <source>Configuration file %x loaded partially only.</source> <target>Cha deach faidhle an rèiteachaidh %x a luchdadh gu tur.</target> @@ -274,8 +313,8 @@ <source>Browse directory</source> <target>Rùraich am pasgan</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Chan fhaigh sinn cothrom air seirbheis lethbhreacan-sgà ile nan clà r.</target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target>Chan fhaigh sinn cothrom air seirbheise lethbhreacan sgà il an draibh.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>Nach cleachd sibh an tionndadh 64 biot de FreeFileSync gus lethbhreacan-sgà ile a chruthachadh air an t-siostam seo?</target> @@ -286,8 +325,8 @@ <source>Cannot determine volume name for %x.</source> <target>Chan urrainn dhuinn ainm an draibh airson %x a dhearbhadh.</target> -<source>Volume name %x not part of file name %y.</source> -<target>Chan eil an t-ainm clà ir %x 'na phà irt dhen ainm fhaidhle %y.</target> +<source>Volume name %x is not part of file path %y.</source> +<target>Chan eil ainm an draibh %x 'na phà irt de shlighe an fhaodhle %y.</target> <source>Abort requested: Waiting for current operation to finish...</source> <target>Tha thu airson sgur dheth: A' feitheamh gus an crìochnaich an gnìomh là ithreach...</target> @@ -355,9 +394,6 @@ <source>Idle time between last detected change and execution of command</source> <target>An tà mh eadar an t-atharrachadh mu dheireadh agus gnìomhachadh na h-à ithne</target> -<source>Command line</source> -<target>Loidhne-à ithne</target> - <source> The command is triggered if: - files or subfolders change @@ -381,9 +417,6 @@ Thèid an loidhne-à ithne a chur gu dol: <source>RealtimeSync - Automated Synchronization</source> <target>RealtimeSync - Sioncronachadh fèin-obrachail</target> -<source>Warning</source> -<target>Rabhadh</target> - <source>Build: %x</source> <target>Build: %x</target> @@ -393,15 +426,21 @@ Thèid an loidhne-à ithne a chur gu dol: <source>All files</source> <target>Gach faidhle</target> +<source>Directory monitoring active</source> +<target>Tha na pasganan 'gam marasgladh</target> + +<source>Waiting until all directories are available...</source> +<target>A' feitheamh gus am bi gach pasgan ri là imh...</target> + <source>&Restore</source> <target>&Aisig</target> +<source>&Show error</source> +<target>&Seall a' mhearachd</target> + <source>&Exit</source> <target>&Fà g an-seo</target> -<source>Waiting for missing directories...</source> -<target>A' feitheamh ris na pasgain a tha a dhìth...</target> - <source>Invalid command line:</source> <target>Loidhne-à ithne mhì-dhligheach:</target> @@ -411,14 +450,14 @@ Thèid an loidhne-à ithne a chur gu dol: <source>File time and size</source> <target>Ceann-là is meud</target> -<source> Two way </source> -<target> An dà chomhair </target> +<source>Two way</source> +<target>An dà chomhair</target> <source>Mirror</source> -<target>Sgà thanaich </target> +<target>Sgà thanaich</target> <source>Update</source> -<target>Ùraich </target> +<target>Ùraich</target> <source>Custom</source> <target>Gnà thaichte</target> @@ -474,11 +513,8 @@ Thèid an loidhne-à ithne a chur gu dol: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>Tha còmstrithean aig na nithean a leanas fhathast is cha dèid an sioncronachadh:</target> -<source>Significant difference detected:</source> -<target>Chaidh diofar mòr a lorg:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>Tha thu an impis barrachd air an dà rna leth dhe na faidhlichean uile sguabadh à s no lethbhreac a dhèanamh dhiubh.</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>Tha diofar mòr eadar na pasganan a leanas. Dèan cinnteach gu bheil thu a' maidseadh nam pasganan ceart airson sioncronachadh.</target> <source>Not enough free disk space available in:</source> <target>Chan eil rùm saor gu leòr air an diosga:</target> @@ -498,12 +534,15 @@ Thèid an loidhne-à ithne a chur gu dol: <source>Generating database...</source> <target>A' gintinn an stòir-dhà ta...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>A' cruthachadh Volume Shadow Copy de %x...</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>A' cruthachadh lethbhreac sgà il draibh airson %x...</target> <source>Data verification error: %x and %y have different content.</source> <target>Mearachd le dearbhadh an dà ta: tha susbaint eadar-dhealaichte ann an %x agus %y.</target> +<source>job name</source> +<target>ainm na h-obrach</target> + <source>Synchronization aborted</source> <target>Sguireadh dhen t-sioncronachadh</target> @@ -528,6 +567,9 @@ Thèid an loidhne-à ithne a chur gu dol: <source>Switching to FreeFileSync main dialog</source> <target>A' gearradh leum gu FreeFileSync sa phrìomh-chòmhradh</target> +<source>Retrying operation after error:</source> +<target>A' feuchainn ris an dèidh na mearachd:</target> + <source>A new version of FreeFileSync is available:</source> <target>Tha tionndadh ùr de FreeFileSync ann:</target> @@ -651,8 +693,8 @@ Thèid an loidhne-à ithne a chur gu dol: <source>&Export file list...</source> <target>Às-p&hortaich liosta nam faidhle...</target> -<source>&Global settings...</source> -<target>&Na roghainnean uile-choitcheann...</target> +<source>&Global settings</source> +<target>&Na roghainnean uile-choitcheann</target> <source>&Tools</source> <target>&Innealan</target> @@ -669,12 +711,6 @@ Thèid an loidhne-à ithne a chur gu dol: <source>Compare</source> <target>Dèan coimeas</target> -<source>Comparison settings</source> -<target>Roghainnean a' choimeasaidh</target> - -<source>Synchronization settings</source> -<target>Roghainnean an t-sioncronachaidh</target> - <source>Synchronize</source> <target>Dèan sioncronachadh</target> @@ -723,6 +759,9 @@ Thèid an loidhne-à ithne a chur gu dol: <source>Synchronizing...</source> <target>A' sioncronachadh...</target> +<source>Minimize to notification area</source> +<target>Lùghdach 's gluais gu raon nam brathan</target> + <source>On completion</source> <target>Nuair a bhios e deiseil</target> @@ -732,6 +771,15 @@ Thèid an loidhne-à ithne a chur gu dol: <source>&Pause</source> <target>&Cuir 'na stad</target> +<source>Variant</source> +<target>Eugsamhail</target> + +<source>Statistics</source> +<target>Stats</target> + +<source>&Don't show this dialog again</source> +<target>&Na seall an còmhradh seo a-rithist</target> + <source>Select a variant</source> <target>Tagh eug-samhail</target> @@ -779,6 +827,12 @@ Bidh dà fhaidhle co-ionnann 'nar beachd-sa <source>Configure your own synchronization rules.</source> <target>Sònraich riaghailtean sioncronachaidh thu fhèin.</target> +<source>Detect moved files</source> +<target>Mothaich do dh'fhaidhlichean a chaidh a ghluasad</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Feumaidh seo faidhlichean stòir-dhà ta. Chan eil gach siostam fhaidhlichean a' cur taic ri seo.</target> + <source>Error handling</source> <target>Là imhseachadh mhearachdan</target> @@ -803,17 +857,17 @@ Bidh dà fhaidhle co-ionnann 'nar beachd-sa <source>Delete or overwrite files permanently</source> <target>Sguab à s no sgrìobh thairis air faidhlichean gu buan</target> -<source>Recycle Bin</source> -<target>Am biona ath-chuairteachaidh</target> +<source>Recycle bin</source> +<target>Am biona</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Cuir na chaidh a sguabadh as no sgrìobhadh thairis air sa bhiona ath-chuairteachaidh</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Dèan lethbhreac-glèidhidh de dh'fhaidhlichean sa bhiona a chaidh a sguabadh à s no a chaidh sgrìobhadh thairis orra</target> <source>Versioning</source> <target>Versioning</target> -<source>Move files to user-defined folder</source> -<target>Gluais na faidhlichean dhan phasgan a shònraich an cleachdaiche</target> +<source>Move files to a user-defined folder</source> +<target>Gluais na faidhlichean gu à ite a shònraich an cleachdaiche</target> <source>Naming convention:</source> <target>Gnà thas nan ainmean:</target> @@ -821,8 +875,8 @@ Bidh dà fhaidhle co-ionnann 'nar beachd-sa <source>Batch job</source> <target>Obair baidse</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Cruthaich faidhle batch airson sioncronachadh fèin-obrachail. Dèan briogadh dùbailte air an fhaidhle seo no cuir e air sgeideal an t-siostaim agad: FreeFileSync.exe <Jobname>.ffs_batch.</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Cruthaich faidhle batch airson sioncronachadh a dh'obraicheas gun thusa a bhith an là thair. Gus a thòiseachadh, dèan briogadh dùbailte air an fhaidhle seo ann am planadair shaothraichean: %x</target> <source>Exit</source> <target>Fà g an-seo</target> @@ -845,30 +899,6 @@ Bidh dà fhaidhle co-ionnann 'nar beachd-sa <source>Limit maximum number of log files</source> <target>Cuingich an à ireamh as motha de dh'fhaidhlichean an loga</target> -<source>Source code written in C++ using:</source> -<target>Chaidh an còd tùsail a sgrìobhadh ann an C++ le taic:</target> - -<source>If you like FreeFileSync</source> -<target>Ma tha FreeFileSync a' còrdadh riut</target> - -<source>Donate with PayPal</source> -<target>Nach doir sibh tabhartas le PayPal?</target> - -<source>Many thanks for localization:</source> -<target>Tha sinn fada an comain nan daoine a leanas airson eadar-theangachadh:</target> - -<source>Feedback and suggestions are welcome</source> -<target>Tha sinn a' cur fà ilte mhòr air beachd is moladh sam bith</target> - -<source>Homepage</source> -<target>An duilleag-dhachaigh</target> - -<source>Email</source> -<target>Post-d</target> - -<source>Published under the GNU General Public License</source> -<target>Air fhoillseachadh fo GNU General Public License</target> - <source>Delete on both sides</source> <target>Sguab à s air an dà thaobh</target> @@ -876,12 +906,12 @@ Bidh dà fhaidhle co-ionnann 'nar beachd-sa <target>Sguab à s air an dà thaobh fiù mur an deach am faidhle a thaghadh ach air aon taobh</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -Cha dèid ach na faidhlichean a fhreagras ri gach roghainn na criathraige a shioncronachadh. -An aire: Feumaidh ainmean nam faidhlichean a bhi dà imheach ris na bun-phasgain aca. +Cha dèidh faidhlichean a shioncronachadh ach ma choileanas iad gach riaghailte na criathraige. +An aire: Feumaidh slighean nam faidhlichean a bhith dà imheach ris na bun-phasganan. </target> <source>Include</source> @@ -911,20 +941,20 @@ An aire: Feumaidh ainmean nam faidhlichean a bhi dà imheach ris na bun-phasgain <source>Fail-safe file copy</source> <target>Dèan lethbhreac nach gabh fà illigeadh</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>Sgrìobh faidhle sealach (*.ffs_tmp) an toiseach agus cuir ainm eile air an uairsin. Bidh seo mar bharantas air staid sheasmhach, fiù ma thachras mearachd mharbhtach.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>Cuir lethbhreac dheth ann am faidhle sealach (*.ffs_tmp) an toiseach is thoir ainm ùr air an uairsin. Leis a seo, bidh staid sheasmhach agad fiù ma thachras mearachd mharbhtach.</target> <source>Copy locked files</source> <target>Dèan lethbhreac de dh'fhaidhlichean glaiste</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Dèan lethbhreac de dh'fhaidhlichean glaiste no co-roinnte le seirbheis lethbhreacan-sgà ile nan clà r (feumaidh seo còraichean rianaire)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>Dèan lethbhreac de dh'fhaidhlichean co-roinnte no glaiste le seirbheis lethbhreacan sgà il an draibh (feumaidh seo còraichean rianaire)</target> <source>Copy file access permissions</source> <target>Dèan lethbhreac de cheadan-inntrigidh nam faidhle</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Tar-chuir ceadan nam faidhle 's nam pasgan (feumaidh seo còraichean rianaire)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>Tar-chuir ceadan nam faidhlichean 's nam pasganan (feumaidh seo còraichean rianaire)</target> <source>Restore hidden dialogs</source> <target>Aisig na còmhraidhean falaichte</target> @@ -938,15 +968,6 @@ An aire: Feumaidh ainmean nam faidhlichean a bhi dà imheach ris na bun-phasgain <source>&Default</source> <target>&Bun-roghainn</target> -<source>Variant</source> -<target>Eugsamhail</target> - -<source>Statistics</source> -<target>Stats</target> - -<source>Don't show this dialog again</source> -<target>Na seall an còmhradh seo a-rithist</target> - <source>Find what:</source> <target>Lorg na leanas:</target> @@ -956,15 +977,45 @@ An aire: Feumaidh ainmean nam faidhlichean a bhi dà imheach ris na bun-phasgain <source>&Find next</source> <target>&Lorg an ath-fhear</target> +<source>Source code written in C++ using:</source> +<target>Chaidh an còd tùsail a sgrìobhadh ann an C++ le taic:</target> + +<source>If you like FreeFileSync</source> +<target>Ma tha FreeFileSync a' còrdadh riut</target> + +<source>Donate with PayPal</source> +<target>Nach doir sibh tabhartas le PayPal?</target> + +<source>Feedback and suggestions are welcome</source> +<target>Tha sinn a' cur fà ilte mhòr air beachd is moladh sam bith</target> + +<source>Homepage</source> +<target>An duilleag-dhachaigh</target> + +<source>Email</source> +<target>Post-d</target> + +<source>Published under the GNU General Public License</source> +<target>Air fhoillseachadh fo GNU General Public License</target> + +<source>Many thanks for localization:</source> +<target>Tha sinn fada an comain nan daoine a leanas airson eadar-theangachadh:</target> + +<source>Start synchronization</source> +<target>Tòisich air an t-sioncronachadh</target> + +<source>Comparison settings</source> +<target>Roghainnean a' choimeasaidh</target> + +<source>Synchronization settings</source> +<target>Roghainnean an t-sioncronachaidh</target> + <source>Delete</source> <target>Sguab à s</target> <source>Configure filter</source> <target>Rèitich a' chriathrag</target> -<source>Start synchronization</source> -<target>Tòisich air an t-sioncronachadh</target> - <source>Find</source> <target>Lorg</target> @@ -999,6 +1050,23 @@ An aire: Feumaidh ainmean nam faidhlichean a bhi dà imheach ris na bun-phasgain <target>Dèan coimeas air an dà thaobh</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>A bheil thu cinnteach gu bheil thu airson an à ithne %y a ruith air %x nì?</pluralform> +<pluralform>A bheil thu cinnteach gu bheil thu airson an à ithne %y a ruith air %x nì?</pluralform> +<pluralform>A bheil thu cinnteach gu bheil thu airson an à ithne %y a ruith air %x nithean?</pluralform> +<pluralform>A bheil thu cinnteach gu bheil thu airson an à ithne %y a ruith air %x nì?</pluralform> +</target> + +<source>Confirm</source> +<target>Dearbh</target> + +<source>&Execute</source> +<target>&Cuir an gnìomh</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1040,12 +1108,15 @@ An aire: Feumaidh ainmean nam faidhlichean a bhi dà imheach ris na bun-phasgain <source>Include temporarily</source> <target>Gabh a-steach gu sealach</target> -<source>Exclude via filter:</source> -<target>Dùin a-mach le criathrag:</target> - <source>multiple selection</source> <target>Ioma-thaghadh</target> +<source>Include via filter:</source> +<target>Gach a-steach slighe na criathraige:</target> + +<source>Exclude via filter:</source> +<target>Dùin a-mach le criathrag:</target> + <source>Include all</source> <target>Gabh a-steach na h-uile</target> @@ -1091,8 +1162,8 @@ An aire: Feumaidh ainmean nam faidhlichean a bhi dà imheach ris na bun-phasgain <source>Do&n't save</source> <target>&Na sà bhail</target> -<source>Never save changes</source> -<target>Na sà bhail atharraichean idir</target> +<source>Never save &changes</source> +<target>Na sà bhail atharrai&chean idir</target> <source>Show files that exist on left side only</source> <target>Na seall ach faidhlichean a tha air an taobh chlì a-mhà in</target> @@ -1145,8 +1216,8 @@ An aire: Feumaidh ainmean nam faidhlichean a bhi dà imheach ris na bun-phasgain <source>All folders are in sync</source> <target>Tha gach pasgan air a shioncronachadh</target> -<source>Comma separated list</source> -<target>Liosta air a sgaradh le cromagan</target> +<source>Comma-separated values</source> +<target>Luachan le cromagan eatarra</target> <source>File list exported</source> <target>Chaidh liosta nam faidhle à s-phortadh</target> @@ -1154,8 +1225,8 @@ An aire: Feumaidh ainmean nam faidhlichean a bhi dà imheach ris na bun-phasgain <source>Searching for program updates...</source> <target>A' lorg ùrachaidhean a' phrògraim...</target> -<source>Ignore further errors</source> -<target>Leig seachad mearachd sam bith eile</target> +<source>&Ignore subsequent errors</source> +<target>Le&ig seachad mearachdan à s a dhèidh seo</target> <source>&Ignore</source> <target>&Leig seachad</target> @@ -1163,8 +1234,8 @@ An aire: Feumaidh ainmean nam faidhlichean a bhi dà imheach ris na bun-phasgain <source>Fatal Error</source> <target>Mearachd mharbhtach</target> -<source>Don't show this warning again</source> -<target>Na seall an rabhadh seo a-rithist</target> +<source>&Don't show this warning again</source> +<target>Na seall an rabha&dh seo a-rithist</target> <source>&Switch</source> <target>&Dèan suids</target> @@ -1199,14 +1270,11 @@ An aire: Feumaidh ainmean nam faidhlichean a bhi dà imheach ris na bun-phasgain <source>Completed</source> <target>Deiseil</target> -<source>Continue</source> -<target>Lean air</target> +<source>&Continue</source> +<target>Lean air adhar&t</target> -<source>Pause</source> -<target>Cuir 'na stad</target> - -<source>Logging</source> -<target>Logadh</target> +<source>Log</source> +<target>Logaich</target> <source>Cannot find %x</source> <target>Chan urrainn dhuinn %x a lorg.</target> @@ -1242,14 +1310,14 @@ An aire: Feumaidh ainmean nam faidhlichean a bhi dà imheach ris na bun-phasgain <target>Criathrag</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>A bheil thu cinnteach gu bheil thu airson an %x nì seo a ghluasad dhan bhiona?</pluralform> -<pluralform>A bheil thu cinnteach gu bheil thu airson na %x nì seo a ghluasad dhan bhiona?</pluralform> -<pluralform>A bheil thu cinnteach gu bheil thu airson na %x nithean seo a ghluasad dhan bhiona?</pluralform> -<pluralform>A bheil thu cinnteach gu bheil thu airson na %x nì seo a ghluasad dhan bhiona?</pluralform> +<pluralform>A bheil thu cinnteach gu bheil thu airson an %x nì seo a chur dhan bhiona?</pluralform> +<pluralform>A bheil thu cinnteach gu bheil thu airson an %x nì seo a chur dhan bhiona?</pluralform> +<pluralform>A bheil thu cinnteach gu bheil thu airson na %x nithean seo a chur dhan bhiona?</pluralform> +<pluralform>A bheil thu cinnteach gu bheil thu airson an %x nì seo a chur dhan bhiona?</pluralform> </target> <source> @@ -1305,9 +1373,6 @@ An aire: Feumaidh ainmean nam faidhlichean a bhi dà imheach ris na bun-phasgain <source>Append a timestamp to each file name</source> <target>Cuir stampa-ama ris ainm gach faidhle</target> -<source>Folder</source> -<target>Pasgan</target> - <source>File</source> <target>Faidhle</target> @@ -1434,8 +1499,8 @@ An aire: Feumaidh ainmean nam faidhlichean a bhi dà imheach ris na bun-phasgain <source>Cannot change process I/O priorities.</source> <target>Chan urrainn dhuinn na prìomhachasan I/O atharrachadh.</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>Chan urrainn dhuinn %x a ghluasad dhan bhiona ath-chuairteachaidh.</target> +<source>Unable to move %x to the recycle bin.</source> +<target>Cha ghabh %x a ghluasad dhan bhiona.</target> <source>Cannot determine final path for %x.</source> <target>Chan urrainn dhuinn an t-slighe dheireannach airson %x a dhearbhadh.</target> diff --git a/BUILD/Languages/serbian.lng b/BUILD/Languages/serbian.lng index f0a26e49..9af8b193 100644 --- a/BUILD/Languages/serbian.lng +++ b/BUILD/Languages/serbian.lng @@ -7,6 +7,178 @@ <plural_definition>n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2</plural_definition> </header> +<source>Unable to move %x to the recycle bin.</source> +<target></target> + +<source> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> +</source> +<target> +</target> + +<source>Log</source> +<target></target> + +<source>&Continue</source> +<target></target> + +<source>&Don't show this warning again</source> +<target></target> + +<source>&Ignore subsequent errors</source> +<target></target> + +<source>Comma-separated values</source> +<target></target> + +<source>Never save &changes</source> +<target></target> + +<source>Include via filter:</source> +<target></target> + +<source>&Execute</source> +<target></target> + +<source>Confirm</source> +<target></target> + +<source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +</target> + +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target></target> + +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target></target> + +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target></target> + +<source> +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. +</source> +<target></target> + +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target></target> + +<source>Move files to a user-defined folder</source> +<target></target> + +<source>Back up deleted and overwritten files in the recycle bin</source> +<target></target> + +<source>Recycle bin</source> +<target></target> + +<source>Requires database files. Not supported by all file systems.</source> +<target></target> + +<source>Detect moved files</source> +<target></target> + +<source>&Don't show this dialog again</source> +<target></target> + +<source>Minimize to notification area</source> +<target></target> + +<source>Retrying operation after error:</source> +<target></target> + +<source>job name</source> +<target></target> + +<source>Creating a Volume Shadow Copy for %x...</source> +<target></target> + +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target></target> + +<source>&Show error</source> +<target></target> + +<source>Waiting until all directories are available...</source> +<target></target> + +<source>Directory monitoring active</source> +<target></target> + +<source>Volume name %x is not part of file path %y.</source> +<target></target> + +<source>Cannot access the Volume Shadow Copy Service.</source> +<target></target> + +<source>%x items</source> +<target></target> + +<source> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> +</source> +<target> +</target> + +<source> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> +</source> +<target> +</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target></target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target></target> + +<source>directory</source> +<target></target> + +<source>config files</source> +<target></target> + +<source>Syntax:</source> +<target></target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target></target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target></target> + +<source>Unequal number of left and right directories specified.</source> +<target></target> + +<source>Cannot open file %x.</source> +<target></target> + +<source>Syntax error</source> +<target></target> + +<source>A directory path is expected after %x.</source> +<target></target> + +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target></target> + +<source>Moving symbolic link %x to the recycle bin</source> +<target></target> + +<source>Moving folder %x to the recycle bin</source> +<target></target> + +<source>Moving file %x to the recycle bin</source> +<target></target> + <source>Both sides have changed since last synchronization.</source> <target>Обе Ñу Ñтране промењене од поÑледње Ñинхронизације.</target> @@ -25,15 +197,6 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Проверавам доÑтупноÑÑ‚ Корпе за Ñмеће за фолдер %x...</target> -<source>Moving file %x to recycle bin</source> -<target>Премештам датотеку %x у Корпи за Ñмеће</target> - -<source>Moving folder %x to recycle bin</source> -<target>Премештам фолдер %x у Корпи за Ñмеће</target> - -<source>Moving symbolic link %x to recycle bin</source> -<target>Премештам Ñимболичну везу %x у Корпи за Ñмеће</target> - <source>Deleting file %x</source> <target>БриÑање датотеке %x</target> @@ -43,21 +206,21 @@ <source>Deleting symbolic link %x</source> <target>БриÑање Ñимболичне везе %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>Корпа за Ñмеће није доÑтупна за Ñледеће фолдере. УмеÑто тога датотеке биће обриÑане трајно:</target> - <source>An exception occurred</source> <target>Догодило Ñе изузеће</target> -<source>Cannot find file %x.</source> -<target>Ðе могу пронаћи датотеку %x.</target> - <source>Error</source> <target>Грешка</target> <source>File %x does not contain a valid configuration.</source> <target>Датотека %x не Ñадржи валидну конфигурацију.</target> +<source>Warning</source> +<target>Упозорење</target> + +<source>Command line</source> +<target>Командна линија</target> + <source>A folder input field is empty.</source> <target>Поље за одабир фолдера је празно.</target> @@ -215,16 +378,6 @@ <source>Total time:</source> <target>Укупно време:</target> -<source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> -</source> -<target> -<pluralform>%x Бајт</pluralform> -<pluralform>%x Бајта</pluralform> -<pluralform>%x Бајтова</pluralform> -</target> - <source>%x MB</source> <target>%x MB</target> @@ -243,16 +396,6 @@ <source>Scanning:</source> <target>Претражујем:</target> -<source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> -</source> -<target> -<pluralform>[%x Ðит]</pluralform> -<pluralform>[%x Ðити]</pluralform> -<pluralform>[%x Ðити]</pluralform> -</target> - <source>Encoding extended time information: %x</source> <target>Кодирам проширене информације о времену: %x</target> @@ -271,9 +414,6 @@ <source>Browse directory</source> <target>Одабери фолдер</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Ðе могу приÑтупити Volume Shadow Copy СервиÑу.</target> - <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>Молимо кориÑтите FreeFileSync 64-битну верзију за израду shadow копија на овом ÑиÑтему.</target> @@ -283,9 +423,6 @@ <source>Cannot determine volume name for %x.</source> <target>Ðе могу утврдити назив партиције за %x.</target> -<source>Volume name %x not part of file name %y.</source> -<target>Ðазив партиције %x није део имена датотеке %y.</target> - <source>Abort requested: Waiting for current operation to finish...</source> <target>Прекид захтеван: Чека Ñе да Ñе тренутна акција заврши...</target> @@ -352,9 +489,6 @@ <source>Idle time between last detected change and execution of command</source> <target>Време мировања између задње препознате промене и извршења наредбе</target> -<source>Command line</source> -<target>Командна линија</target> - <source> The command is triggered if: - files or subfolders change @@ -378,9 +512,6 @@ The command is triggered if: <source>RealtimeSync - Automated Synchronization</source> <target>RealtimeSync - ÐутоматÑка Синхронизација</target> -<source>Warning</source> -<target>Упозорење</target> - <source>Build: %x</source> <target>Подверзија: %x</target> @@ -396,9 +527,6 @@ The command is triggered if: <source>&Exit</source> <target>&Излаз</target> -<source>Waiting for missing directories...</source> -<target>Чека Ñе недоÑтајући фолдери...</target> - <source>Invalid command line:</source> <target>Ðетачна командна линија:</target> @@ -408,14 +536,14 @@ The command is triggered if: <source>File time and size</source> <target>Време и величина датотеке</target> -<source> Two way </source> -<target> ДвоÑмерно </target> +<source>Two way</source> +<target>ДвоÑмерно</target> <source>Mirror</source> -<target>Огледално </target> +<target>Огледално</target> <source>Update</source> -<target>Ðжурирарно </target> +<target>Ðжурирарно</target> <source>Custom</source> <target>Специфично</target> @@ -471,12 +599,6 @@ The command is triggered if: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>Следеће Ñтавке имају неразрешених конфликата и неће бити Ñинхронизоване:</target> -<source>Significant difference detected:</source> -<target>Значајна разлика опажена:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>Више од 50% од укупног броја датотека ће бити копирано или избриÑано.</target> - <source>Not enough free disk space available in:</source> <target>Ðедовољно проÑтора на диÑку у:</target> @@ -495,9 +617,6 @@ The command is triggered if: <source>Generating database...</source> <target>ГенериÑање базе података...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>Креирање Volume Shadow Copy за %x...</target> - <source>Data verification error: %x and %y have different content.</source> <target>Грешка при провери података: %x и %y имају различит Ñадржај.</target> @@ -648,8 +767,8 @@ The command is triggered if: <source>&Export file list...</source> <target>&Извоз лиÑте датотека...</target> -<source>&Global settings...</source> -<target>&Глобална подешавања...</target> +<source>&Global settings</source> +<target>&Глобална подешавања</target> <source>&Tools</source> <target>&Ðлати</target> @@ -729,6 +848,12 @@ The command is triggered if: <source>&Pause</source> <target>&Пауза</target> +<source>Variant</source> +<target>Варијанта</target> + +<source>Statistics</source> +<target>СтатиÑтика</target> + <source>Select a variant</source> <target>Одаберите варијанту</target> @@ -801,27 +926,15 @@ is the same <source>Delete or overwrite files permanently</source> <target>Трајно избриши или замени датотеке</target> -<source>Recycle Bin</source> -<target>Корпа за Ñмеће</target> - -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>КориÑти Корпу за Ñмеће за избриÑане и замењене датотеке</target> - <source>Versioning</source> <target>Верзионирање</target> -<source>Move files to user-defined folder</source> -<target>ПремеÑти датотеке у кориÑнички одабран фолдер</target> - <source>Naming convention:</source> <target>Правило именовања:</target> <source>Batch job</source> <target>Беч задатак</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Креирајте беч датотеку за аутоматÑку Ñинхронизацију. Дупли клик на ову датотеку или додајте задатак у вашем таÑк менаџеру: FreeFileSync.exe <назив задатка>.ffs_batch</target> - <source>Exit</source> <target>Изађи</target> @@ -873,15 +986,6 @@ is the same <source>Delete on both sides even if the file is selected on one side only</source> <target>Избриши на обе Ñтране чак иако је датотека Ñелектована Ñамо на једној Ñтрани</target> -<source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. -</source> -<target> -Само датотеке које одговарају Ñвим филтерÑким подешавањима биће Ñинхронизоване. -Ðапомена: Имена датотека морају бити релативна према оÑновним фолдерима. -</target> - <source>Include</source> <target>Укључи</target> @@ -909,21 +1013,12 @@ Note: File names must be relative to base directories. <source>Fail-safe file copy</source> <target>Копирање заштићено од грешака</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>Запиши у привремену датотеку (*.ffs_tmp) прво, а онда је преименуј. Ово гарантује непромењивоÑÑ‚ чак и у Ñлучају критичне грешке.</target> - <source>Copy locked files</source> <target>Копирај закључане датотеке</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Копирај дељене или закључане датотеке кориÑтећи Volume Shadow Copy Ð¡ÐµÑ€Ð²Ð¸Ñ (Потребна админиÑтраторÑка права)</target> - <source>Copy file access permissions</source> <target>Копирај овлашћења приÑтупа датотекама</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>ПремеÑти овлашћења приÑтупа датотека (Потребна админиÑтраторÑка права)</target> - <source>Restore hidden dialogs</source> <target>Прикажи Ñкривене диалоге</target> @@ -936,15 +1031,6 @@ Note: File names must be relative to base directories. <source>&Default</source> <target>&Подразумевано</target> -<source>Variant</source> -<target>Варијанта</target> - -<source>Statistics</source> -<target>СтатиÑтика</target> - -<source>Don't show this dialog again</source> -<target>Ðе приказуј овај диалог поновно</target> - <source>Find what:</source> <target>Ðађи шта:</target> @@ -954,15 +1040,15 @@ Note: File names must be relative to base directories. <source>&Find next</source> <target>&Ðађи Ñледеће</target> +<source>Start synchronization</source> +<target>Почни Ñинхронизацију</target> + <source>Delete</source> <target>Избриши</target> <source>Configure filter</source> <target>Конфигуриши филтер</target> -<source>Start synchronization</source> -<target>Почни Ñинхронизацију</target> - <source>Find</source> <target>Пронађи</target> @@ -1035,12 +1121,12 @@ Note: File names must be relative to base directories. <source>Include temporarily</source> <target>Тренутно укључи</target> -<source>Exclude via filter:</source> -<target>ИÑкључи преко филтера:</target> - <source>multiple selection</source> <target>вишеÑтруки одабир</target> +<source>Exclude via filter:</source> +<target>ИÑкључи преко филтера:</target> + <source>Include all</source> <target>Укључи Ñве</target> @@ -1086,9 +1172,6 @@ Note: File names must be relative to base directories. <source>Do&n't save</source> <target>Ðе&мој Ñачувати</target> -<source>Never save changes</source> -<target>Ðемој никад Ñачувати промене</target> - <source>Show files that exist on left side only</source> <target>Прикажи датотеке које поÑтоје Ñамо на левој Ñтрани</target> @@ -1140,27 +1223,18 @@ Note: File names must be relative to base directories. <source>All folders are in sync</source> <target>Сви фолдери Ñу Ñинхронизовани</target> -<source>Comma separated list</source> -<target>Зарезом одвојене лиÑте</target> - <source>File list exported</source> <target>ЛиÑта датотека екÑпортована</target> <source>Searching for program updates...</source> <target>Претражујем ажурирање за програм...</target> -<source>Ignore further errors</source> -<target>Занемари даље грешке</target> - <source>&Ignore</source> <target>&Игнориши</target> <source>Fatal Error</source> <target>Критична грешка</target> -<source>Don't show this warning again</source> -<target>Ðе приказуј ово упозорење поновно</target> - <source>&Switch</source> <target>&Замени</target> @@ -1194,15 +1268,6 @@ Note: File names must be relative to base directories. <source>Completed</source> <target>Завршено</target> -<source>Continue</source> -<target>ÐаÑтави</target> - -<source>Pause</source> -<target>Пауза</target> - -<source>Logging</source> -<target>Лог запиÑивање</target> - <source>Cannot find %x</source> <target>Ðемогу пронаћи %x</target> @@ -1237,16 +1302,6 @@ Note: File names must be relative to base directories. <target>Филтрирање</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> -</source> -<target> -<pluralform>Да ли Ñтварно желите да премеÑтите Ñледећу %x Ñтавку у Корпи за Ñмеће?</pluralform> -<pluralform>Да ли Ñтварно желите да премеÑтите Ñледеће %x Ñтавке у Корпи за Ñмеће?</pluralform> -<pluralform>Да ли Ñтварно желите да премеÑтите Ñледећих %x Ñтавки у Корпи за Ñмеће?</pluralform> -</target> - -<source> <pluralform>Do you really want to delete the following item?</pluralform> <pluralform>Do you really want to delete the following %x items?</pluralform> </source> @@ -1298,9 +1353,6 @@ Note: File names must be relative to base directories. <source>Append a timestamp to each file name</source> <target>Додај временÑку ознаку Ñваком имену датотеке</target> -<source>Folder</source> -<target>Фолдер</target> - <source>File</source> <target>Датотека</target> @@ -1424,9 +1476,6 @@ Note: File names must be relative to base directories. <source>Cannot change process I/O priorities.</source> <target>Ðе може Ñе променити Ð¿Ñ€Ð¾Ñ†ÐµÑ I/O приоритета</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>Ðије могуће пребацити %x у Корпи за Ñмеће.</target> - <source>Cannot determine final path for %x.</source> <target>Ðе могу утврдити коначну путању за %x.</target> diff --git a/BUILD/Languages/slovenian.lng b/BUILD/Languages/slovenian.lng index a5bed20e..0f83331f 100644 --- a/BUILD/Languages/slovenian.lng +++ b/BUILD/Languages/slovenian.lng @@ -7,99 +7,6 @@ <plural_definition>n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3</plural_definition> </header> -<source>Log</source> -<target></target> - -<source>&Continue</source> -<target></target> - -<source>Comma-separated values</source> -<target></target> - -<source>&Don't show this dialog again</source> -<target></target> - -<source>&Execute</source> -<target></target> - -<source>Confirm</source> -<target></target> - -<source> -<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> -<pluralform>Do you really want to execute the command %y for %x items?</pluralform> -</source> -<target></target> - -<source>Minimize to notification area</source> -<target></target> - -<source>Retrying operation after error:</source> -<target></target> - -<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> -<target></target> - -<source>&Show error</source> -<target></target> - -<source>Waiting until all directories are available...</source> -<target></target> - -<source>Directory monitoring active</source> -<target></target> - -<source>Volume name %x is not part of file path %y.</source> -<target></target> - -<source>%x items</source> -<target></target> - -<source> -<pluralform>1 thread</pluralform> -<pluralform>%x threads</pluralform> -</source> -<target></target> - -<source> -<pluralform>1 byte</pluralform> -<pluralform>%x bytes</pluralform> -</source> -<target></target> - -<source>Any number of alternative directories for at most one config file.</source> -<target></target> - -<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> -<target></target> - -<source>directory</source> -<target></target> - -<source>config files</source> -<target></target> - -<source>Syntax:</source> -<target></target> - -<source>Directories cannot be set for more than one configuration file.</source> -<target></target> - -<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> -<target></target> - -<source>Unequal number of left and right directories specified.</source> -<target></target> - -<source>Cannot open file %x.</source> -<target></target> - -<source>Syntax error</source> -<target></target> - -<source>A directory path is expected after %x.</source> -<target></target> - <source>Both sides have changed since last synchronization.</source> <target>Obe strani sta se spremenili od zadnje sinhronizacije.</target> @@ -118,13 +25,13 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Preverjam razpoložljivost koÅ¡a za mapo %x...</target> -<source>Moving file %x to recycle bin</source> -<target>Premikam datoteko %x v koÅ¡</target> +<source>Moving file %x to the recycle bin</source> +<target>Premikam datoteko %x koÅ¡</target> -<source>Moving folder %x to recycle bin</source> -<target>Premikam mapo %x v koÅ¡</target> +<source>Moving folder %x to the recycle bin</source> +<target>Premikam imenik %x v koÅ¡</target> -<source>Moving symbolic link %x to recycle bin</source> +<source>Moving symbolic link %x to the recycle bin</source> <target>Premikam simboliÄno povezavo %x v koÅ¡</target> <source>Deleting file %x</source> @@ -136,21 +43,54 @@ <source>Deleting symbolic link %x</source> <target>Brisanje simboliÄnih povezav %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>Za naslednje mape KoÅ¡ ni na voljo. Datoteke bodo zato dokonÄno izbrisane:</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>Za sledeÄe imenike koÅ¡ ni na voljo. Datoteke bodo namesto tega dokonÄno izbrisane:</target> <source>An exception occurred</source> <target>Zgodila se je napaka</target> +<source>A directory path is expected after %x.</source> +<target>Za %x se priÄakuje pot do imenika.</target> + +<source>Syntax error</source> +<target>SintaktiÄna napaka</target> + +<source>Cannot open file %x.</source> +<target>Ne morem odpreti datoteke %x.</target> + <source>Error</source> <target>Napaka</target> <source>File %x does not contain a valid configuration.</source> <target>Datoteka %x ne vsebuje veljavnih nastavitev</target> +<source>Unequal number of left and right directories specified.</source> +<target>VneÅ¡eno je neenako Å¡tevilo levih in desnih imenikov.</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>Konfiguracijska datoteka ne sme vsebovati nastavitev na ravni imeniÅ¡kih parov, Äe so imeniki nastavljeni prek ukazne vrstice.</target> + <source>Warning</source> <target>Pozor</target> +<source>Directories cannot be set for more than one configuration file.</source> +<target>Imeniki ne morejo biti nastavljeni za eÄ kot eno konfiguracijsko datoteko.</target> + +<source>Syntax:</source> +<target>Sintaksa:</target> + +<source>config files</source> +<target>konfiguracijske datoteke</target> + +<source>directory</source> +<target>imenik</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>Poljubno Å¡tevilo FreeFileSync .ffs_gui in/ali .ffs_batch konfigracijskih datotek.</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>Poljubno Å¡tevilo alternatvnih imenikov za najveÄ eno konfiguracijsko datoteko.</target> + <source>Command line</source> <target>Ukazna vrstica</target> @@ -312,6 +252,17 @@ <source>Total time:</source> <target>Celoten Äas:</target> +<source> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> +</source> +<target> +<pluralform>%x bajt</pluralform> +<pluralform>%x bajta</pluralform> +<pluralform>%x bajti</pluralform> +<pluralform>%x bajtov</pluralform> +</target> + <source>%x MB</source> <target>%x MB</target> @@ -330,12 +281,26 @@ <source>Scanning:</source> <target>Pregledujem:</target> +<source> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> +</source> +<target> +<pluralform>%x nit</pluralform> +<pluralform>%x niti</pluralform> +<pluralform>%x niti</pluralform> +<pluralform>%x niti</pluralform> +</target> + <source>Encoding extended time information: %x</source> <target>Podrobne informacije o Äasu enkodiranja: %x</target> <source>/sec</source> <target>/sek</target> +<source>%x items</source> +<target>%x elementov</target> + <source>Configuration file %x loaded partially only.</source> <target>Nastavitvena datoteka %x naložena samo delno.</target> @@ -348,8 +313,8 @@ <source>Browse directory</source> <target>Brskaj po imeniku</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Ne morem dostopati do servisa Volume Shadow Copy</target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target>Ne morem dostopati do Volume Shadov Copy servisa.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>Prosimo uporabite 64-bitno razliÄico FreeFileSync za ustvarjanje senÄnih kopij na tem sistemu.</target> @@ -360,6 +325,9 @@ <source>Cannot determine volume name for %x.</source> <target>Ne morem doloÄiti ime nosilca za %x.</target> +<source>Volume name %x is not part of file path %y.</source> +<target>Ime nosilca %x ni del poti datoteke %y.</target> + <source>Abort requested: Waiting for current operation to finish...</source> <target>Zahtevana je bila prekinitev: Äakam, da se zakljuÄi trenutna operacija...</target> @@ -458,9 +426,18 @@ Ukaz se sproži Äe: <source>All files</source> <target>Vse datoteke</target> +<source>Directory monitoring active</source> +<target>Nadzor imenikov je aktven</target> + +<source>Waiting until all directories are available...</source> +<target>ÄŒakam da so vsi imeniki dostopni...</target> + <source>&Restore</source> <target>&Obnovi</target> +<source>&Show error</source> +<target>&Pokaži napako</target> + <source>&Exit</source> <target>&Izhod</target> @@ -536,6 +513,9 @@ Ukaz se sproži Äe: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>Naslednji elementi imajo nereÅ¡ene konflikte in ne bodo sinhronizirani:</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>Naslednji imeniki so obÄutno razliÄni. Preverite, Äe primerjate pravilne imenike za sinhnorizacijo.</target> + <source>Not enough free disk space available in:</source> <target>Na voljo ni dovolj prostega prostora na disku v:</target> @@ -554,12 +534,15 @@ Ukaz se sproži Äe: <source>Generating database...</source> <target>Ustvarjam podatkovno bazo...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>Ustvarjam SenÄno kopijo nosilca za %x...</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>Ustvarjam Volume Shadow Copy za %x...</target> <source>Data verification error: %x and %y have different content.</source> <target>Napaka pri preverjanju podatkov: %x in %y imata drugaÄno vsebino.</target> +<source>job name</source> +<target>naziv opravila</target> + <source>Synchronization aborted</source> <target>Sinhronizacija prekinjena</target> @@ -584,6 +567,9 @@ Ukaz se sproži Äe: <source>Switching to FreeFileSync main dialog</source> <target>Preklapljam na FreeFileSync osrednje pogovorno okno</target> +<source>Retrying operation after error:</source> +<target>Operacija za ponoven poiskus po napaki:</target> + <source>A new version of FreeFileSync is available:</source> <target>Nova razliÄica FreeFileSync je na voljo:</target> @@ -707,8 +693,8 @@ Ukaz se sproži Äe: <source>&Export file list...</source> <target>&Izvozi seznam datotek...</target> -<source>&Global settings...</source> -<target>&Globalne nastavitve...</target> +<source>&Global settings</source> +<target>&Globalne nastavitve</target> <source>&Tools</source> <target>&Orodja</target> @@ -725,12 +711,6 @@ Ukaz se sproži Äe: <source>Compare</source> <target>Primerjaj</target> -<source>Comparison settings</source> -<target>Nastavitve primerjanja</target> - -<source>Synchronization settings</source> -<target>Nastavitve sinhronizacije</target> - <source>Synchronize</source> <target>Sinhroniziraj</target> @@ -779,6 +759,9 @@ Ukaz se sproži Äe: <source>Synchronizing...</source> <target>Sinhroniziram...</target> +<source>Minimize to notification area</source> +<target>PomanjÅ¡aj v obmoÄje obvestil</target> + <source>On completion</source> <target>Ob zakljuÄku</target> @@ -794,8 +777,8 @@ Ukaz se sproži Äe: <source>Statistics</source> <target>Statistika</target> -<source>Don't show this dialog again</source> -<target>Ne prikazuj veÄ tega pogovora</target> +<source>&Don't show this dialog again</source> +<target>&Ne pokaži veÄ tega sporoÄila</target> <source>Select a variant</source> <target>Izberite spremenljivko</target> @@ -845,6 +828,12 @@ enaka <source>Configure your own synchronization rules.</source> <target>Konfigurirajte vaÅ¡a lastna sinhronizacijska pravila.</target> +<source>Detect moved files</source> +<target>Zaznaj premaknjene datoteke</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Zahteva podatkovno bazo. Ni podprt s strani vseh datoteÄnih sistemov.</target> + <source>Error handling</source> <target>Napaka pri obravnavanju</target> @@ -869,17 +858,17 @@ enaka <source>Delete or overwrite files permanently</source> <target>Trajno izbriÅ¡i ali prepiÅ¡i datoteke</target> -<source>Recycle Bin</source> +<source>Recycle bin</source> <target>KoÅ¡</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Uporabi KoÅ¡ za izbrisane in prepisane datoteke</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Naredi varnostno kopijo izbrisanih in prepisanih datotek v koÅ¡</target> <source>Versioning</source> <target>Ustvarjanje razliÄiÄ</target> -<source>Move files to user-defined folder</source> -<target>Premakni datoteke v uporabniÅ¡ko-definirano mapo</target> +<source>Move files to a user-defined folder</source> +<target>Premakni datoteke v izbran imenik</target> <source>Naming convention:</source> <target>Konvencija poimenovanja:</target> @@ -887,8 +876,8 @@ enaka <source>Batch job</source> <target>Paketno opravilo</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Ustvari paketno datoteko za avtomatiziranje sinhronizacije. Dvokliknite to datoteko ali jo nastavite v razpored opravil vaÅ¡ega sistema: FreeFileSync.exe <ime opravila>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Ustvari skriptno datoteko za samodejno sinhnorizacijo. Za zagon dvojno kliknite to datoteko ali pa jo umestite v razporejevalnik opravil: %x</target> <source>Exit</source> <target>Izhod</target> @@ -911,30 +900,6 @@ enaka <source>Limit maximum number of log files</source> <target>Omeji maksimalno Å¡tevilo datotek beleženja</target> -<source>Source code written in C++ using:</source> -<target>Izvorna koda napisana v C++ z uporabo:</target> - -<source>If you like FreeFileSync</source> -<target>ÄŒe vam je FreeFileSync vÅ¡eÄ</target> - -<source>Donate with PayPal</source> -<target>Doniraj s PayPal</target> - -<source>Many thanks for localization:</source> -<target>Zahvale za lokalizacijo:</target> - -<source>Feedback and suggestions are welcome</source> -<target>Povratne informacije in predlogi so dobrodoÅ¡li</target> - -<source>Homepage</source> -<target>DomaÄa stran</target> - -<source>Email</source> -<target>Email</target> - -<source>Published under the GNU General Public License</source> -<target>Objavljeno pod licenco GNU General Public</target> - <source>Delete on both sides</source> <target>IzbriÅ¡i na obeh straneh</target> @@ -942,12 +907,12 @@ enaka <target>IzbriÅ¡i na obeh straneh, Äetudi je datoteka izbrana na samo eni strani</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -Samo datoteke, ki ustrezajo vsem nastavitvam filtra bodo sinhronizirane. -Opomba: Imena datoteka morajo biti relativna osnovnim imenikom. +Datoteke bodo sinhnorizirane samo, Äe bodo zadoÅ¡Äale vsem filtrirnim pravilom. +Opomba: Poti datotek morajo biti relativne na osnovne imenike. </target> <source>Include</source> @@ -977,20 +942,20 @@ Opomba: Imena datoteka morajo biti relativna osnovnim imenikom. <source>Fail-safe file copy</source> <target>Kopiranje datotek varno pred odpovedjo</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>Najprej zapisuj v zaÄasno datoteko (*.ffs_tmp) in nato preimenuj. To zagotavlja dosledno stanje celo v primeru usodne napake.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>Najprej kopiraj v zaÄasno datoteko (*.ffs_tmp) nato pa jo preimenuj. To zagotavlja konsistenco podatkov v primeru kritiÄne napake.</target> <source>Copy locked files</source> <target>Kopiraj zaklenjene datoteke</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Kopiraj deljene ali zaklenjene datoteke z uporabo servisa Shadow Copy (Zahteva pravice skrbnika)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>Kopiraj zaklenjene ali imenike v souporabi s pomoÄjo Volume Shadow Copy servisa (zahteva pravice administratorja)</target> <source>Copy file access permissions</source> <target>Kopiraj dovoljenja dostopov datoteke</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Prenesi dovoljenja datotek in map (Zahteva pravice Skrbnika)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>Prenesi pravice datotek in imenikov (zahteva pravice administratorja)</target> <source>Restore hidden dialogs</source> <target>Obnovi skrite pogovore</target> @@ -1013,9 +978,39 @@ Opomba: Imena datoteka morajo biti relativna osnovnim imenikom. <source>&Find next</source> <target>&Najdi naslednje</target> +<source>Source code written in C++ using:</source> +<target>Izvorna koda napisana v C++ z uporabo:</target> + +<source>If you like FreeFileSync</source> +<target>ÄŒe vam je FreeFileSync vÅ¡eÄ</target> + +<source>Donate with PayPal</source> +<target>Doniraj s PayPal</target> + +<source>Feedback and suggestions are welcome</source> +<target>Povratne informacije in predlogi so dobrodoÅ¡li</target> + +<source>Homepage</source> +<target>DomaÄa stran</target> + +<source>Email</source> +<target>Email</target> + +<source>Published under the GNU General Public License</source> +<target>Objavljeno pod licenco GNU General Public</target> + +<source>Many thanks for localization:</source> +<target>Zahvale za lokalizacijo:</target> + <source>Start synchronization</source> <target>ZaÄni sinhronizacijo</target> +<source>Comparison settings</source> +<target>Nastavitve primerjanja</target> + +<source>Synchronization settings</source> +<target>Nastavitve sinhronizacije</target> + <source>Delete</source> <target>IzbriÅ¡i</target> @@ -1056,6 +1051,23 @@ Opomba: Imena datoteka morajo biti relativna osnovnim imenikom. <target>Primerjaj obe strani</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>Ali res želite izvesti ukaz %y za %x element?</pluralform> +<pluralform>Ali res želite izvesti ukaz %y za %x elementa?</pluralform> +<pluralform>Ali res želite izvesti ukaz %y za %x elemente?</pluralform> +<pluralform>Ali res želite izvesti ukaz %y za %x elementov?</pluralform> +</target> + +<source>Confirm</source> +<target>Potrdi</target> + +<source>&Execute</source> +<target>&Izvedi</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1097,12 +1109,15 @@ Opomba: Imena datoteka morajo biti relativna osnovnim imenikom. <source>Include temporarily</source> <target>Trenutno vkljuÄi</target> -<source>Exclude via filter:</source> -<target>IzkljuÄi preko filtra:</target> - <source>multiple selection</source> <target>mnogokratna izbira</target> +<source>Include via filter:</source> +<target>VkljuÄi preko filtra:</target> + +<source>Exclude via filter:</source> +<target>IzkljuÄi preko filtra:</target> + <source>Include all</source> <target>VkljuÄi vse</target> @@ -1148,8 +1163,8 @@ Opomba: Imena datoteka morajo biti relativna osnovnim imenikom. <source>Do&n't save</source> <target>Ne shra&ni</target> -<source>Never save changes</source> -<target>Nikoli ne shrani sprememb</target> +<source>Never save &changes</source> +<target>Nikoli ne shrani &sprememb</target> <source>Show files that exist on left side only</source> <target>Prikaži datoteke, ki obstajajo samo na levi</target> @@ -1202,14 +1217,17 @@ Opomba: Imena datoteka morajo biti relativna osnovnim imenikom. <source>All folders are in sync</source> <target>Vse mape so sinhronizirane</target> +<source>Comma-separated values</source> +<target>Vrednosti loÄene z vejico</target> + <source>File list exported</source> <target>Seznam datotek je bil izvožen</target> <source>Searching for program updates...</source> <target>IÅ¡Äem posodobitve programa...</target> -<source>Ignore further errors</source> -<target>Ignoriraj nadaljnje napake</target> +<source>&Ignore subsequent errors</source> +<target>&Ignoriraj nadaljnje napake</target> <source>&Ignore</source> <target>&Ignoriraj</target> @@ -1217,8 +1235,8 @@ Opomba: Imena datoteka morajo biti relativna osnovnim imenikom. <source>Fatal Error</source> <target>Usodna napaka</target> -<source>Don't show this warning again</source> -<target>Ne prikaži veÄ tega opozorila</target> +<source>&Don't show this warning again</source> +<target>&Ne pokaži veÄ tega opozorila</target> <source>&Switch</source> <target>&Preklopi</target> @@ -1253,6 +1271,12 @@ Opomba: Imena datoteka morajo biti relativna osnovnim imenikom. <source>Completed</source> <target>ZakljuÄeno</target> +<source>&Continue</source> +<target>&Nadaljuj</target> + +<source>Log</source> +<target>Dnevnik</target> + <source>Cannot find %x</source> <target>Ne najdem %x</target> @@ -1287,14 +1311,14 @@ Opomba: Imena datoteka morajo biti relativna osnovnim imenikom. <target>Filter</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>Ali resniÄno želite premakniti sledeÄi %xelement v KoÅ¡?</pluralform> -<pluralform>Ali resniÄno želite premakniti naslednja %x elementa v KoÅ¡?</pluralform> -<pluralform>Ali resniÄno želite premakniti naslednje %x elemente v KoÅ¡?</pluralform> -<pluralform>Ali resniÄno želite premakniti naslednjih %x elementov v KoÅ¡?</pluralform> +<pluralform>Ali res želite premakniti sledeÄ %x element v koÅ¡?</pluralform> +<pluralform>Ali res želite premakniti sledeÄa %x elementa v koÅ¡?</pluralform> +<pluralform>Ali res želite premakniti sledeÄe %x elemente v koÅ¡?</pluralform> +<pluralform>Ali res želite premakniti sledeÄih %x elementov v koÅ¡?</pluralform> </target> <source> @@ -1476,8 +1500,8 @@ Opomba: Imena datoteka morajo biti relativna osnovnim imenikom. <source>Cannot change process I/O priorities.</source> <target>Ne morem spremeniti V/I prioritet procesa.</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>Ne morem premakniti %x v KoÅ¡.</target> +<source>Unable to move %x to the recycle bin.</source> +<target>Ne morem premakniti %x v koÅ¡-</target> <source>Cannot determine final path for %x.</source> <target>Ne morem doloÄiti konÄne poti za %x.</target> diff --git a/BUILD/Languages/spanish.lng b/BUILD/Languages/spanish.lng index e1726b2b..507b977a 100644 --- a/BUILD/Languages/spanish.lng +++ b/BUILD/Languages/spanish.lng @@ -7,104 +7,11 @@ <plural_definition>n == 1 ? 0 : 1</plural_definition> </header> -<source>Log</source> -<target></target> - -<source>&Continue</source> -<target></target> - -<source>Comma-separated values</source> -<target></target> - -<source>&Don't show this dialog again</source> -<target></target> - -<source>&Execute</source> -<target></target> - -<source>Confirm</source> -<target></target> - -<source> -<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> -<pluralform>Do you really want to execute the command %y for %x items?</pluralform> -</source> -<target></target> - -<source>Minimize to notification area</source> -<target></target> - -<source>Retrying operation after error:</source> -<target></target> - -<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> -<target></target> - -<source>&Show error</source> -<target></target> - -<source>Waiting until all directories are available...</source> -<target></target> - -<source>Directory monitoring active</source> -<target></target> - -<source>Volume name %x is not part of file path %y.</source> -<target></target> - -<source>%x items</source> -<target></target> - -<source> -<pluralform>1 thread</pluralform> -<pluralform>%x threads</pluralform> -</source> -<target></target> - -<source> -<pluralform>1 byte</pluralform> -<pluralform>%x bytes</pluralform> -</source> -<target></target> - -<source>Any number of alternative directories for at most one config file.</source> -<target></target> - -<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> -<target></target> - -<source>directory</source> -<target></target> - -<source>config files</source> -<target></target> - -<source>Syntax:</source> -<target></target> - -<source>Directories cannot be set for more than one configuration file.</source> -<target></target> - -<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> -<target></target> - -<source>Unequal number of left and right directories specified.</source> -<target></target> - -<source>Cannot open file %x.</source> -<target></target> - -<source>Syntax error</source> -<target></target> - -<source>A directory path is expected after %x.</source> -<target></target> - <source>Both sides have changed since last synchronization.</source> <target>Ambos lados han cambiado desde la última sincronización.</target> <source>Cannot determine sync-direction:</source> -<target>No se puede determinar la dirección de la sincronización:</target> +<target>No se puede determinar la dirección de sincronización:</target> <source>No change since last synchronization.</source> <target>Ningún cambio desde la última sincronización.</target> @@ -118,13 +25,13 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Comprobando disponibilidad de la papelera de reciclaje para la carpeta %x…</target> -<source>Moving file %x to recycle bin</source> +<source>Moving file %x to the recycle bin</source> <target>Mover archivo %x a la papelera de reciclaje</target> -<source>Moving folder %x to recycle bin</source> +<source>Moving folder %x to the recycle bin</source> <target>Mover carpeta %x a la papelera de reciclaje</target> -<source>Moving symbolic link %x to recycle bin</source> +<source>Moving symbolic link %x to the recycle bin</source> <target>Mover vÃnculo simbólico %x a la papelera de reciclaje</target> <source>Deleting file %x</source> @@ -136,21 +43,54 @@ <source>Deleting symbolic link %x</source> <target>Borrar vÃnculo simbólico %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>La Papelera de reciclaje no está disponible para las carpetas siguientes. Los archivos se borrarán de forma permanente:</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>La papelera de reciclaje no está disponible para las carpetas siguientes. Los archivos se borrarán de forma permanente:</target> <source>An exception occurred</source> <target>Ha ocurrido una excepción</target> +<source>A directory path is expected after %x.</source> +<target>Se esperaba una ruta de directorio después de %x.</target> + +<source>Syntax error</source> +<target>Error de sintaxis</target> + +<source>Cannot open file %x.</source> +<target>No se puede abrir el archivo %x.</target> + <source>Error</source> <target>Error</target> <source>File %x does not contain a valid configuration.</source> <target>El archivo %x no contiene una configuración válida.</target> +<source>Unequal number of left and right directories specified.</source> +<target>Desigualdad en el número de directorios especificados a izquierda y derecha.</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>El archivo de configuración no debe incluir parámetros al nivel de un par de directorios cuando éstos se especifican desde la lÃnea de comandos.</target> + <source>Warning</source> <target>Atención</target> +<source>Directories cannot be set for more than one configuration file.</source> +<target>No se pueden definir directorios para más de un archivo de configuración.</target> + +<source>Syntax:</source> +<target>Sintaxis:</target> + +<source>config files</source> +<target>archivos de configuración</target> + +<source>directory</source> +<target>directorio</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>Cualquier número de archivos de configuración de FreeFileSync (.ffs_gui ó .ffs_batch).</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>Cualquier número de directorios alternativos para un archivo de configuración como máximo.</target> + <source>Command line</source> <target>LÃnea de comandos</target> @@ -209,10 +149,10 @@ <target>El elemento existe sólo en el lado derecho</target> <source>Left side is newer</source> -<target>El lado izquierdo es más nuevo</target> +<target>El lado izquierdo es más reciente</target> <source>Right side is newer</source> -<target>El lado derecho es más nuevo</target> +<target>El lado derecho es más reciente</target> <source>Items have different content</source> <target>Los elementos tienen contenido distinto</target> @@ -221,7 +161,7 @@ <target>Ambos lados son iguales</target> <source>Conflict/item cannot be categorized</source> -<target>Conflicto</target> +<target>No se puede categorizar el conflicto o elemento</target> <source>Copy new item to left</source> <target>Copiar nuevo elemento a la izquierda</target> @@ -257,31 +197,31 @@ <target>Actualizar atributos en la derecha</target> <source>Database file %x is incompatible.</source> -<target>El archivo de base de datos %x es incompatible</target> +<target>El archivo de base de datos %x es incompatible.</target> <source>Initial synchronization:</source> <target>Sincronización inicial:</target> <source>Database file %x does not yet exist.</source> -<target>El archivo de base de datos %x aún no existe</target> +<target>El archivo de base de datos %x aún no existe.</target> <source>Database file is corrupt:</source> <target>El archivo de base de datos está dañado:</target> <source>Cannot write file %x.</source> -<target>No se puede escribir el archivo %x</target> +<target>No se puede escribir el archivo %x.</target> <source>Cannot read file %x.</source> -<target>No se puede leer el archivo %x</target> +<target>No se puede leer el archivo %x.</target> <source>Database files do not share a common session.</source> -<target>Los archivos de base de datos no comparten una sesión común</target> +<target>Los archivos de base de datos no comparten una sesión común.</target> <source>Searching for folder %x...</source> <target>Buscando carpeta %x…</target> <source>Cannot read file attributes of %x.</source> -<target>No se puede leer archivo de atributos de %x</target> +<target>No se puede leer archivo de atributos de %x.</target> <source>Cannot get process information.</source> <target>No se puede obtener información del proceso.</target> @@ -310,6 +250,15 @@ <source>Total time:</source> <target>Tiempo total:</target> +<source> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> +</source> +<target> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> +</target> + <source>%x MB</source> <target>%x MB</target> @@ -328,12 +277,24 @@ <source>Scanning:</source> <target>Escanear:</target> +<source> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> +</source> +<target> +<pluralform>1 hilo</pluralform> +<pluralform>%x hilos</pluralform> +</target> + <source>Encoding extended time information: %x</source> -<target>Condificando información de hora extendida: %x</target> +<target>Codificando información de hora extendida: %x</target> <source>/sec</source> <target>/seg</target> +<source>%x items</source> +<target>%x elementos</target> + <source>Configuration file %x loaded partially only.</source> <target>Archivo de configuración %x cargado sólo parcialmente.</target> @@ -346,7 +307,7 @@ <source>Browse directory</source> <target>Examinar directorio</target> -<source>Cannot access Volume Shadow Copy Service.</source> +<source>Cannot access the Volume Shadow Copy Service.</source> <target>No se puede acceder al servicio de Instantánea de volumen.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> @@ -358,6 +319,9 @@ <source>Cannot determine volume name for %x.</source> <target>No se puede determinar nombre del volumen de %x.</target> +<source>Volume name %x is not part of file path %y.</source> +<target>El nombre de volumen %x no es parte de la ruta de archivo %y.</target> + <source>Abort requested: Waiting for current operation to finish...</source> <target>Anulación solicitada: esperando a que la operación actual finalice…</target> @@ -401,7 +365,7 @@ <target>3. Presione ’Inicio’.</target> <source>To get started just import a .ffs_batch file.</source> -<target>Para comenzar, importe un archivo .ffs_batch</target> +<target>Para comenzar, importe un archivo .ffs_batch.</target> <source>Folders to watch</source> <target>Carpetas para ver</target> @@ -430,9 +394,9 @@ The command is triggered if: - new folders arrive (e.g. USB stick insert) </source> <target> -El comando es disparado si:: +El comando es disparado si: - hay cambios en los archivos o subcarpetas -- aparecen nuevas carpetas (Insertando una memoria USB, por ejemplo) +- aparecen nuevas carpetas (en una memoria USB, por ejemplo) </target> <source>Start</source> @@ -456,9 +420,18 @@ El comando es disparado si:: <source>All files</source> <target>Todos los archivos</target> +<source>Directory monitoring active</source> +<target>Supervisión de directorios activada</target> + +<source>Waiting until all directories are available...</source> +<target>Esperando que todos los directorios estén disponibles…</target> + <source>&Restore</source> <target>&Restaurar</target> +<source>&Show error</source> +<target>Mo&strar error</target> + <source>&Exit</source> <target>&Salir</target> @@ -472,7 +445,7 @@ El comando es disparado si:: <target>Fecha y tamaño del archivo</target> <source>Two way</source> -<target>Dos formas</target> +<target>Bidireccional</target> <source>Mirror</source> <target>Espejo</target> @@ -534,6 +507,9 @@ El comando es disparado si:: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>Los siguientes elementos tienen conflictos sin resolver y no serán sincronizados:</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>Las carpetas siguientes muestran diferencias significativas. Compruebe que hace coincidir las carpetas correctas para su sincronización.</target> + <source>Not enough free disk space available in:</source> <target>Espacio en disco insuficiente en:</target> @@ -552,12 +528,15 @@ El comando es disparado si:: <source>Generating database...</source> <target>Generando base de datos…</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>Creando Instantánea de volumen para %x…</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>Creando una Instantánea de volumen para %x…</target> <source>Data verification error: %x and %y have different content.</source> <target>Error al comprobar los datos: %x y %y tienen contenidos diferentes.</target> +<source>job name</source> +<target>nombre de tarea</target> + <source>Synchronization aborted</source> <target>Sincronización anulada</target> @@ -582,6 +561,9 @@ El comando es disparado si:: <source>Switching to FreeFileSync main dialog</source> <target>Cambiando a la ventana principal de FreeFileSync</target> +<source>Retrying operation after error:</source> +<target>Reintento de operación después de error:</target> + <source>A new version of FreeFileSync is available:</source> <target>Una nueva versión de FreeFileSync está disponible:</target> @@ -691,7 +673,7 @@ El comando es disparado si:: <target>&Guardar</target> <source>Save as &batch job...</source> -<target>Guardar como trabajo &batch …</target> +<target>Guardar como tarea &lote…</target> <source>1. &Compare</source> <target>1. &Comparar</target> @@ -705,8 +687,8 @@ El comando es disparado si:: <source>&Export file list...</source> <target>&Exportar lista de archivos…</target> -<source>&Global settings...</source> -<target>&Opciones globales…</target> +<source>&Global settings</source> +<target>&Opciones globales</target> <source>&Tools</source> <target>Herramien&tas</target> @@ -742,7 +724,7 @@ El comando es disparado si:: <target>Intercambiar lados</target> <source>Save as batch job</source> -<target>Salvar como tarea batch</target> +<target>Salvar como tarea lote</target> <source>Hide excluded items</source> <target>Ocultar elementos excluidos</target> @@ -777,6 +759,9 @@ El comando es disparado si:: <source>Synchronizing...</source> <target>Sincronizando…</target> +<source>Minimize to notification area</source> +<target>Minimizar en el área de notificación</target> + <source>On completion</source> <target>Al completar</target> @@ -792,8 +777,8 @@ El comando es disparado si:: <source>Statistics</source> <target>EstadÃsticas</target> -<source>Don't show this dialog again</source> -<target>No volver a mostrar este diálogo</target> +<source>&Don't show this dialog again</source> +<target>&No volver a mostrar este diálogo</target> <source>Select a variant</source> <target>Seleccione una variante</target> @@ -843,6 +828,12 @@ es el mismo <source>Configure your own synchronization rules.</source> <target>Configuración de sus propias reglas de sincronización.</target> +<source>Detect moved files</source> +<target>Detectar archivos movidos</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Archivos de base de datos requeridos. No son compatibles en todos los sistemas de archivos.</target> + <source>Error handling</source> <target>Gestión de errores</target> @@ -867,26 +858,26 @@ es el mismo <source>Delete or overwrite files permanently</source> <target>Borrar o Sobrescribir archivos permanentemente</target> -<source>Recycle Bin</source> +<source>Recycle bin</source> <target>Papelera de reciclaje</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Utilizar la papelera de reciclaje para archivos eliminados y sobrescritos</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Se eliminó la copia de respaldo y se reemplazaron archivos en la papelera de reciclaje</target> <source>Versioning</source> <target>Control de versiones</target> -<source>Move files to user-defined folder</source> -<target>Mover archivos a una carpeta definida por el usuario</target> +<source>Move files to a user-defined folder</source> +<target>Mover archivos a una carpeta del usuario</target> <source>Naming convention:</source> <target>Convención de nomenclatura:</target> <source>Batch job</source> -<target>Tarea por lotes</target> +<target>Tarea lote</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Crear archivo batch para sincronización automática. Haga doble clic en este archivo o prográmelo en el planificador de tareas del sistema: FreeFileSync.exe <job name>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Crear archivo por lotes para sincronización desatendida. Para iniciar, haga doble clic en este archivo o prográmelo en el planificador de tareas : %x</target> <source>Exit</source> <target>Salir</target> @@ -910,19 +901,19 @@ es el mismo <target>Limitar el número máximo de archivos de registro</target> <source>Source code written in C++ using:</source> -<target>Código fuente escrito en C++ utilizando:</target> +<target>Código fuente original en C++ con apoyo de:</target> <source>If you like FreeFileSync</source> -<target>Si te gusta FreeFileSync</target> +<target>¿Te gusta FreeFileSync? :</target> <source>Donate with PayPal</source> -<target>Donar a través de PayPal</target> +<target>Haz una donación por PayPal</target> <source>Many thanks for localization:</source> <target>Agradecimientos por las traducciones a:</target> <source>Feedback and suggestions are welcome</source> -<target>Feedback y sugerencias son bienvenidas</target> +<target>Comentarios y sugerencias bienvenidos :</target> <source>Homepage</source> <target>Página de inicio</target> @@ -931,7 +922,7 @@ es el mismo <target>Correo electrónico</target> <source>Published under the GNU General Public License</source> -<target>Publicado bajo GNU General Public License</target> +<target>Publicado con derechos GNU General Public License :</target> <source>Delete on both sides</source> <target>Borrar en ambos lados</target> @@ -940,12 +931,12 @@ es el mismo <target>Borrar en ambos lados incluso si el archivo está seleccionado en un solo lado</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -Sólo archivos en que coincidan todos los filtros serán sincronizados. -Aviso: Los nombres de archivos deben ser relativos a los directorios base. +Sólo se sincronizarán los archivos que cumplan todos los filtros. +Nota: las rutas de archivo deben ser relativas a los directorios base. </target> <source>Include</source> @@ -975,20 +966,20 @@ Aviso: Los nombres de archivos deben ser relativos a los directorios base. <source>Fail-safe file copy</source> <target>Copia de archivo a prueba de fallos</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> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> <target>Escribir en archivo temporal (*.ffs_tmp) primero y después renombrarlo. Esto garantiza un estado consistente incluso en caso de error fatal.</target> <source>Copy locked files</source> <target>Copiar archivos bloqueados</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Copiar archivos compartidos o bloqueados usando el servicio "Instantánea de volumen" (Requiere derechos de administrador)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>Copiar archivos compartidos o bloqueados usando el servicio de Instantánea de volumen (requiere derechos de administrador)</target> <source>Copy file access permissions</source> <target>Copiar permisos de acceso al archivo</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Transferir permisos de archivo y carpeta (Requiere derechos de Administrador)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>Transferir permisos de archivo y carpeta (requiere derechos de administrador)</target> <source>Restore hidden dialogs</source> <target>Restaurar diálogos ocultos</target> @@ -1054,6 +1045,21 @@ Aviso: Los nombres de archivos deben ser relativos a los directorios base. <target>Comparar ambos lados</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>¿Realmente desea ejecutar la orden %y para un elemento?</pluralform> +<pluralform>¿Realmente desea ejecutar la orden %y para %x elementos?</pluralform> +</target> + +<source>Confirm</source> +<target>Confirmar</target> + +<source>&Execute</source> +<target>&Ejecutar</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1089,12 +1095,15 @@ Aviso: Los nombres de archivos deben ser relativos a los directorios base. <source>Include temporarily</source> <target>Incluir temporalmente</target> -<source>Exclude via filter:</source> -<target>Excluir a través del filtro:</target> - <source>multiple selection</source> <target>selección múltiple</target> +<source>Include via filter:</source> +<target>Incluir a través del filtro:</target> + +<source>Exclude via filter:</source> +<target>Excluir a través del filtro:</target> + <source>Include all</source> <target>Incluir todo</target> @@ -1132,7 +1141,7 @@ Aviso: Los nombres de archivos deben ser relativos a los directorios base. <target>Configuración guardada</target> <source>FreeFileSync batch</source> -<target>Batch de FreeFileSync</target> +<target>Lote de FreeFileSync</target> <source>Do you want to save changes to %x?</source> <target>¿Quiere guardar los cambios de %x?</target> @@ -1140,8 +1149,8 @@ Aviso: Los nombres de archivos deben ser relativos a los directorios base. <source>Do&n't save</source> <target>&No guardar</target> -<source>Never save changes</source> -<target>Nunca guardar cambios</target> +<source>Never save &changes</source> +<target>Nunca guardar &cambios</target> <source>Show files that exist on left side only</source> <target>Mostrar sólo archivos existentes en la izquierda</target> @@ -1194,14 +1203,17 @@ Aviso: Los nombres de archivos deben ser relativos a los directorios base. <source>All folders are in sync</source> <target>Todas las carpetas están sincronizadas</target> +<source>Comma-separated values</source> +<target>Valores separados por comas</target> + <source>File list exported</source> <target>Lista de archivos exportada</target> <source>Searching for program updates...</source> <target>Buscando actualizaciones del programa…</target> -<source>Ignore further errors</source> -<target>Ignorar más errores</target> +<source>&Ignore subsequent errors</source> +<target>&Ignorar errores posteriores</target> <source>&Ignore</source> <target>&Ignorar</target> @@ -1209,8 +1221,8 @@ Aviso: Los nombres de archivos deben ser relativos a los directorios base. <source>Fatal Error</source> <target>Error fatal</target> -<source>Don't show this warning again</source> -<target>No volver a mostrar este aviso</target> +<source>&Don't show this warning again</source> +<target>&No volver a mostrar este aviso</target> <source>&Switch</source> <target>&Cambiar</target> @@ -1245,6 +1257,12 @@ Aviso: Los nombres de archivos deben ser relativos a los directorios base. <source>Completed</source> <target>Terminado</target> +<source>&Continue</source> +<target>&Continuar</target> + +<source>Log</source> +<target>Registro</target> + <source>Cannot find %x</source> <target>No se puede encontrar %x</target> @@ -1279,12 +1297,12 @@ Aviso: Los nombres de archivos deben ser relativos a los directorios base. <target>Filtro</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>¿Realmente desea mover este objeto a la papelera de reciclaje?</pluralform> -<pluralform>¿Realmente desea mover estos %x objetos a la papelera de reciclaje?</pluralform> +<pluralform>¿Realmente desea mover este elemento a la papelera de reciclaje?</pluralform> +<pluralform>¿Realmente desea mover estos %x elementos a la papelera de reciclaje?</pluralform> </target> <source> @@ -1456,10 +1474,10 @@ Aviso: Los nombres de archivos deben ser relativos a los directorios base. <target>Fallo al intentar suspender el sistema.</target> <source>Cannot change process I/O priorities.</source> -<target>No se pudieron cambiar las priridades de E/S del proceso.</target> +<target>No se pudieron cambiar las prioridades de E/S del proceso.</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>No se puede mover %x a la Papelera de reciclaje.</target> +<source>Unable to move %x to the recycle bin.</source> +<target>Incapaz de mover %x a la papelera de reciclaje.</target> <source>Cannot determine final path for %x.</source> <target>No se puede determinar la ruta final de %x.</target> diff --git a/BUILD/Languages/swedish.lng b/BUILD/Languages/swedish.lng index 8102e92b..f6e3f52b 100644 --- a/BUILD/Languages/swedish.lng +++ b/BUILD/Languages/swedish.lng @@ -25,13 +25,13 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Kontrollerar papperskorgens tillgänglighet för %x...</target> -<source>Moving file %x to recycle bin</source> -<target>Flyttar filen %x till papperskorgen</target> +<source>Moving file %x to the recycle bin</source> +<target>Flyttar %x till papperskorgen</target> -<source>Moving folder %x to recycle bin</source> +<source>Moving folder %x to the recycle bin</source> <target>Flyttar mappen %x till papperskorgen</target> -<source>Moving symbolic link %x to recycle bin</source> +<source>Moving symbolic link %x to the recycle bin</source> <target>Flyttar den symboliska länken %x till papperskorgen</target> <source>Deleting file %x</source> @@ -43,14 +43,20 @@ <source>Deleting symbolic link %x</source> <target>Tar bort den symboliska länken %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>Papperskorgen är inte tillgänglig för följande mappar. Filerna kommer att tas bort permanent istället:</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>Papperskorgen är inte tillgänglig för följande mappar. Filerna kommer istället att tas bort permanent:</target> <source>An exception occurred</source> <target>Ett undantag inträffade</target> -<source>Cannot find file %x.</source> -<target>Filen %x kan inte hittas</target> +<source>A directory path is expected after %x.</source> +<target>En sökväg förväntas efter %x.</target> + +<source>Syntax error</source> +<target>Syntaxfel</target> + +<source>Cannot open file %x.</source> +<target>Kan inte öppna %x</target> <source>Error</source> <target>Fel</target> @@ -58,6 +64,36 @@ <source>File %x does not contain a valid configuration.</source> <target>Filen %x innehÃ¥ller ingen giltig konfiguration.</target> +<source>Unequal number of left and right directories specified.</source> +<target>Ett ojämnt antal vänster- och högermappar har specificerats.</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>Konfigurationsfilen kan inte innehÃ¥lla inställningar pÃ¥ katalogparnivÃ¥ när mappar anges via kommandorad.</target> + +<source>Warning</source> +<target>Varning</target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target>Mappar kan inte anges för mer än en konfigurationsfil</target> + +<source>Syntax:</source> +<target>Syntax:</target> + +<source>config files</source> +<target>konfigurationsfiler</target> + +<source>directory</source> +<target>mapp</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>Valfritt antal FreeFileSync .ffs_gui och/eller .ffs_batch konfigurationsfiler.</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>Valfritt antal alternativa mappar för max en konfigurationsfil.</target> + +<source>Command line</source> +<target>Kommandofält</target> + <source>A folder input field is empty.</source> <target>Ett inmatningsfält är tomt</target> @@ -215,12 +251,12 @@ <target>Total tid:</target> <source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </source> <target> -<pluralform>1 Byte</pluralform> -<pluralform>%x Byte</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x byte</pluralform> </target> <source>%x MB</source> @@ -242,12 +278,12 @@ <target>Skannar:</target> <source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </source> <target> -<pluralform>[1 trÃ¥d]</pluralform> -<pluralform>[%x trÃ¥dar]</pluralform> +<pluralform>1 trÃ¥d</pluralform> +<pluralform>%x trÃ¥dar</pluralform> </target> <source>Encoding extended time information: %x</source> @@ -256,6 +292,9 @@ <source>/sec</source> <target>/s</target> +<source>%x items</source> +<target>%x objekt</target> + <source>Configuration file %x loaded partially only.</source> <target>Konfigurationsfilen %x lästes bara delvis in.</target> @@ -268,8 +307,8 @@ <source>Browse directory</source> <target>Sök upp mapp</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Kan inte komma Ã¥t tjänsten Volume Shadow Copy.</target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target>Kan inte komma Ã¥t tjänsten 'Volume Shadow Copy'</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>Använd FreeFileSync 64-bitarsversion för att skapa skuggkopior pÃ¥ detta system.</target> @@ -280,8 +319,8 @@ <source>Cannot determine volume name for %x.</source> <target>Kan inte utläsa volymnamn för %x</target> -<source>Volume name %x not part of file name %y.</source> -<target>Volymnamn %x saknas i filnamn %y.</target> +<source>Volume name %x is not part of file path %y.</source> +<target>Volymnamnet %x är inte en del av sökvägen %y.</target> <source>Abort requested: Waiting for current operation to finish...</source> <target>Avbryter: Väntar pÃ¥ att aktuell process skall slutföras...</target> @@ -349,9 +388,6 @@ <source>Idle time between last detected change and execution of command</source> <target>Väntetid mellan senast upptäckta förändring och kommandoexekvering</target> -<source>Command line</source> -<target>Kommandofält</target> - <source> The command is triggered if: - files or subfolders change @@ -375,9 +411,6 @@ Kommandot triggas om: <source>RealtimeSync - Automated Synchronization</source> <target>RealtimeSync - Automatiserad synkronisering</target> -<source>Warning</source> -<target>Varning</target> - <source>Build: %x</source> <target>Bygge: %x</target> @@ -387,15 +420,21 @@ Kommandot triggas om: <source>All files</source> <target>Alla filer</target> +<source>Directory monitoring active</source> +<target>Mappövervakning aktiv</target> + +<source>Waiting until all directories are available...</source> +<target>Väntar pÃ¥ att samtliga mappar skall bli tillgängliga...</target> + <source>&Restore</source> <target>&Ã…terställ</target> +<source>&Show error</source> +<target>&Visa fel</target> + <source>&Exit</source> <target>&Avsluta</target> -<source>Waiting for missing directories...</source> -<target>Väntar pÃ¥ saknade mappsökvägar...</target> - <source>Invalid command line:</source> <target>Ogiltig kommandorad:</target> @@ -405,14 +444,14 @@ Kommandot triggas om: <source>File time and size</source> <target>Tidsstämpling och storlek</target> -<source> Two way </source> -<target> TvÃ¥vägs </target> +<source>Two way</source> +<target>TvÃ¥vägs</target> <source>Mirror</source> -<target>Spegla </target> +<target>Spegla</target> <source>Update</source> -<target>Uppdatera </target> +<target>Uppdatera</target> <source>Custom</source> <target>Anpassat</target> @@ -468,11 +507,8 @@ Kommandot triggas om: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>Följande objekt har olösta konflikter, och kommer inte att synkroniseras:</target> -<source>Significant difference detected:</source> -<target>Betydande skillnad upptäckt:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>mer än 50% av totalt filantal kommer att kopieras eller tas bort.</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>Följande mappar är signifikant olika. Kontrollera att du jämför rätt mappar för synkronisering.</target> <source>Not enough free disk space available in:</source> <target>Ej tillräckligt ledigt diskutrymme pÃ¥:</target> @@ -492,12 +528,15 @@ Kommandot triggas om: <source>Generating database...</source> <target>Skapar databas...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>Skapar Volume Shadow Copy för %x...</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>Skapar en 'Volume Shadow Copy' för %x...</target> <source>Data verification error: %x and %y have different content.</source> <target>Dataverifieringsfel: %x och %y har olika innehÃ¥ll.</target> +<source>job name</source> +<target>Ã¥tgärdsnamn</target> + <source>Synchronization aborted</source> <target>Synkronisering avbruten</target> @@ -522,6 +561,9 @@ Kommandot triggas om: <source>Switching to FreeFileSync main dialog</source> <target>Växlar till FreeFileSyncs huvuddialog</target> +<source>Retrying operation after error:</source> +<target>Försöker utföra Ã¥tgärden igen, efter fel:</target> + <source>A new version of FreeFileSync is available:</source> <target>Det finns en ny version av FreeFileSync</target> @@ -645,8 +687,8 @@ Kommandot triggas om: <source>&Export file list...</source> <target>&Exportera fillista...</target> -<source>&Global settings...</source> -<target>&Allmäna inställningar...</target> +<source>&Global settings</source> +<target>&Allmäna inställningar</target> <source>&Tools</source> <target>&Verktyg</target> @@ -717,6 +759,9 @@ Kommandot triggas om: <source>Synchronizing...</source> <target>Synkroniserar...</target> +<source>Minimize to notification area</source> +<target>Minimera till meddelandefältet</target> + <source>On completion</source> <target>Vid slutfört</target> @@ -726,6 +771,15 @@ Kommandot triggas om: <source>&Pause</source> <target>&Paus</target> +<source>Variant</source> +<target>Variant</target> + +<source>Statistics</source> +<target>Statistik</target> + +<source>&Don't show this dialog again</source> +<target>&Visa inte den här dialogen igen</target> + <source>Select a variant</source> <target>Välj en variant</target> @@ -774,6 +828,12 @@ Filerna betecknas som lika om, <source>Configure your own synchronization rules.</source> <target>Konfigurera dina egna synkroniseringsregler.</target> +<source>Detect moved files</source> +<target>Hitta flyttade filer</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Kräver databasfiler som inte stöds av alla filsystem</target> + <source>Error handling</source> <target>Felhantering</target> @@ -798,17 +858,17 @@ Filerna betecknas som lika om, <source>Delete or overwrite files permanently</source> <target>Ta bort eller skriv över permanent</target> -<source>Recycle Bin</source> +<source>Recycle bin</source> <target>Papperskorgen</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Använd papperskorgen för borttagna och överskrivna filer</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Kopiera borttagna och överskrivna filer till papperskorgen</target> <source>Versioning</source> <target>Versionshantering</target> -<source>Move files to user-defined folder</source> -<target>Flytta filer till användardefinierad mapp</target> +<source>Move files to a user-defined folder</source> +<target>Flytta filer till en fördefinierad mapp</target> <source>Naming convention:</source> <target>Regler för namngivning</target> @@ -816,8 +876,8 @@ Filerna betecknas som lika om, <source>Batch job</source> <target>Batch-jobb</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Skapa en batch-fil för att automatisera synkroniseringen. Dubbelklicka pÃ¥ filen, eller använd systemets schemaläggare och schemalägg: FreeFileSync.exe <filnamn>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Skapa en batch-fil för obevakad synkronisering. Dubbelklicka pÃ¥ filen för att starta den, eller schemalägg i en Ã¥tgärdshanterare: %x</target> <source>Exit</source> <target>Avsluta</target> @@ -871,12 +931,12 @@ Filerna betecknas som lika om, <target>Ta bort pÃ¥ bÃ¥da sidor, även om filen är markerad pÃ¥ endast en sida</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -Endast filer som matchar alla inställningar, kommer att synkroniseras. -Notera att filnamn mÃ¥ste stÃ¥ i förhÃ¥llande till basmappar +Filer synkroniseras endast om de klarar alla filterregler. +OBS! Sökvägar mÃ¥ste vara relaterade till ursprungsmappar. </target> <source>Include</source> @@ -906,20 +966,20 @@ Notera att filnamn mÃ¥ste stÃ¥ i förhÃ¥llande till basmappar <source>Fail-safe file copy</source> <target>Felsäker filkopiering</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>Skriv först till en temporär fil (*.ffs_tmp) och byt sedan namn pÃ¥ den. Detta garanterar en konsistent status även vid allvarliga fel</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>Kopiera till en temporär fil först (*.ffs_tmp), och byt sedan namn pÃ¥ den. Detta garanterar ett konsekvent tillstÃ¥nd även vid allvarliga fel.</target> <source>Copy locked files</source> <target>Kopiera lÃ¥sta filer</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Kopiera delade eller lÃ¥sta filer med hjälp av Volume Shadow Copy Service (Kräver administratörsrättighet)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>Kopiera delade eller lÃ¥sta filer med tjänsten 'Volume Shadow Copy' (kräver administratörsbehörighet)</target> <source>Copy file access permissions</source> <target>Kopiera filÃ¥tkomstbehörigheter</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Överför behörigheter för filer och mappar (Kräver administratörsrättigheter)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>Överför fil- och mappbehörigheter (kräver administratörsbehörighet)</target> <source>Restore hidden dialogs</source> <target>Ã…terställ dolda dialoger</target> @@ -933,15 +993,6 @@ Notera att filnamn mÃ¥ste stÃ¥ i förhÃ¥llande till basmappar <source>&Default</source> <target>&Standard</target> -<source>Variant</source> -<target>Variant</target> - -<source>Statistics</source> -<target>Statistik</target> - -<source>Don't show this dialog again</source> -<target>Visa inte det här igen</target> - <source>Find what:</source> <target>Sök efter:</target> @@ -951,15 +1002,15 @@ Notera att filnamn mÃ¥ste stÃ¥ i förhÃ¥llande till basmappar <source>&Find next</source> <target>&Sök nästa</target> +<source>Start synchronization</source> +<target>Starta synkronisering</target> + <source>Delete</source> <target>Ta bort</target> <source>Configure filter</source> <target>Filterinställningar</target> -<source>Start synchronization</source> -<target>Starta synkronisering</target> - <source>Find</source> <target>Sök</target> @@ -994,6 +1045,21 @@ Notera att filnamn mÃ¥ste stÃ¥ i förhÃ¥llande till basmappar <target>Jämför bÃ¥da sidor</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>Vill du verkligen köra kommandot %y för 1 objekt?</pluralform> +<pluralform>Vill du verkligen köra kommandot %y för %x objekt?</pluralform> +</target> + +<source>Confirm</source> +<target>Bekräfta</target> + +<source>&Execute</source> +<target>&Kör</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1029,12 +1095,15 @@ Notera att filnamn mÃ¥ste stÃ¥ i förhÃ¥llande till basmappar <source>Include temporarily</source> <target>Inkludera tillfälligt</target> -<source>Exclude via filter:</source> -<target>Lägg till i undantag:</target> - <source>multiple selection</source> <target>flerval</target> +<source>Include via filter:</source> +<target>Inkludera via filter:</target> + +<source>Exclude via filter:</source> +<target>Lägg till i undantag:</target> + <source>Include all</source> <target>Inkludera alla</target> @@ -1080,8 +1149,8 @@ Notera att filnamn mÃ¥ste stÃ¥ i förhÃ¥llande till basmappar <source>Do&n't save</source> <target>Spara &inte</target> -<source>Never save changes</source> -<target>Spara aldrig ändringar</target> +<source>Never save &changes</source> +<target>Spara aldrig &ändringar</target> <source>Show files that exist on left side only</source> <target>Visa filer som endast finns till vänster</target> @@ -1134,8 +1203,8 @@ Notera att filnamn mÃ¥ste stÃ¥ i förhÃ¥llande till basmappar <source>All folders are in sync</source> <target>Alla mappar är synkroniserade</target> -<source>Comma separated list</source> -<target>Komma-separerad lista</target> +<source>Comma-separated values</source> +<target>Kommaseparerade värden</target> <source>File list exported</source> <target>Fillista exporterad</target> @@ -1143,8 +1212,8 @@ Notera att filnamn mÃ¥ste stÃ¥ i förhÃ¥llande till basmappar <source>Searching for program updates...</source> <target>Söker efter programuppdateringar...</target> -<source>Ignore further errors</source> -<target>Ignorera ytterligare fel</target> +<source>&Ignore subsequent errors</source> +<target>&Ignorera efterföljande fel</target> <source>&Ignore</source> <target>&Ignorera</target> @@ -1152,8 +1221,8 @@ Notera att filnamn mÃ¥ste stÃ¥ i förhÃ¥llande till basmappar <source>Fatal Error</source> <target>Allvarligt fel</target> -<source>Don't show this warning again</source> -<target>Visa inte denna varning igen.</target> +<source>&Don't show this warning again</source> +<target>&Visa inte den här varningen igen</target> <source>&Switch</source> <target>&Växla</target> @@ -1188,14 +1257,11 @@ Notera att filnamn mÃ¥ste stÃ¥ i förhÃ¥llande till basmappar <source>Completed</source> <target>Slutförd</target> -<source>Continue</source> -<target>Fortsätt</target> +<source>&Continue</source> +<target>&Fortsätt</target> -<source>Pause</source> -<target>Paus</target> - -<source>Logging</source> -<target>Loggar</target> +<source>Log</source> +<target>Logg</target> <source>Cannot find %x</source> <target>Kan inte hitta %x</target> @@ -1231,8 +1297,8 @@ Notera att filnamn mÃ¥ste stÃ¥ i förhÃ¥llande till basmappar <target>Filter</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> <pluralform>Vill du verkligen flytta följande objekt till papperskorgen?</pluralform> @@ -1290,9 +1356,6 @@ Notera att filnamn mÃ¥ste stÃ¥ i förhÃ¥llande till basmappar <source>Append a timestamp to each file name</source> <target>Lägg till en tidsstämpel till varje filnamn</target> -<source>Folder</source> -<target>Mapp</target> - <source>File</source> <target>Fil</target> @@ -1413,8 +1476,8 @@ Notera att filnamn mÃ¥ste stÃ¥ i förhÃ¥llande till basmappar <source>Cannot change process I/O priorities.</source> <target>Kan inte ändra process I/O-prioritet</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>Kan inte flytta %x till Papperskorgen.</target> +<source>Unable to move %x to the recycle bin.</source> +<target>Kan inte att flytta %x till papperskorgen</target> <source>Cannot determine final path for %x.</source> <target>Kan inte utläsa slutlig sökväg för %x.</target> diff --git a/BUILD/Languages/turkish.lng b/BUILD/Languages/turkish.lng index 6f0e74b4..870eb214 100644 --- a/BUILD/Languages/turkish.lng +++ b/BUILD/Languages/turkish.lng @@ -7,9 +7,6 @@ <plural_definition>n == 1 ? 0 : 1</plural_definition> </header> -<source>Retrying operation after error:</source> -<target></target> - <source>Both sides have changed since last synchronization.</source> <target>Son eÅŸleÅŸtirmeden bu yana iki tarafın da içeriÄŸi deÄŸiÅŸmiÅŸ.</target> @@ -28,14 +25,14 @@ <source>Checking recycle bin availability for folder %x...</source> <target>%x klasörü için Geri Dönüşüm Kutusu kullanılabilir mi diye bakılıyor...</target> -<source>Moving file %x to recycle bin</source> -<target>%x dosyası geri dönüşüm kutusuna atılıyor</target> +<source>Moving file %x to the recycle bin</source> +<target>%x dosyası Geri Dönüşüm Kutusuna atılıyor</target> -<source>Moving folder %x to recycle bin</source> -<target>%x klasörü geri dönüşüm kutusuna atılıyor</target> +<source>Moving folder %x to the recycle bin</source> +<target>%x klasörü Geri Dönüşüm Kutusuna atılıyor</target> -<source>Moving symbolic link %x to recycle bin</source> -<target>%x sembolik baÄŸlantısı geri dönüşüm kutusuna atılıyor</target> +<source>Moving symbolic link %x to the recycle bin</source> +<target>%x simgesel baÄŸlantısı Geri Dönüşüm Kutusuna atılıyor</target> <source>Deleting file %x</source> <target>%x dosyası siliniyor</target> @@ -46,14 +43,20 @@ <source>Deleting symbolic link %x</source> <target>%x sembolik baÄŸlantısı siliniyor</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>Åžu klasörler için Geri Dönüşüm Kutusu kullanılamaz. Dosyalar geri döndürülemeyecek ÅŸekilde silinir:</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>Åžu klasörler için Geri Dönüşüm Kutusu kullanılamaz. Dosyalar kalıcı olarak silinecek:</target> <source>An exception occurred</source> <target>OlaÄŸan dışı bir durumla karşılaşıldı</target> -<source>Cannot find file %x.</source> -<target>%x dosyası bulunamadı.</target> +<source>A directory path is expected after %x.</source> +<target>%x ardından bir klasör yolu gelmelidir.</target> + +<source>Syntax error</source> +<target>Yazım hatası</target> + +<source>Cannot open file %x.</source> +<target>%x dosyası açılamıyor.</target> <source>Error</source> <target>Hata</target> @@ -61,6 +64,36 @@ <source>File %x does not contain a valid configuration.</source> <target>%x dosyası geçerli ayar bilgilerini içermiyor.</target> +<source>Unequal number of left and right directories specified.</source> +<target>SaÄŸdan ve soldan seçilen klasör sayısı aynı deÄŸil.</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>Klasörler komut satırından seçildiÄŸinde, ayar dosyasında klasör çifti düzeyinde ayar bulunmamalıdır.</target> + +<source>Warning</source> +<target>Uyarı</target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target>Klasörler bir ayar dosyasından fazlasında kullanılamaz.</target> + +<source>Syntax:</source> +<target>Yazım:</target> + +<source>config files</source> +<target>ayar dosyaları</target> + +<source>directory</source> +<target>klasör</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>FreeFileSync .ffs_gui ya da .ffs_batch ayar dosyalarının sayısı.</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>En çok bir ayar dosyası için alternatif klasörlerin sayısı.</target> + +<source>Command line</source> +<target>Komut satırı</target> + <source>A folder input field is empty.</source> <target>Bir klasör giriÅŸ alanı boÅŸ.</target> @@ -110,22 +143,22 @@ <target>Bellek yetersiz.</target> <source>Item exists on left side only</source> -<target>Sol taraftaki ögeler</target> +<target>Yalnız solda bulunan ögeler</target> <source>Item exists on right side only</source> -<target>SaÄŸ taraftaki ögeler</target> +<target>Yalnız saÄŸda bulunan ögeler</target> <source>Left side is newer</source> -<target>Sol taraftaki daha yeni ögeler</target> +<target>Soldaki daha yeni ögeler</target> <source>Right side is newer</source> -<target>SaÄŸ taraftaki daha yeni ögeler</target> +<target>SaÄŸdaki daha yeni ögeler</target> <source>Items have different content</source> <target>İçeriÄŸi farklı ögeler</target> <source>Both sides are equal</source> -<target>Ä°ki taraftada aynı</target> +<target>Öge iki taraftada aynı</target> <source>Conflict/item cannot be categorized</source> <target>UyuÅŸmayan/sınıflanamayan ögeler</target> @@ -218,12 +251,12 @@ <target>Toplam süre:</target> <source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </source> <target> -<pluralform>1 Bayt</pluralform> -<pluralform>%x Bayt</pluralform> +<pluralform>1 bayt</pluralform> +<pluralform>%x bayt</pluralform> </target> <source>%x MB</source> @@ -245,12 +278,12 @@ <target>Taranıyor:</target> <source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </source> <target> -<pluralform>[1 Ä°ÅŸ]</pluralform> -<pluralform>[%x Ä°ÅŸ]</pluralform> +<pluralform>1 iÅŸ parçacığı</pluralform> +<pluralform>%x iÅŸ parçacığı</pluralform> </target> <source>Encoding extended time information: %x</source> @@ -259,6 +292,9 @@ <source>/sec</source> <target>/saniye</target> +<source>%x items</source> +<target>%x öge</target> + <source>Configuration file %x loaded partially only.</source> <target>%x ayarlar dosyası kısmen yüklendi.</target> @@ -271,8 +307,8 @@ <source>Browse directory</source> <target>Klasöre gözatın</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Birim Gölge Kopya hizmetine eriÅŸilemedi.</target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target>Birim Gölge Hizmetine eriÅŸilemiyor.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>Bu sistem üzerinde gölge kopyalar oluÅŸturmak için FreeFileSync 64-bit sürümünü kullanın.</target> @@ -283,8 +319,8 @@ <source>Cannot determine volume name for %x.</source> <target>%x için birim adı belirlenemedi.</target> -<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>Volume name %x is not part of file path %y.</source> +<target>%x birim adı %y dosya yolunun bir parçası deÄŸil.</target> <source>Abort requested: Waiting for current operation to finish...</source> <target>Vazgeçildi: Yürürlükteki iÅŸlemin bitmesi bekleniyor...</target> @@ -352,9 +388,6 @@ <source>Idle time between last detected change and execution of command</source> <target>Son algılanan deÄŸiÅŸiklik ile komutun yürütülmesi arasında beklenecek süre</target> -<source>Command line</source> -<target>Komut satırı</target> - <source> The command is triggered if: - files or subfolders change @@ -373,14 +406,11 @@ Komut ÅŸu durumlarda yürütülür: <target>&Yeniden deneyin</target> <source>Cancel</source> -<target>Ä°ptal Edin</target> +<target>Ä°ptal</target> <source>RealtimeSync - Automated Synchronization</source> <target>RealtimeSync - KendiliÄŸinden EÅŸleÅŸtirme</target> -<source>Warning</source> -<target>Uyarı</target> - <source>Build: %x</source> <target>Yapım: %x</target> @@ -390,15 +420,21 @@ Komut ÅŸu durumlarda yürütülür: <source>All files</source> <target>Tüm dosyalar</target> +<source>Directory monitoring active</source> +<target>Klasör izleme kullanılıyor</target> + +<source>Waiting until all directories are available...</source> +<target>Tüm klasörlerin uygun olması bekleniyor...</target> + <source>&Restore</source> -<target>Ge&ri yükleyin</target> +<target>Gö&rüntülensin</target> + +<source>&Show error</source> +<target>Hataya &bakın</target> <source>&Exit</source> <target>Çı&kın</target> -<source>Waiting for missing directories...</source> -<target>Kayıp klasörler için bekleniyor...</target> - <source>Invalid command line:</source> <target>Geçersiz komut satırı:</target> @@ -471,11 +507,8 @@ Komut ÅŸu durumlarda yürütülür: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>UyuÅŸmazlığı çözülmemiÅŸ ÅŸu ögeler eÅŸleÅŸtirilmeyecek:</target> -<source>Significant difference detected:</source> -<target>Önemli fark saptandı:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>Dosyaların yarıdan fazlası kopyalanacak ya da silinecek.</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>Åžu klasörler arasında oldukça büyük farklar var. EÅŸleÅŸtirme için doÄŸru klasörleri seçtiÄŸinize emin olun.</target> <source>Not enough free disk space available in:</source> <target>Åžurada yeterli disk alanı yok :</target> @@ -495,12 +528,15 @@ Komut ÅŸu durumlarda yürütülür: <source>Generating database...</source> <target>Veri tabanı oluÅŸturuluyor...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>%x için Birim Gölge Kopyası oluÅŸturuluyor...</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>%x için Birim Gölge Hizmeti oluÅŸturuluyor...</target> <source>Data verification error: %x and %y have different content.</source> <target>Veri doÄŸrulama hatası: %x ve %y farklı içeriklere sahip.</target> +<source>job name</source> +<target>iÅŸ adı</target> + <source>Synchronization aborted</source> <target>EÅŸleÅŸtirme durduruldu</target> @@ -525,6 +561,9 @@ Komut ÅŸu durumlarda yürütülür: <source>Switching to FreeFileSync main dialog</source> <target>FreeFileSync ana penceresine geçiliyor</target> +<source>Retrying operation after error:</source> +<target>Hatanın ardından iÅŸlem yeniden deneniyor:</target> + <source>A new version of FreeFileSync is available:</source> <target>Yeni bir FreeFileSync sürümü yayınlanmış:</target> @@ -586,7 +625,7 @@ Komut ÅŸu durumlarda yürütülür: <target>Klasör ya da dosyaları sürükleyip buraya bırakabilirsiniz</target> <source>Close progress dialog</source> -<target>Ä°ÅŸlem penceresini kapatılsın</target> +<target>Ä°ÅŸlem penceresi kapatılsın</target> <source>Standby</source> <target>Uykuya dalınsın</target> @@ -648,8 +687,8 @@ Komut ÅŸu durumlarda yürütülür: <source>&Export file list...</source> <target>Dosya list&esini verin...</target> -<source>&Global settings...</source> -<target>&Genel ayarlar...</target> +<source>&Global settings</source> +<target>&Genel ayarlar</target> <source>&Tools</source> <target>A&raçlar</target> @@ -658,7 +697,7 @@ Komut ÅŸu durumlarda yürütülür: <target>&Sürümü Denetleyin</target> <source>Check &automatically once a week</source> -<target>&KendiliÄŸinden haftada bir denetlensin</target> +<target>&Haftada bir kendiliÄŸinden denetlensin</target> <source>Check for new &version</source> <target>Yeni &sürümü denetleyin</target> @@ -720,17 +759,29 @@ Komut ÅŸu durumlarda yürütülür: <source>Synchronizing...</source> <target>EÅŸleÅŸtiriliyor...</target> +<source>Minimize to notification area</source> +<target>Bildirim alanına küçültün</target> + <source>On completion</source> <target>Ä°ÅŸlem tamamlandığında:</target> <source>Close</source> -<target>Kapatılsın</target> +<target>Kapatın</target> <source>&Pause</source> <target>&Duraklatılsın</target> +<source>Variant</source> +<target>Ä°ÅŸlem tipi</target> + +<source>Statistics</source> +<target>Ä°statistikler</target> + +<source>&Don't show this dialog again</source> +<target>Bu &pencere bir daha görüntülenmesin</target> + <source>Select a variant</source> -<target>Bir çeÅŸit seçin</target> +<target>Ä°ÅŸlem tipini seçin</target> <source> Files are found equal if @@ -757,7 +808,7 @@ aynı olmalıdır </target> <source>Symbolic Link handling</source> -<target>Sembolik baÄŸlantı iÅŸleme:</target> +<target>Sembolik baÄŸlantılar:</target> <source>Help</source> <target>Yardım</target> @@ -777,6 +828,12 @@ aynı olmalıdır <source>Configure your own synchronization rules.</source> <target>EÅŸleÅŸtirme kurallarını istediÄŸiniz ÅŸekilde ayarlayabilirsiniz.</target> +<source>Detect moved files</source> +<target>Taşınmış dosyalar algılansın</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Veritabanı dosyalarına gerek duyar. Tüm dosya sistemleri tarafından desteklenmez.</target> + <source>Error handling</source> <target>Hata olursa:</target> @@ -801,17 +858,17 @@ aynı olmalıdır <source>Delete or overwrite files permanently</source> <target>Dosyalar kalıcı olarak silinir ya da üzerine yazılır</target> -<source>Recycle Bin</source> -<target>Geri Dönüşüm Kutusuna gönderilsin</target> +<source>Recycle bin</source> +<target>Geri Dönüşüm Kutusuna atılsın</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>Silinen ve üzerine yazılan dosyalar Geri Dönüşüm Kutusuna gönderilir</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Geri Dönüşüm Kutusundaki silinmiÅŸ ya da üzerine yazılmış dosyalar yedeklensin</target> <source>Versioning</source> <target>Eski sürüm olarak saklansın</target> -<source>Move files to user-defined folder</source> -<target>Dosyalar kullanıcı tarafından belirlenen bir klasöre taşınsın</target> +<source>Move files to a user-defined folder</source> +<target>Dosyalar kullanıcı tarafından belirtilen bir klasöre taşınsın</target> <source>Naming convention:</source> <target>Adlandırma kuralı:</target> @@ -819,8 +876,8 @@ aynı olmalıdır <source>Batch job</source> <target>Toplu iÅŸ</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Toplu iÅŸ dosyası ile otomatik eÅŸleÅŸtirme yapılabilir. Dosyadaki iÅŸlemler, çift tıklanarak ya da sisteminizdeki görev zamanlayıcıya; FreeFileSync.exe <görev adı>.ffs_batch ÅŸeklinde eklenerek yürütülebilir.</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Katılımsız eÅŸleÅŸtirme için bir toplu iÅŸ dosyası oluÅŸturun. Ä°ÅŸlemi baÅŸlatmak için bu dosyaya çift tıklayın ya da görev zamanlayıcı ile programlayın: %x</target> <source>Exit</source> <target>Çıkın</target> @@ -874,19 +931,19 @@ aynı olmalıdır <target>Dosya yalnız bir tarafta seçili olsa bile her iki taraftaki de silinir</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -Yalnız süzgeç ayarlarına tamamen uyan dosyalar eÅŸleÅŸtirilir. -Not: Dosya adları kök klasörlere göre bağıl olmalıdır. +Yalnız tüm süzgeç kurallarına uyan dosyalar eÅŸleÅŸtirilir. +Not: Dosya yolları seçilmiÅŸ klasörlere göre yazılmalıdır. </target> <source>Include</source> -<target>Katılsın:</target> +<target>Katılacak ögeler:</target> <source>Exclude</source> -<target>Katılmasın</target> +<target>Katılmayacak ögeler</target> <source>Time span</source> <target>Zaman aralığı</target> @@ -909,20 +966,20 @@ Not: Dosya adları kök klasörlere göre bağıl olmalıdır. <source>Fail-safe file copy</source> <target>Dosyalar hatasız kopyalansın</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>Kopyalama önce geçici bir dosyaya (*.ffs_tmp) yapılır. Sonra dosya yeniden adlandırılır. Böylece hatalara karşı daha saÄŸlıklı bir çalışma ortamı saÄŸlanır.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>Dosyalar önce geçici dosyaya kopyalanıp (*.ffs_tmp) sonra yeniden adlandırılır. Bu yöntem, ciddi bir hata oluÅŸması durumunda bile iÅŸlemin tutarlı yapılmasını saÄŸlar.</target> <source>Copy locked files</source> <target>Kilitli dosyalar da kopyalansın</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Paylaşılan ya da kilitli dosyalar, Gölge Kopya Hizmeti'ni kullanarak kopyalanır (yönetici izinleri gerekir).</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>Paylaşılan ya da kilitlenmiÅŸ dosyalar Birim Gölge Hizmetini kullanılarak kopyalanır (yönetici hakları gereklidir)</target> <source>Copy file access permissions</source> <target>Dosya eriÅŸim izinleri de kopyalansın</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Dosya ve klasör izinleri de kopyalanır (yönetici izinleri gerekir).</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>Dosya ve klasör izinleri de aktarılır (yönetici hakları gereklidir)</target> <source>Restore hidden dialogs</source> <target>GizlenmiÅŸ iletiler yeniden görüntülensin</target> @@ -936,15 +993,6 @@ Not: Dosya adları kök klasörlere göre bağıl olmalıdır. <source>&Default</source> <target>&Varsayılan</target> -<source>Variant</source> -<target>Ä°ÅŸlem tipi</target> - -<source>Statistics</source> -<target>Ä°statistikler</target> - -<source>Don't show this dialog again</source> -<target>Bu ileti artık görüntülenmesin</target> - <source>Find what:</source> <target>Aranacak:</target> @@ -954,15 +1002,15 @@ Not: Dosya adları kök klasörlere göre bağıl olmalıdır. <source>&Find next</source> <target>&Sonrakini bulun</target> +<source>Start synchronization</source> +<target>EÅŸleÅŸtirmeyi baÅŸlatın</target> + <source>Delete</source> <target>Silin</target> <source>Configure filter</source> <target>Süzgeci ayarlayın</target> -<source>Start synchronization</source> -<target>EÅŸleÅŸtirmeyi baÅŸlatın</target> - <source>Find</source> <target>Arayın</target> @@ -997,6 +1045,21 @@ Not: Dosya adları kök klasörlere göre bağıl olmalıdır. <target>Ä°ki tarafı karşılaÅŸtırır</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>1 öge için %y komutunu çalıştırmak istediÄŸinize emin misiniz?</pluralform> +<pluralform>%x öge için %y komutunu çalıştırmak istediÄŸinize emin misiniz?</pluralform> +</target> + +<source>Confirm</source> +<target>Onaylayın</target> + +<source>&Execute</source> +<target>Çalış&tırın</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1032,12 +1095,15 @@ Not: Dosya adları kök klasörlere göre bağıl olmalıdır. <source>Include temporarily</source> <target>Geçici olarak katılsın</target> -<source>Exclude via filter:</source> -<target>Süzerek dışarda bırakılsın:</target> - <source>multiple selection</source> <target>çoklu seçim</target> +<source>Include via filter:</source> +<target>Åžu süzgeçle katılsın:</target> + +<source>Exclude via filter:</source> +<target>Süzerek dışarda bırakılsın:</target> + <source>Include all</source> <target>Tümü katılsın</target> @@ -1083,29 +1149,29 @@ Not: Dosya adları kök klasörlere göre bağıl olmalıdır. <source>Do&n't save</source> <target>Kaydedilmesi&n</target> -<source>Never save changes</source> -<target>DeÄŸiÅŸiklikler asla kaydedilmesin</target> +<source>Never save &changes</source> +<target>DeÄŸiÅŸiklikler asla &kaydedilmesin</target> <source>Show files that exist on left side only</source> -<target>Yalnız sol tarafta bulunan dosyalar görüntülensin</target> +<target>Yalnız sol tarafta bulunan dosyaları görüntüler ya da gizler</target> <source>Show files that exist on right side only</source> -<target>Yalnız saÄŸ tarafta bulunan dosyalar görüntülensin</target> +<target>Yalnız saÄŸ tarafta bulunan dosyaları görüntüler ya da gizler</target> <source>Show files that are newer on left</source> -<target>Solda daha yeni olan dosyalar görüntülensin</target> +<target>Solda daha yeni olan dosyaları görüntüler ya da gizler</target> <source>Show files that are newer on right</source> -<target>SaÄŸda daha yeni olan dosyalar görüntülensin</target> +<target>SaÄŸda daha yeni olan dosyaları görüntüler ya da gizler</target> <source>Show files that are equal</source> -<target>Aynı olan dosyalar görüntülensin</target> +<target>Aynı olan dosyaları görüntüler ya da gizler</target> <source>Show files that are different</source> -<target>Farklı olan dosyalar görüntülensin</target> +<target>Farklı olan dosyaları görüntüler ya da gizler</target> <source>Show conflicts</source> -<target>UyuÅŸmazlıklar görüntülensin</target> +<target>UyuÅŸmazlıkları görüntüler ya da gizler</target> <source>Show files that will be created on the left side</source> <target>Sol tarafa eklenecek dosyalar görüntülensin</target> @@ -1137,8 +1203,8 @@ Not: Dosya adları kök klasörlere göre bağıl olmalıdır. <source>All folders are in sync</source> <target>Tüm klasörler eÅŸleÅŸtirildi</target> -<source>Comma separated list</source> -<target>Virgül ile ayrılmış liste</target> +<source>Comma-separated values</source> +<target>Virgül ile ayrılmış deÄŸerler</target> <source>File list exported</source> <target>Dosya listesi verildi</target> @@ -1146,8 +1212,8 @@ Not: Dosya adları kök klasörlere göre bağıl olmalıdır. <source>Searching for program updates...</source> <target>Yazılım güncellemesine bakılıyor...</target> -<source>Ignore further errors</source> -<target>Sonraki hatalar yoksayılsın</target> +<source>&Ignore subsequent errors</source> +<target>Sonraki &hatalar yoksayılsın</target> <source>&Ignore</source> <target>&Yoksayın</target> @@ -1155,8 +1221,8 @@ Not: Dosya adları kök klasörlere göre bağıl olmalıdır. <source>Fatal Error</source> <target>Ölümcül Hata</target> -<source>Don't show this warning again</source> -<target>Bu uyarı artık görüntülenmesin</target> +<source>&Don't show this warning again</source> +<target>Bu uyarı bir daha &görüntülenmesin</target> <source>&Switch</source> <target>&DeÄŸiÅŸtirin</target> @@ -1191,20 +1257,17 @@ Not: Dosya adları kök klasörlere göre bağıl olmalıdır. <source>Completed</source> <target>Tamamlandı</target> -<source>Continue</source> -<target>Devam edin</target> - -<source>Pause</source> -<target>Duraklatın</target> +<source>&Continue</source> +<target>&Devam</target> -<source>Logging</source> -<target>Günlükleme</target> +<source>Log</source> +<target>Günlük</target> <source>Cannot find %x</source> <target>%x bulunamadı</target> <source>Inactive</source> -<target>Devre dışı</target> +<target>Kullanılmıyor</target> <source>Today</source> <target>Bugün</target> @@ -1234,12 +1297,12 @@ Not: Dosya adları kök klasörlere göre bağıl olmalıdır. <target>Süzgeç</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>AÅŸağıdaki 1 ögeyi Geri Dönüşüm Kutusuna göndermek istediÄŸinize emin misiniz?</pluralform> -<pluralform>AÅŸağıdaki %x ögeyi Geri Dönüşüm Kutusuna göndermek istediÄŸinize emin misiniz?</pluralform> +<pluralform>AÅŸağıdaki ögeyi Geri Dönüşüm Kutusuna atmak istediÄŸinize emin misiniz?</pluralform> +<pluralform>AÅŸağıdaki %x ögeyi Geri Dönüşüm Kutusuna atmak istediÄŸinize emin misiniz?</pluralform> </target> <source> @@ -1413,8 +1476,8 @@ Not: Dosya adları kök klasörlere göre bağıl olmalıdır. <source>Cannot change process I/O priorities.</source> <target>GiriÅŸ/Çıkış iÅŸlemi öncelikleri deÄŸiÅŸtirilemedi</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>%x Geri Dönüşüm Kutusuna gönderilemedi.</target> +<source>Unable to move %x to the recycle bin.</source> +<target>%x Geri Dönüşüm Kutusuna atılamıyor.</target> <source>Cannot determine final path for %x.</source> <target>Son %x yolu belirlenemedi.</target> diff --git a/BUILD/Languages/ukrainian.lng b/BUILD/Languages/ukrainian.lng index 68b045a1..0b5406b7 100644 --- a/BUILD/Languages/ukrainian.lng +++ b/BUILD/Languages/ukrainian.lng @@ -7,7 +7,7 @@ <plural_definition>n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2</plural_definition> </header> -<source>Retrying operation after error:</source> +<source>Close search bar</source> <target></target> <source>Both sides have changed since last synchronization.</source> @@ -31,14 +31,14 @@ <source>Checking recycle bin availability for folder %x...</source> <target>Перевірка доÑтупноÑÑ‚Ñ– Корзини Ð´Ð»Ñ Ð¿Ð°Ð¿ÐºÐ¸ %x...</target> -<source>Moving file %x to recycle bin</source> -<target>ÐŸÐµÑ€ÐµÐ¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ %x у Корзину</target> +<source>Moving file %x to the recycle bin</source> +<target>ÐŸÐµÑ€ÐµÐ¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ %x до Корзини</target> -<source>Moving folder %x to recycle bin</source> -<target>ÐŸÐµÑ€ÐµÐ¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¿Ð°Ð¿ÐºÐ¸ %x у Корзину</target> +<source>Moving folder %x to the recycle bin</source> +<target>ÐŸÐµÑ€ÐµÐ¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¿Ð°Ð¿ÐºÐ¸ %x до Корзини</target> -<source>Moving symbolic link %x to recycle bin</source> -<target>ÐŸÐµÑ€ÐµÐ¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ñимвольного поÑÐ¸Ð»Ð°Ð½Ð½Ñ %x у Корзину</target> +<source>Moving symbolic link %x to the recycle bin</source> +<target>ÐŸÐµÑ€ÐµÐ¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ñимволічного поÑÐ¸Ð»Ð°Ð½Ð½Ñ %x до Корзини</target> <source>Deleting file %x</source> <target>Ð’Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ %x</target> @@ -49,14 +49,20 @@ <source>Deleting symbolic link %x</source> <target>Ð’Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ Ñимвольного поÑÐ¸Ð»Ð°Ð½Ð½Ñ %x</target> -<source>The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:</source> -<target>Корзина Ð´Ð»Ñ Ð¿Ð°Ð¿Ð¾Ðº недоÑтупна. Файли будуть вилучені назавжди:</target> +<source>The recycle bin is not available for the following folders. Files will be deleted permanently instead:</source> +<target>Корзина не доÑтупна Ð´Ð»Ñ Ñ‚Ð°ÐºÐ¸Ñ… папок. Файли заміÑÑ‚ÑŒ цього будуть видалені назавжди:</target> <source>An exception occurred</source> <target>ВідбулоÑÑŒ виключеннÑ</target> -<source>Cannot find file %x.</source> -<target>Ðе вдаєтьÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ файлу %x.</target> +<source>A directory path is expected after %x.</source> +<target>ПіÑÐ»Ñ %x очікуєтьÑÑ ÑˆÐ»ÑÑ… до каталогу.</target> + +<source>Syntax error</source> +<target>СинтакÑична помилка</target> + +<source>Cannot open file %x.</source> +<target>Ðе вдаєтьÑÑ Ñ„Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл %x.</target> <source>Error</source> <target>Помилка</target> @@ -64,6 +70,36 @@ <source>File %x does not contain a valid configuration.</source> <target>Файл %x не міÑтить правильної конфігурації.</target> +<source>Unequal number of left and right directories specified.</source> +<target>Вказано різну кількіÑÑ‚ÑŒ лівих Ñ– правих каталогів</target> + +<source>The config file must not contain settings at directory pair level when directories are set via command line.</source> +<target>Конфігураційний файл не повинен міÑтити налаштувань на рівні пар каталогів, Ñкщо каталоги задаютьÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð½Ð¸Ð¼ Ñ€Ñдком.</target> + +<source>Warning</source> +<target>Увага</target> + +<source>Directories cannot be set for more than one configuration file.</source> +<target>Каталоги не можуть бути призначені більш ніж одному файлу конфігурації.</target> + +<source>Syntax:</source> +<target>СинтакÑиÑ:</target> + +<source>config files</source> +<target>файли конфігурації</target> + +<source>directory</source> +<target>каталог</target> + +<source>Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.</source> +<target>Будь-Ñка кількіÑÑ‚ÑŒ FreeFileSync .ffs_gui та/або .ffs_batch файлів конфігурації.</target> + +<source>Any number of alternative directories for at most one config file.</source> +<target>Будь-Ñка кількіÑÑ‚ÑŒ альтернативних каталогів Ð´Ð»Ñ Ñ‰Ð¾Ð½Ð°Ð¹Ð±Ñ–Ð»ÑŒÑˆÐµ одного конфігураційного файлу.</target> + +<source>Command line</source> +<target>Командний Ñ€Ñдок</target> + <source>A folder input field is empty.</source> <target>Порожнє поле папки.</target> @@ -222,8 +258,8 @@ <target>Загальний чаÑ:</target> <source> -<pluralform>1 Byte</pluralform> -<pluralform>%x Bytes</pluralform> +<pluralform>1 byte</pluralform> +<pluralform>%x bytes</pluralform> </source> <target> <pluralform>%x байт</pluralform> @@ -250,13 +286,13 @@ <target>Сканую:</target> <source> -<pluralform>[1 Thread]</pluralform> -<pluralform>[%x Threads]</pluralform> +<pluralform>1 thread</pluralform> +<pluralform>%x threads</pluralform> </source> <target> -<pluralform>[%x Ðить виконаннÑ]</pluralform> -<pluralform>[%x Ðиті виконаннÑ]</pluralform> -<pluralform>[%x Ðитей виконаннÑ]</pluralform> +<pluralform>%x нить виконаннÑ</pluralform> +<pluralform>%x ниті виконаннÑ</pluralform> +<pluralform>%x нитей виконаннÑ</pluralform> </target> <source>Encoding extended time information: %x</source> @@ -265,6 +301,9 @@ <source>/sec</source> <target>/Ñек</target> +<source>%x items</source> +<target>%x елементів</target> + <source>Configuration file %x loaded partially only.</source> <target>Файл конфігурації %x завантажено лише чаÑтково.</target> @@ -277,8 +316,8 @@ <source>Browse directory</source> <target>ПереглÑнути каталог</target> -<source>Cannot access Volume Shadow Copy Service.</source> -<target>Ðе вдаєтьÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ доÑтуп до поÑлуги тіньового ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ñ‚Ð¾Ð¼Ñƒ</target> +<source>Cannot access the Volume Shadow Copy Service.</source> +<target>Ðе вдаєтьÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ доÑтуп до поÑлуги Тіньового ÐšÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ð¢Ð¾Ð¼Ñƒ.</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>Будь лаÑка, викориÑтовуйте 64-розрÑдну верÑÑ–ÑŽ FreeFileSync Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ‚Ñ–Ð½ÑŒÐ¾Ð²Ð¸Ñ… копій у цій ÑиÑтемі.</target> @@ -289,8 +328,8 @@ <source>Cannot determine volume name for %x.</source> <target>Ðе вдалоÑÑ Ð²Ñтановити ім'Ñ Ñ‚Ð¾Ð¼Ñƒ Ð´Ð»Ñ %x.</target> -<source>Volume name %x not part of file name %y.</source> -<target>Ð†Ð¼â€™Ñ Ñ‚Ð¾Ð¼Ñƒ %x не Ñ” чаÑтиною імені файлу %y.</target> +<source>Volume name %x is not part of file path %y.</source> +<target>Ім'Ñ Ñ‚Ð¾Ð¼Ñƒ %x не Ñ” чаÑтиною файловго шлÑху %y.</target> <source>Abort requested: Waiting for current operation to finish...</source> <target>Запит перериваннÑ: Ð’ очікуванні Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¾Ñ— операції...</target> @@ -358,9 +397,6 @@ <source>Idle time between last detected change and execution of command</source> <target>Ð§Ð°Ñ Ð¿Ñ€Ð¾Ñтою між виÑвленнÑм оÑтанньої зміни та виконаннÑм команди</target> -<source>Command line</source> -<target>Командний Ñ€Ñдок</target> - <source> The command is triggered if: - files or subfolders change @@ -384,9 +420,6 @@ The command is triggered if: <source>RealtimeSync - Automated Synchronization</source> <target>RealtimeSync - Ðвтоматична ÑинхронізаціÑ</target> -<source>Warning</source> -<target>Увага</target> - <source>Build: %x</source> <target>компілÑÑ†Ñ–Ñ %x</target> @@ -396,15 +429,21 @@ The command is triggered if: <source>All files</source> <target>Ð’ÑÑ– файли</target> +<source>Directory monitoring active</source> +<target>Моніторинг каталогів активний</target> + +<source>Waiting until all directories are available...</source> +<target>ÐžÑ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾ÑтупноÑÑ‚Ñ– вÑÑ–Ñ… каталогів...</target> + <source>&Restore</source> <target>&Відновити</target> +<source>&Show error</source> +<target>&Показати помилку</target> + <source>&Exit</source> <target>&Вихід</target> -<source>Waiting for missing directories...</source> -<target>ÐžÑ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ð¿ÑƒÑ‰ÐµÐ½Ð¸Ñ… каталогів...</target> - <source>Invalid command line:</source> <target>Ðеправильний командний Ñ€Ñдок:</target> @@ -414,14 +453,14 @@ The command is triggered if: <source>File time and size</source> <target>Дата та розмір файлу</target> -<source> Two way </source> -<target> Обидва напрÑмки </target> +<source>Two way</source> +<target>Обидва напрÑмки</target> <source>Mirror</source> -<target>Дзеркало </target> +<target>Дзеркало</target> <source>Update</source> -<target>Оновити </target> +<target>Оновити</target> <source>Custom</source> <target>Вибірково</target> @@ -477,11 +516,8 @@ The command is triggered if: <source>The following items have unresolved conflicts and will not be synchronized:</source> <target>ÐаÑтупні елементи мають невирішені конфлікти Ñ– не будуть Ñинхронізовані:</target> -<source>Significant difference detected:</source> -<target>ВиÑвлена Ñ–Ñтотна різницÑ:</target> - -<source>More than 50% of the total number of files will be copied or deleted.</source> -<target>Понад 50% загальної кількоÑÑ‚Ñ– файлів буде зкопійовано чи вилучено.</target> +<source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> +<target>Ці папки Ñ–Ñтотно відрізнÑÑŽÑ‚ÑŒÑÑ. ПереконайтеÑÑ, що ви вказали відповідні папки Ð´Ð»Ñ Ñинхронізації.</target> <source>Not enough free disk space available in:</source> <target>Ðе доÑтатньо вільного міÑÑ†Ñ Ð²:</target> @@ -501,12 +537,15 @@ The command is triggered if: <source>Generating database...</source> <target>Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð±Ð°Ð·Ð¸ даних...</target> -<source>Creating Volume Shadow Copy for %x...</source> -<target>Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¢Ð¾Ð¼Ñƒ тіньового ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ %x...</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¢Ñ–Ð½ÑŒÐ¾Ð²Ð¾Ñ— Копії Ð´Ð»Ñ %x...</target> <source>Data verification error: %x and %y have different content.</source> <target>Помилка перевірки даних: %x та %y мають різний вміÑÑ‚.</target> +<source>job name</source> +<target>назва завданнÑ</target> + <source>Synchronization aborted</source> <target>Ð¡Ð¸Ð½Ñ…Ñ€Ð¾Ð½Ñ–Ð·Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¸Ð¿Ð¸Ð½ÐµÐ½Ð°</target> @@ -531,6 +570,9 @@ The command is triggered if: <source>Switching to FreeFileSync main dialog</source> <target>Перехід до головного діалогу FreeFileSync</target> +<source>Retrying operation after error:</source> +<target>Ð’Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ— піÑÐ»Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸:</target> + <source>A new version of FreeFileSync is available:</source> <target>ДоÑтупна нова верÑÑ–Ñ FreeFileSync:</target> @@ -654,8 +696,8 @@ The command is triggered if: <source>&Export file list...</source> <target>&ЕкÑпортувати ÑпиÑок файлів...</target> -<source>&Global settings...</source> -<target>&Глобальні налаштуваннÑ...</target> +<source>&Global settings</source> +<target>&Глобальні налаштуваннÑ</target> <source>&Tools</source> <target>&ІнÑтрументи</target> @@ -672,12 +714,6 @@ The command is triggered if: <source>Compare</source> <target>ПорівнÑти</target> -<source>Comparison settings</source> -<target>ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ€Ñ–Ð²Ð½ÑŽÐ²Ð°Ð½Ð½Ñ</target> - -<source>Synchronization settings</source> -<target>ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñинхронізації</target> - <source>Synchronize</source> <target>Синхронізувати</target> @@ -690,6 +726,12 @@ The command is triggered if: <source>Swap sides</source> <target>ПомінÑти міÑцÑми</target> +<source>Find what:</source> +<target>Знайти:</target> + +<source>Match case</source> +<target>Враховувати регіÑÑ‚Ñ€</target> + <source>Save as batch job</source> <target>Зберегти Ñк пакетне завданнÑ</target> @@ -726,6 +768,9 @@ The command is triggered if: <source>Synchronizing...</source> <target>СинхронізаціÑ...</target> +<source>Minimize to notification area</source> +<target>Згорнути в облаÑÑ‚ÑŒ повідомлень</target> + <source>On completion</source> <target>ПіÑÐ»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ</target> @@ -735,6 +780,15 @@ The command is triggered if: <source>&Pause</source> <target>&Пауза</target> +<source>Variant</source> +<target>Варіант</target> + +<source>Statistics</source> +<target>СтатиÑтика</target> + +<source>&Don't show this dialog again</source> +<target>Більше &не показувати цей діалог</target> + <source>Select a variant</source> <target>Виберіть варіант</target> @@ -779,6 +833,12 @@ is the same <source>Configure your own synchronization rules.</source> <target>Ðалаштувати влаÑні правила Ñинхронізації.</target> +<source>Detect moved files</source> +<target>ВиÑвлÑти переміщені файли</target> + +<source>Requires database files. Not supported by all file systems.</source> +<target>Потрібні файли бази даних. ПідтримуєтьÑÑ Ð½Ðµ вÑіма файловими ÑиÑтемами.</target> + <source>Error handling</source> <target>Обробка помилок</target> @@ -803,16 +863,16 @@ is the same <source>Delete or overwrite files permanently</source> <target>Вилучати чи перезапиÑати файли назавжди</target> -<source>Recycle Bin</source> +<source>Recycle bin</source> <target>Корзина</target> -<source>Use Recycle Bin for deleted and overwritten files</source> -<target>ВикориÑтати Корзину Ð´Ð»Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð¸Ñ… Ñ– перезапиÑаних файлів</target> +<source>Back up deleted and overwritten files in the recycle bin</source> +<target>Резервно зберегти вилучені та перезаиÑані файли в Корзині</target> <source>Versioning</source> <target>Ð—Ð°Ð¿Ð¸Ñ Ð²ÐµÑ€Ñій</target> -<source>Move files to user-defined folder</source> +<source>Move files to a user-defined folder</source> <target>ПереміÑтити файли у визначену кориÑтувачем папку</target> <source>Naming convention:</source> @@ -821,8 +881,8 @@ is the same <source>Batch job</source> <target>Пакетне завданнÑ</target> -<source>Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch</source> -<target>Ð”Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ð·Ð°Ñ†Ñ–Ñ— Ñинхронізації Ñтворіть пакетний файл. Двічі клацніть цей файл чи впишіть до ÑиÑтемного планувальника завдань: FreeFileSync.exe <назва завданнÑ>.ffs_batch</target> +<source>Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x</source> +<target>Створити пакетний файл Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾Ñ— Ñинхронізації. Щоб розпочати двічі клацніть цей файл або заплануйте в планувальнику завдань: %x</target> <source>Exit</source> <target>Вихід</target> @@ -845,30 +905,6 @@ is the same <source>Limit maximum number of log files</source> <target>Обмежити макÑимальну кількіÑÑ‚ÑŒ файлів журналу</target> -<source>Source code written in C++ using:</source> -<target>Код програми напиÑаний на C++ з викориÑтаннÑм:</target> - -<source>If you like FreeFileSync</source> -<target>Якщо Вам ÑподобавÑÑ FreeFileSync</target> - -<source>Donate with PayPal</source> -<target>Пожертвувати через PayPal</target> - -<source>Many thanks for localization:</source> -<target>ПодÑка за локалізацію:</target> - -<source>Feedback and suggestions are welcome</source> -<target>Відгуки та пропозиції вітаютьÑÑ</target> - -<source>Homepage</source> -<target>Оф.Ñайт</target> - -<source>Email</source> -<target>Почта</target> - -<source>Published under the GNU General Public License</source> -<target>Видано за ліцензією GNU General Public License</target> - <source>Delete on both sides</source> <target>Вилучити з обох Ñторін</target> @@ -876,12 +912,12 @@ is the same <target>Вилучити з обох Ñторін, навіть Ñкщо файл виділений тільки з однієї Ñторони</target> <source> -Only files that match all filter settings will be synchronized. -Note: File names must be relative to base directories. +Files will only be synchronized if they pass all filter rules. +Note: File paths must be relative to base directories. </source> <target> -Тільки файли, Ñкі задовільнÑÑŽÑ‚ÑŒ вÑім налаштуваннÑм фільтра будуть Ñинхронізовані. -Увага: Ðазви файлів вказуютьÑÑ Ð²Ñ–Ð´Ð½Ð¾Ñно базових каталогів. +Файли будуть Ñинхронізовані тільки Ñкщо вони задовільнÑÑŽÑ‚ÑŒ уÑім правилам фільтрації. +Примітка: ШлÑхи до файлів повинні бути відноÑними до базових каталогів. </target> <source>Include</source> @@ -911,20 +947,20 @@ Note: File names must be relative to base directories. <source>Fail-safe file copy</source> <target>Безпечне ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð²</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>ЗапиÑати до тимчаÑового файлу (*.ffs_tmp), а потім перейменувати. Це гарантує Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… навіть при критичній помилці.</target> +<source>Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error.</source> +<target>Скопіюйте Ñпочатку в тимчаÑовий файл (*.ffs_tmp), потім перейменуйте його. Це гарантує узгоджений Ñтан навіть у разі Ð²Ð¸Ð½Ð¸ÐºÐ½ÐµÐ½Ð½Ñ Ñ„Ð°Ñ‚Ð°Ð»ÑŒÐ½Ð¾Ñ— помилки.</target> <source>Copy locked files</source> <target>Копіювати заблоковані файли</target> -<source>Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)</source> -<target>Копіювати Ñпільних чи заблокованих файлів з викориÑтаннÑм поÑлуги Тіньового ÐšÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ð¢Ð¾Ð¼Ñƒ (потрібні права ÐдмініÑтратора)</target> +<source>Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)</source> +<target>Копіювати Ñпільні та заблоковані файли за допомогою ÑервіÑу Тіньового ÐšÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ð¢Ð¾Ð¼Ñƒ (потрібні права адмініÑтратора)</target> <source>Copy file access permissions</source> <target>Копіювати права доÑтупу до файлу</target> -<source>Transfer file and folder permissions (Requires Administrator rights)</source> -<target>Дозволи переноÑу файлів та папок (Вимагає прав ÐдмініÑтратора)</target> +<source>Transfer file and folder permissions (requires administrator rights)</source> +<target>ПеренеÑти права файлів Ñ– папок (потрібні права адмініÑтратора)</target> <source>Restore hidden dialogs</source> <target>Відновити Ñховані діалоги</target> @@ -938,35 +974,44 @@ Note: File names must be relative to base directories. <source>&Default</source> <target>&За замовчуваннÑм</target> -<source>Variant</source> -<target>Варіант</target> +<source>Source code written in C++ using:</source> +<target>Код програми напиÑаний на C++ з викориÑтаннÑм:</target> -<source>Statistics</source> -<target>СтатиÑтика</target> +<source>If you like FreeFileSync</source> +<target>Якщо Вам ÑподобавÑÑ FreeFileSync</target> -<source>Don't show this dialog again</source> -<target>Ðе показувати надалі цього діалогу</target> +<source>Donate with PayPal</source> +<target>Пожертвувати через PayPal</target> -<source>Find what:</source> -<target>Знайти:</target> +<source>Feedback and suggestions are welcome</source> +<target>Відгуки та пропозиції вітаютьÑÑ</target> -<source>Match case</source> -<target>Враховувати регіÑÑ‚Ñ€</target> +<source>Homepage</source> +<target>Оф.Ñайт</target> -<source>&Find next</source> -<target>&Знайти наÑтупний</target> +<source>Email</source> +<target>Почта</target> -<source>Delete</source> -<target>Видалити</target> +<source>Published under the GNU General Public License</source> +<target>Видано за ліцензією GNU General Public License</target> -<source>Configure filter</source> -<target>ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ñ–Ð»ÑŒÑ‚Ñ€Ð°</target> +<source>Many thanks for localization:</source> +<target>ПодÑка за локалізацію:</target> <source>Start synchronization</source> <target>Розпочати Ñинхронізацію</target> -<source>Find</source> -<target>Знайти</target> +<source>Comparison settings</source> +<target>ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ€Ñ–Ð²Ð½ÑŽÐ²Ð°Ð½Ð½Ñ</target> + +<source>Synchronization settings</source> +<target>ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñинхронізації</target> + +<source>Delete</source> +<target>Видалити</target> + +<source>Configure filter</source> +<target>ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ñ–Ð»ÑŒÑ‚Ñ€Ð°</target> <source>Select time span</source> <target>Виберіть чаÑовий інтервал</target> @@ -974,6 +1019,9 @@ Note: File names must be relative to base directories. <source>Folder pairs</source> <target>Пари папок</target> +<source>Find</source> +<target>Знайти</target> + <source>Overview</source> <target>Головна</target> @@ -999,6 +1047,22 @@ Note: File names must be relative to base directories. <target>ПорівнÑти обидві Ñторони</target> <source> +<pluralform>Do you really want to execute the command %y for 1 item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>Ви дійÑно хочете виконати команду %y Ð´Ð»Ñ %x елемента?</pluralform> +<pluralform>Ви дійÑно хочете виконати команду %y Ð´Ð»Ñ %x елементів?</pluralform> +<pluralform>Ви дійÑно хочете виконати команду %y Ð´Ð»Ñ %x елементів?</pluralform> +</target> + +<source>Confirm</source> +<target>Підтвердити</target> + +<source>&Execute</source> +<target>&Виконати</target> + +<source> <pluralform>1 directory</pluralform> <pluralform>%x directories</pluralform> </source> @@ -1031,17 +1095,20 @@ Note: File names must be relative to base directories. <source>Set direction:</source> <target>Виберіть напрÑм:</target> -<source>Exclude temporarily</source> -<target>Виключити тимчаÑово</target> +<source>multiple selection</source> +<target>груповий вибір</target> -<source>Include temporarily</source> -<target>Включити</target> +<source>Include via filter:</source> +<target>Включити згідно фільтру:</target> <source>Exclude via filter:</source> <target>Виключити через фільтр:</target> -<source>multiple selection</source> -<target>груповий вибір</target> +<source>Exclude temporarily</source> +<target>Виключити тимчаÑово</target> + +<source>Include temporarily</source> +<target>Включити</target> <source>Include all</source> <target>Включити вÑе</target> @@ -1088,8 +1155,8 @@ Note: File names must be relative to base directories. <source>Do&n't save</source> <target>&Ðе зберігати</target> -<source>Never save changes</source> -<target>Ðіколи не зберігати змін</target> +<source>Never save &changes</source> +<target>Ðіколи не зберігати &зміни</target> <source>Show files that exist on left side only</source> <target>Показати файли, Ñкі Ñ” тільки ліворуч</target> @@ -1142,8 +1209,11 @@ Note: File names must be relative to base directories. <source>All folders are in sync</source> <target>Ð’ÑÑ– папки Ñинхронізовано</target> -<source>Comma separated list</source> -<target>Розділений комами ÑпиÑок</target> +<source>Cannot find %x</source> +<target>Ðе можна знайти %x</target> + +<source>Comma-separated values</source> +<target>Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»ÐµÐ½Ñ– комою</target> <source>File list exported</source> <target>СпиÑок файлів екÑпортовано</target> @@ -1151,8 +1221,8 @@ Note: File names must be relative to base directories. <source>Searching for program updates...</source> <target>Пошук оновлень програми ...</target> -<source>Ignore further errors</source> -<target>Ігнорувати майбутні помилки</target> +<source>&Ignore subsequent errors</source> +<target>&Ігнорувати наÑтупні помилки</target> <source>&Ignore</source> <target>&Ігнорувати</target> @@ -1160,8 +1230,8 @@ Note: File names must be relative to base directories. <source>Fatal Error</source> <target>Критична помилка</target> -<source>Don't show this warning again</source> -<target>Ðе показувати більше це попередженнÑ</target> +<source>&Don't show this warning again</source> +<target>&Ðадалі не показувати це попередженнÑ</target> <source>&Switch</source> <target>&Змінити</target> @@ -1196,17 +1266,11 @@ Note: File names must be relative to base directories. <source>Completed</source> <target>Завершено</target> -<source>Continue</source> -<target>Далі</target> - -<source>Pause</source> -<target>Пауза</target> +<source>&Continue</source> +<target>&Продовжити</target> -<source>Logging</source> -<target>Лог-файли</target> - -<source>Cannot find %x</source> -<target>Ðе можна знайти %x</target> +<source>Log</source> +<target>Лог</target> <source>Inactive</source> <target>Ðеактивний</target> @@ -1239,13 +1303,13 @@ Note: File names must be relative to base directories. <target>Фільтр</target> <source> -<pluralform>Do you really want to move the following item to the Recycle Bin?</pluralform> -<pluralform>Do you really want to move the following %x items to the Recycle Bin?</pluralform> +<pluralform>Do you really want to move the following item to the recycle bin?</pluralform> +<pluralform>Do you really want to move the following %x items to the recycle bin?</pluralform> </source> <target> -<pluralform>Ви дійÑно хочете переміÑтити цей %x елемент до Корзини?</pluralform> -<pluralform>Ви дійÑно хочете переміÑтити ці %x елементи до Корзини?</pluralform> -<pluralform>Ви дійÑно хочете переміÑтити ці %x елементів до Корзини?</pluralform> +<pluralform>Ви дійÑно хочете переміÑтити цей %x елемент у Корзину?</pluralform> +<pluralform>Ви дійÑно хочете переміÑтити ці %x елементи у Корзину?</pluralform> +<pluralform>Ви дійÑно хочете переміÑтити ці %x елементів у Корзину?</pluralform> </target> <source> @@ -1300,9 +1364,6 @@ Note: File names must be relative to base directories. <source>Append a timestamp to each file name</source> <target>Додати чаÑову мітку до кожного імені файлу</target> -<source>Folder</source> -<target>Папка</target> - <source>File</source> <target>Файл</target> @@ -1426,8 +1487,8 @@ Note: File names must be relative to base directories. <source>Cannot change process I/O priorities.</source> <target>Ðе вдалоÑÑ Ð·Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸ пріоритетів Ð’Ñ…/Вих процеÑу.</target> -<source>Unable to move %x to the Recycle Bin.</source> -<target>Ðе вдаєтьÑÑ Ð¿ÐµÑ€ÐµÐ½ÐµÑти %x до Корзини.</target> +<source>Unable to move %x to the recycle bin.</source> +<target>Ðе вдаєтьÑÑ Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñтити %x до Корзини.</target> <source>Cannot determine final path for %x.</source> <target>Ðе вдаєтьÑÑ Ð²Ð¸Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ кінцевого шлÑху Ð´Ð»Ñ %x.</target> diff --git a/BUILD/Resources.zip b/BUILD/Resources.zip Binary files differindex 4b79261a..cf73407d 100644 --- a/BUILD/Resources.zip +++ b/BUILD/Resources.zip diff --git a/FreeFileSync.vcxproj b/FreeFileSync.vcxproj index fd2c8db9..ed3a8a34 100644 --- a/FreeFileSync.vcxproj +++ b/FreeFileSync.vcxproj @@ -114,14 +114,14 @@ <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);Wininet.lib</AdditionalDependencies> + <AdditionalDependencies>wxmsw29ud_aui.lib;wxmsw29ud_adv.lib;wxmsw29ud_core.lib;wxbase29ud_net.lib;wxbase29ud.lib;wxpngd.lib;wxzlibd.lib;comctl32.lib;ws2_32.lib;Rpcrt4.lib;winmm.lib;%(AdditionalDependencies);Wininet.lib</AdditionalDependencies> <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage\lib;C:\Program Files\C++\wxWidgets\lib\vc12_x86_debug_dll</AdditionalLibraryDirectories> <LinkStatus> </LinkStatus> </Link> <ResourceCompile> <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include</AdditionalIncludeDirectories> - <PreprocessorDefinitions>%(PreprocessorDefinitions);</PreprocessorDefinitions> + <PreprocessorDefinitions>%(PreprocessorDefinitions);ZEN_ARCHITECTURE_X86</PreprocessorDefinitions> </ResourceCompile> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> @@ -146,7 +146,7 @@ <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);Wininet.lib</AdditionalDependencies> + <AdditionalDependencies>wxbase29ud.lib;wxmsw29ud_core.lib;wxmsw29ud_adv.lib;wxmsw29ud_aui.lib;wxbase29ud_net.lib;wxpngd.lib;wxzlibd.lib;comctl32.lib;ws2_32.lib;Rpcrt4.lib;winmm.lib;%(AdditionalDependencies);Wininet.lib</AdditionalDependencies> <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage_x64\lib;C:\Program Files\C++\wxWidgets\lib\vc12_x64_debug_dll</AdditionalLibraryDirectories> <LinkStatus> </LinkStatus> @@ -155,7 +155,7 @@ </Link> <ResourceCompile> <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include</AdditionalIncludeDirectories> - <PreprocessorDefinitions>%(PreprocessorDefinitions);WX_CPU_AMD64</PreprocessorDefinitions> + <PreprocessorDefinitions>%(PreprocessorDefinitions);ZEN_ARCHITECTURE_X64</PreprocessorDefinitions> </ResourceCompile> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> @@ -167,7 +167,7 @@ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;wxUSE_UNICODE;__WXMSW__;ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <AdditionalIncludeDirectories>C:\Program Files\C++\Boost;C:\Program Files\C++\wxWidgets\include;C:\Program Files\C++\wxWidgets\lib\vc12_x86_release_lib\mswu;.</AdditionalIncludeDirectories> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - <DisableSpecificWarnings>4100;4512</DisableSpecificWarnings> + <DisableSpecificWarnings>4100;4512;4996</DisableSpecificWarnings> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <MultiProcessorCompilation>true</MultiProcessorCompilation> <ForcedIncludeFiles>zen/warn_static.h</ForcedIncludeFiles> @@ -177,7 +177,7 @@ <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);Wininet.lib</AdditionalDependencies> + <AdditionalDependencies>wxmsw29u_aui.lib;wxmsw29u_adv.lib;wxmsw29u_core.lib;wxbase29u.lib;wxpng.lib;wxzlib.lib;wxbase29u_net.lib;comctl32.lib;ws2_32.lib;winmm.lib;Rpcrt4.lib;%(AdditionalDependencies);Wininet.lib</AdditionalDependencies> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage\lib;C:\Program Files\C++\wxWidgets\lib\vc12_x86_release_lib</AdditionalLibraryDirectories> <LinkStatus> @@ -185,7 +185,7 @@ </Link> <ResourceCompile> <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include</AdditionalIncludeDirectories> - <PreprocessorDefinitions>%(PreprocessorDefinitions);</PreprocessorDefinitions> + <PreprocessorDefinitions>%(PreprocessorDefinitions);ZEN_ARCHITECTURE_X86</PreprocessorDefinitions> </ResourceCompile> <PostBuildEvent> <Command>"C:\Program Files\C++\CodeSigning\SignCode.cmd" "$(TargetPath)"</Command> @@ -200,7 +200,7 @@ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;wxUSE_UNICODE;__WXMSW__;ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <AdditionalIncludeDirectories>C:\Program Files\C++\Boost;C:\Program Files\C++\wxWidgets\include;C:\Program Files\C++\wxWidgets\lib\vc12_x64_release_lib\mswu;.</AdditionalIncludeDirectories> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - <DisableSpecificWarnings>4100;4512</DisableSpecificWarnings> + <DisableSpecificWarnings>4100;4512;4996</DisableSpecificWarnings> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <MultiProcessorCompilation>true</MultiProcessorCompilation> <ForcedIncludeFiles>zen/warn_static.h</ForcedIncludeFiles> @@ -211,7 +211,7 @@ <GenerateDebugInformation>true</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);Wininet.lib</AdditionalDependencies> + <AdditionalDependencies>wxmsw29u_aui.lib;wxmsw29u_adv.lib;wxmsw29u_core.lib;wxbase29u.lib;wxpng.lib;wxzlib.lib;wxbase29u_net.lib;comctl32.lib;ws2_32.lib;winmm.lib;Rpcrt4.lib;%(AdditionalDependencies);Wininet.lib</AdditionalDependencies> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage_x64\lib;C:\Program Files\C++\wxWidgets\lib\vc12_x64_release_lib</AdditionalLibraryDirectories> <LinkStatus> @@ -219,7 +219,7 @@ </Link> <ResourceCompile> <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include</AdditionalIncludeDirectories> - <PreprocessorDefinitions>%(PreprocessorDefinitions);WX_CPU_AMD64</PreprocessorDefinitions> + <PreprocessorDefinitions>%(PreprocessorDefinitions);ZEN_ARCHITECTURE_X64</PreprocessorDefinitions> </ResourceCompile> <PostBuildEvent> <Command>"C:\Program Files\C++\CodeSigning\SignCode.cmd" "$(TargetPath)"</Command> @@ -271,13 +271,13 @@ <ClCompile Include="ui\tray_icon.cpp" /> <ClCompile Include="ui\tree_view.cpp" /> <ClCompile Include="ui\triple_splitter.cpp" /> - <ClCompile Include="wx+\button.cpp" /> <ClCompile Include="wx+\create_pch.cpp"> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> </ClCompile> <ClCompile Include="wx+\graph.cpp" /> <ClCompile Include="wx+\grid.cpp" /> + <ClCompile Include="wx+\image_tools.cpp" /> <ClCompile Include="wx+\mouse_move_dlg.cpp" /> <ClCompile Include="wx+\tooltip.cpp" /> <ClCompile Include="wx+\zlib_wrap.cpp" /> @@ -42,7 +42,7 @@ CXXFLAGS += `wx-config --cxxflags --debug=no` LINKFLAGS += `wx-config --libs std, aui --debug=no` -lboost_thread -lboost_system -lz else #static wxWidgets and boost library linkage for precompiled release -WX_CONFIG_BIN =$(HOME)/Desktop/wxGTK-2.8.12/lib/release/bin/wx-config +WX_CONFIG_BIN =$(HOME)/Desktop/wxWidgets-2.9.5/lib/release/bin/wx-config CXXFLAGS += -I$(HOME)/Desktop/boost_1_54_0 BOOST_LIB_DIR =$(HOME)/Desktop/boost_1_54_0/stage/lib @@ -56,7 +56,7 @@ ifeq ($(OPERATING_SYSTEM_NAME), Darwin) COMPILER_BIN=clang++ -stdlib=libc++ CXXFLAGS += -DZEN_MAC -WX_CONFIG_BIN =$(HOME)/Desktop/wxWidgets-2.9.4/lib/release/bin/wx-config +WX_CONFIG_BIN =$(HOME)/Desktop/wxWidgets-2.9.5/lib/release/bin/wx-config CXXFLAGS += -I$(HOME)/Desktop/boost_1_54_0 BOOST_LIB_DIR =$(HOME)/Desktop/boost_1_54_0/stage/lib MACOS_SDK =-mmacosx-version-min=10.7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk @@ -68,7 +68,7 @@ CXXFLAGS += $(MACOS_SDK) `$(WX_CONFIG_BIN) --cxxflags --debug=no --static= LINKFLAGS += $(MACOS_SDK) `$(WX_CONFIG_BIN) --libs std, aui --debug=no --static=yes` $(BOOST_LIB_DIR)/libboost_thread.a $(BOOST_LIB_DIR)/libboost_system.a endif -##################################################################################################### +###################################################### CPP_LIST= #internal list of all *.cpp files needed for compilation CPP_LIST+=algorithm.cpp @@ -121,7 +121,7 @@ CPP_LIST+=zen/zstring.cpp CPP_LIST+=zen/format_unit.cpp CPP_LIST+=zen/process_priority.cpp CPP_LIST+=wx+/grid.cpp -CPP_LIST+=wx+/button.cpp +CPP_LIST+=wx+/image_tools.cpp CPP_LIST+=wx+/graph.cpp CPP_LIST+=wx+/tooltip.cpp CPP_LIST+=wx+/zlib_wrap.cpp diff --git a/RealtimeSync/RealtimeSync.vcxproj b/RealtimeSync/RealtimeSync.vcxproj index 08abd76f..dbaa2aa5 100644 --- a/RealtimeSync/RealtimeSync.vcxproj +++ b/RealtimeSync/RealtimeSync.vcxproj @@ -113,12 +113,12 @@ <SubSystem>Windows</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> <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> + <AdditionalDependencies>wxmsw29ud_adv.lib;wxmsw29ud_core.lib;wxbase29ud.lib;wxpngd.lib;wxzlibd.lib;wxbase29ud_net.lib;comctl32.lib;ws2_32.lib;Rpcrt4.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage\lib;C:\Program Files\C++\wxWidgets\lib\vc12_x86_debug_dll</AdditionalLibraryDirectories> </Link> <ResourceCompile> <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include</AdditionalIncludeDirectories> - <PreprocessorDefinitions>%(PreprocessorDefinitions);</PreprocessorDefinitions> + <PreprocessorDefinitions>%(PreprocessorDefinitions);ZEN_ARCHITECTURE_X86</PreprocessorDefinitions> </ResourceCompile> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> @@ -143,14 +143,14 @@ <SubSystem>Windows</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> <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> + <AdditionalDependencies>wxmsw29ud_adv.lib;wxmsw29ud_core.lib;wxbase29ud.lib;wxpngd.lib;wxzlibd.lib;wxbase29ud_net.lib;comctl32.lib;ws2_32.lib;Rpcrt4.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage_x64\lib;C:\Program Files\C++\wxWidgets\lib\vc12_x64_debug_dll</AdditionalLibraryDirectories> <LinkStatus> </LinkStatus> </Link> <ResourceCompile> <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include</AdditionalIncludeDirectories> - <PreprocessorDefinitions>%(PreprocessorDefinitions);WX_CPU_AMD64</PreprocessorDefinitions> + <PreprocessorDefinitions>%(PreprocessorDefinitions);ZEN_ARCHITECTURE_X64</PreprocessorDefinitions> </ResourceCompile> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> @@ -162,7 +162,7 @@ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;wxUSE_UNICODE;__WXMSW__;ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <AdditionalIncludeDirectories>C:\Program Files\C++\Boost;C:\Program Files\C++\wxWidgets\include;C:\Program Files\C++\wxWidgets\lib\vc12_x86_release_lib\mswu;..</AdditionalIncludeDirectories> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - <DisableSpecificWarnings>4100;4512</DisableSpecificWarnings> + <DisableSpecificWarnings>4100;4512;4996</DisableSpecificWarnings> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <MultiProcessorCompilation>true</MultiProcessorCompilation> <ForcedIncludeFiles>zen/warn_static.h</ForcedIncludeFiles> @@ -172,13 +172,13 @@ <GenerateDebugInformation>false</GenerateDebugInformation> <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> - <AdditionalDependencies>wxbase28u.lib;wxmsw28u_adv.lib;wxmsw28u_core.lib;wxpng.lib;wxzlib.lib;wxbase28u_net.lib;comctl32.lib;ws2_32.lib;winmm.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>wxbase29u.lib;wxmsw29u_adv.lib;wxmsw29u_core.lib;wxpng.lib;wxzlib.lib;wxbase29u_net.lib;comctl32.lib;ws2_32.lib;winmm.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage\lib;C:\Program Files\C++\wxWidgets\lib\vc12_x86_release_lib</AdditionalLibraryDirectories> </Link> <ResourceCompile> <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include</AdditionalIncludeDirectories> - <PreprocessorDefinitions>%(PreprocessorDefinitions);</PreprocessorDefinitions> + <PreprocessorDefinitions>%(PreprocessorDefinitions);ZEN_ARCHITECTURE_X86</PreprocessorDefinitions> </ResourceCompile> <PostBuildEvent> <Command>"C:\Program Files\C++\CodeSigning\SignCode.cmd" "$(TargetPath)"</Command> @@ -193,7 +193,7 @@ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;wxUSE_UNICODE;__WXMSW__;ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <AdditionalIncludeDirectories>C:\Program Files\C++\Boost;C:\Program Files\C++\wxWidgets\include;C:\Program Files\C++\wxWidgets\lib\vc12_x64_release_lib\mswu;..</AdditionalIncludeDirectories> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - <DisableSpecificWarnings>4100;4512</DisableSpecificWarnings> + <DisableSpecificWarnings>4100;4512;4996</DisableSpecificWarnings> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <MultiProcessorCompilation>true</MultiProcessorCompilation> <ForcedIncludeFiles>zen/warn_static.h</ForcedIncludeFiles> @@ -203,13 +203,13 @@ <GenerateDebugInformation>false</GenerateDebugInformation> <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> - <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> + <AdditionalDependencies>wxmsw29u_adv.lib;wxmsw29u_core.lib;wxbase29u.lib;wxpng.lib;wxzlib.lib;wxbase29u_net.lib;comctl32.lib;ws2_32.lib;winmm.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage_x64\lib;C:\Program Files\C++\wxWidgets\lib\vc12_x64_release_lib</AdditionalLibraryDirectories> </Link> <ResourceCompile> <AdditionalIncludeDirectories>C:\Program Files\C++\wxWidgets\include</AdditionalIncludeDirectories> - <PreprocessorDefinitions>%(PreprocessorDefinitions);WX_CPU_AMD64</PreprocessorDefinitions> + <PreprocessorDefinitions>%(PreprocessorDefinitions);ZEN_ARCHITECTURE_X64</PreprocessorDefinitions> </ResourceCompile> <PostBuildEvent> <Command>"C:\Program Files\C++\CodeSigning\SignCode.cmd" "$(TargetPath)"</Command> @@ -224,11 +224,11 @@ <ClCompile Include="..\structures.cpp" /> <ClCompile Include="..\ui\dir_name.cpp" /> <ClCompile Include="..\ui\folder_history_box.cpp" /> - <ClCompile Include="..\wx+\button.cpp" /> <ClCompile Include="..\wx+\create_pch.cpp"> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> </ClCompile> + <ClCompile Include="..\wx+\image_tools.cpp" /> <ClCompile Include="..\wx+\mouse_move_dlg.cpp" /> <ClCompile Include="..\zen\debug_memory_leaks.cpp" /> <ClCompile Include="..\zen\dir_watcher.cpp" /> @@ -240,10 +240,7 @@ <ClCompile Include="..\zen\privilege.cpp" /> <ClCompile Include="..\zen\scroll_window_under_cursor.cpp" /> <ClCompile Include="..\zen\zstring.cpp" /> - <ClCompile Include="application.cpp"> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Use</PrecompiledHeader> - </ClCompile> + <ClCompile Include="application.cpp" /> <ClCompile Include="gui_generated.cpp" /> <ClCompile Include="main_dlg.cpp" /> <ClCompile Include="monitor.cpp" /> diff --git a/RealtimeSync/application.cpp b/RealtimeSync/application.cpp index af8a40a9..c2ed4078 100644 --- a/RealtimeSync/application.cpp +++ b/RealtimeSync/application.cpp @@ -24,9 +24,6 @@ #elif defined ZEN_LINUX #include <gtk/gtk.h> - -#elif defined ZEN_MAC -#include <ApplicationServices/ApplicationServices.h> #endif using namespace zen; @@ -72,10 +69,6 @@ bool Application::OnInit() #elif defined ZEN_LINUX ::gtk_rc_parse((zen::getResourceDir() + "styles.gtk_rc").c_str()); //remove inner border from bitmap buttons - -#elif defined ZEN_MAC - ProcessSerialNumber psn = { 0, kCurrentProcess }; - ::TransformProcessType(&psn, kProcessTransformToForegroundApplication); //behave like an application bundle, even when the app is not packaged (yet) #endif SetAppName(L"FreeFileSync"); //reuse FFS's name, to have "GetUserDataDir()/GetResourcesDir()" return the same directory in ffs_paths.cpp @@ -137,8 +130,7 @@ void Application::onEnterEventLoop(wxEvent& event) if (!commandArgs.empty()) cfgFilename = commandArgs[0]; - MainDialog* frame = new MainDialog(nullptr, cfgFilename); - frame->Show(); + MainDialog::create(cfgFilename); } diff --git a/RealtimeSync/gui_generated.cpp b/RealtimeSync/gui_generated.cpp index 659f7ea4..16b52345 100644 --- a/RealtimeSync/gui_generated.cpp +++ b/RealtimeSync/gui_generated.cpp @@ -5,7 +5,7 @@ // PLEASE DO "NOT" EDIT THIS FILE! /////////////////////////////////////////////////////////////////////////// -#include "../wx+/button.h" +#include "../wx+/bitmap_button.h" #include "gui_generated.h" @@ -207,7 +207,7 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr m_staticline5 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); bSizerMain->Add( m_staticline5, 0, wxEXPAND, 5 ); - m_buttonStart = new zen::BitmapButton( this, wxID_OK, _("Start"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonStart = new zen::BitmapTextButton( this, wxID_OK, _("Start"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); m_buttonStart->SetDefault(); m_buttonStart->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) ); @@ -300,7 +300,6 @@ ErrorDlgGenerated::ErrorDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer26->Add( m_bitmap10, 0, wxRIGHT|wxLEFT, 10 ); m_textCtrl8 = new wxTextCtrl( m_panel3, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 400,150 ), wxTE_MULTILINE|wxTE_READONLY|wxNO_BORDER ); - m_textCtrl8->SetMaxLength( 0 ); bSizer26->Add( m_textCtrl8, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP, 5 ); diff --git a/RealtimeSync/gui_generated.h b/RealtimeSync/gui_generated.h index aabb23fc..182f75ca 100644 --- a/RealtimeSync/gui_generated.h +++ b/RealtimeSync/gui_generated.h @@ -11,7 +11,7 @@ #include <wx/artprov.h> #include <wx/xrc/xmlres.h> #include <wx/intl.h> -namespace zen { class BitmapButton; } +namespace zen { class BitmapTextButton; } #include <wx/string.h> #include <wx/bitmap.h> @@ -75,7 +75,7 @@ protected: wxStaticText* m_staticText6; wxTextCtrl* m_textCtrlCommand; wxStaticLine* m_staticline5; - zen::BitmapButton* m_buttonStart; + zen::BitmapTextButton* m_buttonStart; // Virtual event handlers, overide them in your derived class virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } diff --git a/RealtimeSync/main_dlg.cpp b/RealtimeSync/main_dlg.cpp index b7a0aee1..7b3e0f92 100644 --- a/RealtimeSync/main_dlg.cpp +++ b/RealtimeSync/main_dlg.cpp @@ -9,8 +9,7 @@ #include <wx/msgdlg.h> #include <wx/wupdlock.h> #include <wx/filedlg.h> -//#include <wx/utils.h> -#include <wx+/button.h> +#include <wx+/bitmap_button.h> #include <wx+/string_conv.h> #include <wx+/mouse_move_dlg.h> #include <wx+/font_size.h> @@ -23,6 +22,9 @@ #include "../lib/help_provider.h" #include "../lib/process_xml.h" #include "../lib/ffs_paths.h" +#ifdef ZEN_MAC +#include <ApplicationServices/ApplicationServices.h> +#endif using namespace zen; @@ -42,6 +44,12 @@ private: }; +void MainDialog::create(const Zstring& cfgFile) +{ + /*MainDialog* frame = */ new MainDialog(nullptr, cfgFile); +} + + MainDialog::MainDialog(wxDialog* dlg, const Zstring& cfgFileName) : MainDlgGenerated(dlg) { @@ -53,14 +61,16 @@ MainDialog::MainDialog(wxDialog* dlg, const Zstring& cfgFileName) SetIcon(GlobalResources::instance().programIconRTS); //set application icon setRelativeFontSize(*m_buttonStart, 1.5); - m_buttonStart->setInnerBorderSize(8); m_bpButtonRemoveTopFolder->Hide(); m_panelMainFolder->Layout(); m_bpButtonAddFolder ->SetBitmapLabel(getResourceImage(L"item_add")); m_bpButtonRemoveTopFolder->SetBitmapLabel(getResourceImage(L"item_remove")); - m_buttonStart ->setBitmapFront(getResourceImage(L"startRts"), 5); + ///m_buttonStart ->setBitmapFront(getResourceImage(L"startRts"), 5); + + setBitmapTextLabel(*m_buttonStart, getResourceImage(L"startRts").ConvertToImage(), m_buttonStart->GetLabel(), 5, 8); + //register key event Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(MainDialog::OnKeyPressed), nullptr, this); @@ -106,9 +116,19 @@ MainDialog::MainDialog(wxDialog* dlg, const Zstring& cfgFileName) { wxCommandEvent dummy2(wxEVT_COMMAND_BUTTON_CLICKED); this->OnStart(dummy2); + //don't Show()! } else + { m_buttonStart->SetFocus(); //don't "steal" focus if program is running from sys-tray" + Show(); +#ifdef ZEN_MAC + ProcessSerialNumber psn = { 0, kCurrentProcess }; + ::TransformProcessType(&psn, kProcessTransformToForegroundApplication); //show dock icon, even if we're not an application bundle + //if the executable is not yet in a bundle or if it is called through a launcher, we need to set focus manually: + ::SetFrontProcess(&psn); +#endif + } //drag and drop .ffs_real and .ffs_batch on main dialog setupFileDrop(*m_panelMain); @@ -193,6 +213,11 @@ void MainDialog::OnStart(wxCommandEvent& event) xmlAccess::XmlRealConfig currentCfg = getConfiguration(); Hide(); +#ifdef ZEN_MAC + //hide dock icon: else user is able to forcefully show the hidden main dialog by clicking on the icon!! + ProcessSerialNumber psn = { 0, kCurrentProcess }; + ::TransformProcessType(&psn, kProcessTransformToUIElementApplication); +#endif switch (rts::startDirectoryMonitor(currentCfg, xmlAccess::extractJobName(utfCvrtTo<Zstring>(currentConfigFileName)))) { @@ -204,6 +229,10 @@ void MainDialog::OnStart(wxCommandEvent& event) break; } Show(); //don't show for EXIT_APP +#ifdef ZEN_MAC + ::TransformProcessType(&psn, kProcessTransformToForegroundApplication); //show dock icon again + ::SetFrontProcess(&psn); //why isn't this covered by wxWindows::Raise()?? +#endif Raise(); } diff --git a/RealtimeSync/main_dlg.h b/RealtimeSync/main_dlg.h index 2a1fb03e..9e5537f0 100644 --- a/RealtimeSync/main_dlg.h +++ b/RealtimeSync/main_dlg.h @@ -13,6 +13,7 @@ #include <zen/zstring.h> #include <zen/async_task.h> #include <wx+/file_drop.h> +#include <wx/timer.h> #include "../ui/dir_name.h" namespace xmlAccess @@ -25,10 +26,12 @@ class DirectoryPanel; class MainDialog: public MainDlgGenerated { public: + static void create(const Zstring& cfgFile); + +private: MainDialog(wxDialog* dlg, const Zstring& cfgFileName); ~MainDialog(); -private: void loadConfig(const Zstring& filename); virtual void OnClose (wxCloseEvent& event) { Destroy(); } diff --git a/RealtimeSync/makefile b/RealtimeSync/makefile index d84c425f..50a08049 100644 --- a/RealtimeSync/makefile +++ b/RealtimeSync/makefile @@ -25,7 +25,7 @@ CXXFLAGS += `wx-config --cxxflags --debug=no` LINKFLAGS += `wx-config --libs --debug=no` -lboost_thread -lboost_system -lz else #static wxWidgets and boost library linkage for precompiled release -WX_CONFIG_BIN =$(HOME)/Desktop/wxGTK-2.8.12/lib/release/bin/wx-config +WX_CONFIG_BIN =$(HOME)/Desktop/wxWidgets-2.9.5/lib/release/bin/wx-config CXXFLAGS += -I$(HOME)/Desktop/boost_1_54_0 BOOST_LIB_DIR =$(HOME)/Desktop/boost_1_54_0/stage/lib @@ -39,7 +39,7 @@ ifeq ($(OPERATING_SYSTEM_NAME), Darwin) COMPILER_BIN=clang++ -stdlib=libc++ CXXFLAGS += -DZEN_MAC -WX_CONFIG_BIN =$(HOME)/Desktop/wxWidgets-2.9.4/lib/release/bin/wx-config +WX_CONFIG_BIN =$(HOME)/Desktop/wxWidgets-2.9.5/lib/release/bin/wx-config CXXFLAGS += -I$(HOME)/Desktop/boost_1_54_0 BOOST_LIB_DIR =$(HOME)/Desktop/boost_1_54_0/stage/lib MACOS_SDK =-mmacosx-version-min=10.7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk @@ -50,7 +50,7 @@ CXXFLAGS += $(MACOS_SDK) `$(WX_CONFIG_BIN) --cxxflags --debug=no --static=yes` LINKFLAGS += $(MACOS_SDK) `$(WX_CONFIG_BIN) --libs --debug=no --static=yes` $(BOOST_LIB_DIR)/libboost_thread.a $(BOOST_LIB_DIR)/libboost_system.a endif -##################################################################################################### +###################################################### CPP_LIST= #internal list of all *.cpp files needed for compilation CPP_LIST+=application.cpp @@ -74,7 +74,7 @@ CPP_LIST+=../zen/file_handling.cpp CPP_LIST+=../zen/file_io.cpp CPP_LIST+=../zen/file_traverser.cpp CPP_LIST+=../zen/zstring.cpp -CPP_LIST+=../wx+/button.cpp +CPP_LIST+=../wx+/image_tools.cpp #list of all *.o files (we need the "RTS" subdirectory to handle "../*.cpp" files OBJECT_LIST=$(CPP_LIST:%.cpp=../OBJ/RTS_GCC_Make_Release/RTS/%.o) diff --git a/RealtimeSync/tray_menu.cpp b/RealtimeSync/tray_menu.cpp index 33758ad2..e1cf8cad 100644 --- a/RealtimeSync/tray_menu.cpp +++ b/RealtimeSync/tray_menu.cpp @@ -16,6 +16,7 @@ #include <wx/taskbar.h> #include <wx/icon.h> //Linux needs this #include <wx/app.h> +#include <wx/timer.h> #include "resources.h" #include "gui_generated.h" #include "monitor.h" diff --git a/algorithm.cpp b/algorithm.cpp index 2415cd18..dd068e0d 100644 --- a/algorithm.cpp +++ b/algorithm.cpp @@ -25,7 +25,7 @@ using namespace std::rel_ops; void zen::swapGrids(const MainConfiguration& config, FolderComparison& folderCmp) { - std::for_each(begin(folderCmp), end(folderCmp), std::mem_fun_ref(&BaseDirPair::flip)); + std::for_each(begin(folderCmp), end(folderCmp), [](BaseDirPair& baseObj) { baseObj.flip(); }); redetermineSyncDirection(config, folderCmp, [](const std::wstring&) {}); } @@ -36,22 +36,22 @@ namespace class Redetermine { public: - static void execute(const DirectionSet& dirCfgIn, HierarchyObject& hierObj) - { - Redetermine(dirCfgIn).recurse(hierObj); - } + static void execute(const DirectionSet& dirCfgIn, HierarchyObject& hierObj) { Redetermine(dirCfgIn).recurse(hierObj); } private: Redetermine(const DirectionSet& dirCfgIn) : dirCfg(dirCfgIn) {} void recurse(HierarchyObject& hierObj) const { - std::for_each(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), [&](FilePair& fileObj) { (*this)(fileObj); }); - std::for_each(hierObj.refSubLinks().begin(), hierObj.refSubLinks().end(), [&](SymlinkPair& linkObj) { (*this)(linkObj); }); - std::for_each(hierObj.refSubDirs ().begin(), hierObj.refSubDirs ().end(), [&](DirPair& dirObj) { (*this)(dirObj); }); + for (FilePair& fileObj : hierObj.refSubFiles()) + processFile(fileObj); + for (SymlinkPair& linkObj : hierObj.refSubLinks()) + processLink(linkObj); + for (DirPair& dirObj : hierObj.refSubDirs()) + processDir(dirObj); } - void operator()(FilePair& fileObj) const + void processFile(FilePair& fileObj) const { const CompareFilesResult cat = fileObj.getCategory(); @@ -92,7 +92,7 @@ private: } } - void operator()(SymlinkPair& linkObj) const + void processLink(SymlinkPair& linkObj) const { switch (linkObj.getLinkCategory()) { @@ -124,7 +124,7 @@ private: } } - void operator()(DirPair& dirObj) const + void processDir(DirPair& dirObj) const { const CompareDirResult cat = dirObj.getDirCategory(); @@ -162,28 +162,26 @@ private: //--------------------------------------------------------------------------------------------------------------- -struct AllEqual //test if non-equal items exist in scanned data +//test if non-equal items exist in scanned data +bool allItemsCategoryEqual(const HierarchyObject& hierObj) { - bool operator()(const HierarchyObject& hierObj) const - { - return std::all_of(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), - [](const FilePair& fileObj) { return fileObj.getCategory() == FILE_EQUAL; })&& //files + return std::all_of(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), + [](const FilePair& fileObj) { return fileObj.getCategory() == FILE_EQUAL; })&& //files - std::all_of(hierObj.refSubLinks().begin(), hierObj.refSubLinks().end(), - [](const SymlinkPair& linkObj) { return linkObj.getLinkCategory() == SYMLINK_EQUAL; })&& //symlinks + std::all_of(hierObj.refSubLinks().begin(), hierObj.refSubLinks().end(), + [](const SymlinkPair& linkObj) { return linkObj.getLinkCategory() == SYMLINK_EQUAL; })&& //symlinks - std::all_of(hierObj.refSubDirs(). begin(), hierObj.refSubDirs(). end(), - [](const DirPair& dirObj) - { - return dirObj.getDirCategory() == DIR_EQUAL && AllEqual()(dirObj); //short circuit-behavior! - }); //directories - } -}; + std::all_of(hierObj.refSubDirs(). begin(), hierObj.refSubDirs().end(), + [](const DirPair& dirObj) + { + return dirObj.getDirCategory() == DIR_EQUAL && allItemsCategoryEqual(dirObj); //short circuit-behavior! + }); //directories +} } bool zen::allElementsEqual(const FolderComparison& folderCmp) { - return std::all_of(begin(folderCmp), end(folderCmp), AllEqual()); + return std::all_of(begin(folderCmp), end(folderCmp), [](const BaseDirPair& baseObj) { return allItemsCategoryEqual(baseObj); }); } //--------------------------------------------------------------------------------------------------------------- @@ -224,7 +222,7 @@ bool stillInSync(const InSyncFile& dbFile, CompareVariant compareVar, size_t fil switch (compareVar) { case CMP_BY_TIME_SIZE: - if (dbFile.inSyncType == IN_SYNC_BINARY_EQUAL) return true; //special rule: this is already "good enough" for CMP_BY_TIME_SIZE! + if (dbFile.cmpVar == CMP_BY_CONTENT) return true; //special rule: this is already "good enough" for CMP_BY_TIME_SIZE! return //case-sensitive short name match is a database invariant! CmpFileTime::getResult(dbFile.left.lastWriteTimeRaw, dbFile.right.lastWriteTimeRaw, fileTimeTolerance) == CmpFileTime::TIME_EQUAL; @@ -232,7 +230,7 @@ bool stillInSync(const InSyncFile& dbFile, CompareVariant compareVar, size_t fil case CMP_BY_CONTENT: //case-sensitive short name match is a database invariant! - return dbFile.inSyncType == IN_SYNC_BINARY_EQUAL; + return dbFile.cmpVar == CMP_BY_CONTENT; //in contrast to comparison, we don't care about modification time here! } assert(false); @@ -273,14 +271,14 @@ bool stillInSync(const InSyncSymlink& dbLink, CompareVariant compareVar, size_t switch (compareVar) { case CMP_BY_TIME_SIZE: - if (dbLink.inSyncType == IN_SYNC_BINARY_EQUAL) return true; //special rule: this is already "good enough" for CMP_BY_TIME_SIZE! + if (dbLink.cmpVar == CMP_BY_CONTENT) return true; //special rule: this is already "good enough" for CMP_BY_TIME_SIZE! return //case-sensitive short name match is a database invariant! CmpFileTime::getResult(dbLink.left.lastWriteTimeRaw, dbLink.right.lastWriteTimeRaw, fileTimeTolerance) == CmpFileTime::TIME_EQUAL; case CMP_BY_CONTENT: //case-sensitive short name match is a database invariant! - return dbLink.inSyncType == IN_SYNC_BINARY_EQUAL; + return dbLink.cmpVar == CMP_BY_CONTENT; //in contrast to comparison, we don't care about modification time here! } assert(false); @@ -314,98 +312,175 @@ bool stillInSync(const InSyncDir& dbDir) //---------------------------------------------------------------------------------------------- -class RedetermineAuto +class DetectMovedFiles { public: - static void execute(BaseDirPair& baseDirectory, std::function<void(const std::wstring&)> reportWarning) - { - RedetermineAuto(baseDirectory, reportWarning); - } + static void execute(BaseDirPair& baseDirectory, const InSyncDir& dbContainer) { DetectMovedFiles(baseDirectory, dbContainer); } private: - RedetermineAuto(BaseDirPair& baseDirectory, std::function<void(const std::wstring&)> reportWarning) : - txtBothSidesChanged(_("Both sides have changed since last synchronization.")), - txtNoSideChanged(_("Cannot determine sync-direction:") + L" \n" + _("No change since last synchronization.")), - txtDbNotInSync(_("Cannot determine sync-direction:") + L" \n" + _("The database entry is not in sync considering current settings.")), + DetectMovedFiles(BaseDirPair& baseDirectory, const InSyncDir& dbContainer) : cmpVar(baseDirectory.getCompVariant()), - fileTimeTolerance(baseDirectory.getFileTimeTolerance()), - reportWarning_(reportWarning) + fileTimeTolerance(baseDirectory.getFileTimeTolerance()) { - if (AllEqual()(baseDirectory)) //nothing to do: abort and don't show any nag-screens - return; + recurse(baseDirectory); + + if (!exLeftOnly.empty() && !exRightOnly.empty()) + detectFilePairs(dbContainer); + } - //try to load sync-database files - std::shared_ptr<InSyncDir> lastSyncState = loadDBFile(baseDirectory); - if (!lastSyncState) + void recurse(HierarchyObject& hierObj) + { + for (FilePair& fileObj : hierObj.refSubFiles()) { - //set conservative "two-way" directions - DirectionSet twoWayCfg = getTwoWaySet(); + const CompareFilesResult cat = fileObj.getCategory(); - Redetermine::execute(twoWayCfg, baseDirectory); - return; + if (cat == FILE_LEFT_SIDE_ONLY) + { + if (fileObj.getFileId<LEFT_SIDE>() != FileId()) + { + auto rv = exLeftOnly.insert(std::make_pair(fileObj.getFileId<LEFT_SIDE>(), &fileObj)); + assert(rv.second); + if (!rv.second) //duplicate file ID! + rv.first->second = nullptr; + } + } + else if (cat == FILE_RIGHT_SIDE_ONLY) + { + if (fileObj.getFileId<RIGHT_SIDE>() != FileId()) + { + auto rv = exRightOnly.insert(std::make_pair(fileObj.getFileId<RIGHT_SIDE>(), &fileObj)); + assert(rv.second); + if (!rv.second) //duplicate file ID! + rv.first->second = nullptr; + } + } } + for (DirPair& dirObj : hierObj.refSubDirs()) + recurse(dirObj); + } - //-> considering filter not relevant: - //if narrowing filter: all ok; if widening filter (if file ex on both sides -> conflict, fine; if file ex. on one side: copy to other side: fine) + void detectFilePairs(const InSyncDir& container) const + { + for (auto& dbFile : container.files) + findAndSetMovePair(dbFile.second); - recurse(baseDirectory, &*lastSyncState); + for (auto& dbDir : container.dirs) + detectFilePairs(dbDir.second); + } - //----------- detect renamed files ----------------- - if (!exLeftOnly.empty() && !exRightOnly.empty()) - detectRenamedFiles(*lastSyncState); + static bool sameSizeAndDateLeft(const FilePair& fsObj, const InSyncFile& dbEntry) + { + return fsObj.getFileSize<LEFT_SIDE>() == dbEntry.fileSize && + sameFileTime(fsObj.getLastWriteTime<LEFT_SIDE>(), dbEntry.left.lastWriteTimeRaw, 2); //respect 2 second FAT/FAT32 precision! + //PS: *never* allow 2 sec tolerance as container predicate!! + // => no strict weak ordering relation! reason: no transitivity of equivalence! + } + static bool sameSizeAndDateRight(const FilePair& fsObj, const InSyncFile& dbEntry) + { + return fsObj.getFileSize<RIGHT_SIDE>() == dbEntry.fileSize && + sameFileTime(fsObj.getLastWriteTime<RIGHT_SIDE>(), dbEntry.right.lastWriteTimeRaw, 2); } - std::shared_ptr<InSyncDir> loadDBFile(const BaseDirPair& baseDirObj) //return nullptr on failure + void findAndSetMovePair(const InSyncFile& dbEntry) const { - try - { - return loadLastSynchronousState(baseDirObj); //throw FileError, FileErrorDatabaseNotExisting - } - catch (FileErrorDatabaseNotExisting&) {} //let's ignore this error, it seems there's no value in reporting it other than confuse users - catch (FileError& error) //e.g. incompatible database version + const FileId idLeft = dbEntry.left .fileId; + const FileId idRight = dbEntry.right.fileId; + + if (idLeft != FileId() && + idRight != FileId() && + stillInSync(dbEntry, cmpVar, fileTimeTolerance)) { - reportWarning_(error.toString() + L" \n\n" + - _("Setting default synchronization directions: Old files will be overwritten with newer files.")); + auto itL = exLeftOnly.find(idLeft); + if (itL != exLeftOnly.end()) + if (FilePair* fileLeftOnly = itL->second) //= nullptr, if duplicate ID! + if (sameSizeAndDateLeft(*fileLeftOnly, dbEntry)) + { + auto itR = exRightOnly.find(idRight); + if (itR != exRightOnly.end()) + if (FilePair* fileRightOnly = itR->second) //= nullptr, if duplicate ID! + if (sameSizeAndDateRight(*fileRightOnly, dbEntry)) + if (fileLeftOnly ->getMoveRef() == nullptr && //the db may contain duplicate file ids on left or right side: e.g. consider aliasing through symlinks + fileRightOnly->getMoveRef() == nullptr) //=> should not be a problem (same id, size, date => alias!) but don't let a row participate in two move pairs! + { + fileLeftOnly ->setMoveRef(fileRightOnly->getId()); //found a pair, mark it! + fileRightOnly->setMoveRef(fileLeftOnly ->getId()); // + } + } } - return nullptr; } - void recurse(HierarchyObject& hierObj, const InSyncDir* dbContainer) + const CompareVariant cmpVar; + const size_t fileTimeTolerance; + + std::map<FileId, FilePair*> exLeftOnly; //FilePair* == nullptr for duplicate ids! => consider aliasing through symlinks! + std::map<FileId, FilePair*> exRightOnly; //=> avoid ambiguity for mixtures of files/symlinks on one side and allow 1-1 mapping only! + + /* + detect renamed files: + + X -> |_| Create right + |_| -> Y Delete right + + is detected as: + + Rename Y to X on right + + Algorithm: + ---------- + DB-file left <--- (name, size, date) ---> DB-file right + | | + | (file ID, size, date) | (file ID, size, date) + \|/ \|/ + file left only file right only + + FAT caveat: File Ids are generally not stable when file is either moved or renamed! + => 1. Move/rename operations on FAT cannot be detected reliably. + => 2. database generally contains wrong file ID on FAT after renaming from .ffs_tmp files => correct file Ids in database only after next sync + => 3. even exFAT screws up (but less than FAT) and changes IDs after file move. Did they learn nothing from the past? + + Possible refinement + ------------------- + If the file ID is wrong (FAT) or not available, we could at least allow direct association by name, instead of breaking the chain completely: support NTFS -> FAT + */ +}; + +//---------------------------------------------------------------------------------------------- + +class RedetermineTwoWay +{ +public: + static void execute(BaseDirPair& baseDirectory, const InSyncDir& dbContainer) { RedetermineTwoWay(baseDirectory, dbContainer); } + +private: + RedetermineTwoWay(BaseDirPair& baseDirectory, const InSyncDir& dbContainer) : + txtBothSidesChanged(_("Both sides have changed since last synchronization.")), + txtNoSideChanged(_("Cannot determine sync-direction:") + L" \n" + _("No change since last synchronization.")), + txtDbNotInSync(_("Cannot determine sync-direction:") + L" \n" + _("The database entry is not in sync considering current settings.")), + cmpVar(baseDirectory.getCompVariant()), + fileTimeTolerance(baseDirectory.getFileTimeTolerance()) + { + //-> considering filter not relevant: + //if narrowing filter: all ok; if widening filter (if file ex on both sides -> conflict, fine; if file ex. on one side: copy to other side: fine) + + recurse(baseDirectory, &dbContainer); + } + + void recurse(HierarchyObject& hierObj, const InSyncDir* dbContainer) const { - std::for_each(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), [&](FilePair& fileObj) { processFile (fileObj, dbContainer); }); - std::for_each(hierObj.refSubLinks().begin(), hierObj.refSubLinks().end(), [&](SymlinkPair& linkObj) { processSymlink(linkObj, dbContainer); }); - std::for_each(hierObj.refSubDirs ().begin(), hierObj.refSubDirs ().end(), [&](DirPair& dirObj) { processDir (dirObj, dbContainer); }); + for (FilePair& fileObj : hierObj.refSubFiles()) + processFile(fileObj, dbContainer); + for (SymlinkPair& linkObj : hierObj.refSubLinks()) + processSymlink(linkObj, dbContainer); + for (DirPair& dirObj : hierObj.refSubDirs()) + processDir(dirObj, dbContainer); } - void processFile(FilePair& fileObj, const InSyncDir* dbContainer) + void processFile(FilePair& fileObj, const InSyncDir* dbContainer) const { const CompareFilesResult cat = fileObj.getCategory(); if (cat == FILE_EQUAL) return; - //----------------- prepare detection of renamed files ----------------- - if (cat == FILE_LEFT_SIDE_ONLY) - { - if (fileObj.getFileId<LEFT_SIDE>() != FileId()) - { - auto rv = exLeftOnly.insert(std::make_pair(fileObj.getFileId<LEFT_SIDE>(), &fileObj)); - assert(rv.second); - if (!rv.second) //duplicate file ID! - rv.first->second = nullptr; - } - } - else if (cat == FILE_RIGHT_SIDE_ONLY) - { - if (fileObj.getFileId<RIGHT_SIDE>() != FileId()) - { - auto rv = exRightOnly.insert(std::make_pair(fileObj.getFileId<RIGHT_SIDE>(), &fileObj)); - assert(rv.second); - if (!rv.second) //duplicate file ID! - rv.first->second = nullptr; - } - } - //---------------------------------------------------------------------- - //##################### schedule old temporary files for deletion #################### if (cat == FILE_LEFT_SIDE_ONLY && endsWith(fileObj.getShortName<LEFT_SIDE>(), TEMP_FILE_ENDING)) return fileObj.setSyncDir(SyncDirection::LEFT); @@ -443,7 +518,7 @@ private: } } - void processSymlink(SymlinkPair& linkObj, const InSyncDir* dbContainer) + void processSymlink(SymlinkPair& linkObj, const InSyncDir* dbContainer) const { const CompareSymlinkResult cat = linkObj.getLinkCategory(); if (cat == SYMLINK_EQUAL) @@ -479,7 +554,7 @@ private: } } - void processDir(DirPair& dirObj, const InSyncDir* dbContainer) + void processDir(DirPair& dirObj, const InSyncDir* dbContainer) const { const CompareDirResult cat = dirObj.getDirCategory(); @@ -522,58 +597,7 @@ private: } } - recurse(dirObj, dbEntry ? &dbEntry->second : nullptr); //recursion - } - - //note: - we cannot integrate this traversal into "recurse()" since it may take a *slightly* different path: e.g. file renamed on both sides - void detectRenamedFiles(InSyncDir& container) - { - std::for_each(container.files.begin(), container.files.end(), - [&](std::pair<const Zstring, InSyncFile>& dbFile) { findAndSetMovePair(dbFile.second); }); - - std::for_each(container.dirs.begin(), container.dirs.end(), - [&](std::pair<const Zstring, InSyncDir>& dbDir) { detectRenamedFiles(dbDir.second); }); - } - - static bool sameSizeAndDateLeft(const FilePair& fsObj, const InSyncFile& dbEntry) - { - return fsObj.getFileSize<LEFT_SIDE>() == dbEntry.fileSize && - sameFileTime(fsObj.getLastWriteTime<LEFT_SIDE>(), dbEntry.left.lastWriteTimeRaw, 2); //respect 2 second FAT/FAT32 precision! - //PS: *never* allow 2 sec tolerance as container predicate!! - // => no strict weak ordering relation! reason: no transitivity of equivalence! - } - static bool sameSizeAndDateRight(const FilePair& fsObj, const InSyncFile& dbEntry) - { - return fsObj.getFileSize<RIGHT_SIDE>() == dbEntry.fileSize && - sameFileTime(fsObj.getLastWriteTime<RIGHT_SIDE>(), dbEntry.right.lastWriteTimeRaw, 2); - } - - void findAndSetMovePair(const InSyncFile& dbEntry) const - { - const FileId idLeft = dbEntry.left .fileId; - const FileId idRight = dbEntry.right.fileId; - - if (idLeft != FileId() && - idRight != FileId() && - stillInSync(dbEntry, cmpVar, fileTimeTolerance)) - { - auto itL = exLeftOnly.find(idLeft); - if (itL != exLeftOnly.end()) - if (FilePair* fileLeftOnly = itL->second) //= nullptr, if duplicate ID! - if (sameSizeAndDateLeft(*fileLeftOnly, dbEntry)) - { - auto itR = exRightOnly.find(idRight); - if (itR != exRightOnly.end()) - if (FilePair* fileRightOnly = itR->second) //= nullptr, if duplicate ID! - if (sameSizeAndDateRight(*fileRightOnly, dbEntry)) - if (fileLeftOnly ->getMoveRef() == nullptr && //the db may contain duplicate file ids on left or right side: e.g. consider aliasing through symlinks - fileRightOnly->getMoveRef() == nullptr) //=> should not be a problem (same id, size, date => alias!) but don't let a row participate in two move pairs! - { - fileLeftOnly ->setMoveRef(fileRightOnly->getId()); //found a pair, mark it! - fileRightOnly->setMoveRef(fileLeftOnly ->getId()); // - } - } - } + recurse(dirObj, dbEntry ? &dbEntry->second : nullptr); } const std::wstring txtBothSidesChanged; @@ -582,51 +606,6 @@ private: const CompareVariant cmpVar; const size_t fileTimeTolerance; - std::function<void(const std::wstring&)> reportWarning_; - - std::map<FileId, FilePair*> exLeftOnly; //FilePair* == nullptr for duplicate ids! => consider aliasing through symlinks! - std::map<FileId, FilePair*> exRightOnly; //=> avoid ambiguity for mixtures of files/symlinks on one side and allow 1-1 mapping only! - - /* - detect renamed files - - X -> |_| Create right - |_| -> Y Delete right - - is detected as: - - Rename Y to X on right - - Algorithm: - ---------- - DB-file left <--- (name, size, date) ---> DB-file right - | | - | (file ID, size, date) | (file ID, size, date) - \|/ \|/ - file left only file right only - - FAT caveat: File Ids are generally not stable when file is either moved or renamed! - => 1. Move/rename operations on FAT cannot be detected reliably. - => 2. database generally contains wrong file ID on FAT after renaming from .ffs_tmp files => correct file Ids in database only after next sync - => 3. even exFAT screws up (but less than FAT) and changes IDs after file move. Did they learn nothing from the past? - - Possible refinement - ------------------- - If the file ID is wrong (FAT) or not available, we could at least allow direct association by name, instead of breaking the chain completely: support NTFS -> FAT - - 1. find equal entries in database: - std::hash_map: DB* |-> DB* onceEqual - - 2. build alternative mappings if file Id is available for database entries: - std::map: FielId |-> DB* leftIdToDbRight - std::map: FielId |-> DB* rightIdToDbRight - - 3. collect files on one side during determination of sync directions: - std::vector<FilePair*, DB*> exLeftOnlyToDbRight -> first try to use file Id, if failed associate via file name instead - std::hash_map<DB*, FilePair*> dbRightToexRightOnly -> - - 4. find renamed pairs - */ }; } @@ -652,15 +631,40 @@ std::vector<DirectionConfig> zen::extractDirectionCfg(const MainConfiguration& m } -void zen::redetermineSyncDirection(const DirectionConfig& directConfig, BaseDirPair& baseDirectory, std::function<void(const std::wstring&)> reportWarning) +void zen::redetermineSyncDirection(const DirectionConfig& dirCfg, BaseDirPair& baseDirectory, std::function<void(const std::wstring&)> reportWarning) { - if (directConfig.var == DirectionConfig::AUTOMATIC) - RedetermineAuto::execute(baseDirectory, reportWarning); - else + //try to load sync-database files + std::shared_ptr<InSyncDir> lastSyncState; + if (dirCfg.var == DirectionConfig::TWOWAY || detectMovedFilesEnabled(dirCfg)) + try + { + if (allItemsCategoryEqual(baseDirectory)) + return; //nothing to do: abort and don't even try to open db files + + lastSyncState = loadLastSynchronousState(baseDirectory); //throw FileError, FileErrorDatabaseNotExisting + } + catch (FileErrorDatabaseNotExisting&) {} //let's ignore this error, there's no value in reporting it other than confuse users + catch (FileError& error) //e.g. incompatible database version + { + reportWarning(error.toString() + + (dirCfg.var == DirectionConfig::TWOWAY ? + L" \n\n" + _("Setting default synchronization directions: Old files will be overwritten with newer files.") : std::wstring())); + } + + //set sync directions + if (dirCfg.var == DirectionConfig::TWOWAY) { - DirectionSet dirCfg = extractDirections(directConfig); - Redetermine::execute(dirCfg, baseDirectory); + if (lastSyncState) + RedetermineTwoWay::execute(baseDirectory, *lastSyncState); + else //default fallback + Redetermine::execute(getTwoWayUpdateSet(), baseDirectory); } + else + Redetermine::execute(extractDirections(dirCfg), baseDirectory); + + //detect renamed files + if (lastSyncState) + DetectMovedFiles::execute(baseDirectory, *lastSyncState); } @@ -681,113 +685,88 @@ void zen::redetermineSyncDirection(const MainConfiguration& mainCfg, FolderCompa } } - //--------------------------------------------------------------------------------------------------------------- -class SetNewDirection -{ -public: - SetNewDirection(SyncDirection newDirection) : newDirection_(newDirection) {} - void operator()(FilePair& fileObj) const +struct SetNewDirection +{ + static void execute(FilePair& fileObj, SyncDirection newDirection) { if (fileObj.getCategory() != FILE_EQUAL) - fileObj.setSyncDir(newDirection_); + fileObj.setSyncDir(newDirection); } - void operator()(SymlinkPair& linkObj) const + static void execute(SymlinkPair& linkObj, SyncDirection newDirection) { if (linkObj.getLinkCategory() != SYMLINK_EQUAL) - linkObj.setSyncDir(newDirection_); + linkObj.setSyncDir(newDirection); } - void operator()(DirPair& dirObj) const + static void execute(DirPair& dirObj, SyncDirection newDirection) { if (dirObj.getDirCategory() != DIR_EQUAL) - dirObj.setSyncDir(newDirection_); - execute(dirObj); //recursion + dirObj.setSyncDir(newDirection); + + //recurse: + for (FilePair& fileObj : dirObj.refSubFiles()) + execute(fileObj, newDirection); + for (SymlinkPair& linkObj : dirObj.refSubLinks()) + execute(linkObj, newDirection); + for (DirPair& dirObj2 : dirObj.refSubDirs()) + execute(dirObj2, newDirection); } - -private: - void execute(HierarchyObject& hierObj) const - { - std::for_each(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), [&](FilePair& fileObj) { (*this)(fileObj); }); - std::for_each(hierObj.refSubLinks().begin(), hierObj.refSubLinks().end(), [&](SymlinkPair& linkObj) { (*this)(linkObj); }); - std::for_each(hierObj.refSubDirs ().begin(), hierObj.refSubDirs ().end(), [&](DirPair& dirObj) { (*this)(dirObj); }); - } - - const SyncDirection newDirection_; }; void zen::setSyncDirectionRec(SyncDirection newDirection, FileSystemObject& fsObj) { - SetNewDirection dirSetter(newDirection); - //process subdirectories also! struct Recurse: public FSObjectVisitor { - Recurse(const SetNewDirection& ds) : dirSetter_(ds) {} + Recurse(SyncDirection newDir) : newDir_(newDir) {} virtual void visit(const FilePair& fileObj) { - dirSetter_(const_cast<FilePair&>(fileObj)); //phyiscal object is not const in this method anyway + SetNewDirection::execute(const_cast<FilePair&>(fileObj), newDir_); //phyiscal object is not const in this method anyway } virtual void visit(const SymlinkPair& linkObj) { - dirSetter_(const_cast<SymlinkPair&>(linkObj)); // + SetNewDirection::execute(const_cast<SymlinkPair&>(linkObj), newDir_); // } virtual void visit(const DirPair& dirObj) { - dirSetter_(const_cast<DirPair&>(dirObj)); // + SetNewDirection::execute(const_cast<DirPair&>(dirObj), newDir_); // } private: - const SetNewDirection& dirSetter_; - } recurse(dirSetter); - fsObj.accept(recurse); + SyncDirection newDir_; + } setDirVisitor(newDirection); + fsObj.accept(setDirVisitor); } //--------------- functions related to filtering ------------------------------------------------------------------------------------ +namespace +{ template <bool include> -class InOrExcludeAllRows +void inOrExcludeAllRows(zen::HierarchyObject& hierObj) { -public: - void operator()(zen::BaseDirPair& baseDirectory) const //be careful with operator() to no get called by std::for_each! - { - execute(baseDirectory); - } - - void execute(zen::HierarchyObject& hierObj) const //don't create ambiguity by replacing with operator() - { - std::for_each(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), [&](FilePair& fileObj) { (*this)(fileObj); }); - std::for_each(hierObj.refSubLinks().begin(), hierObj.refSubLinks().end(), [&](SymlinkPair& linkObj) { (*this)(linkObj); }); - std::for_each(hierObj.refSubDirs ().begin(), hierObj.refSubDirs ().end(), [&](DirPair& dirObj) { (*this)(dirObj); }); - } - -private: - void operator()(zen::FilePair& fileObj) const - { + for (FilePair& fileObj : hierObj.refSubFiles()) fileObj.setActive(include); - } - - void operator()(zen::SymlinkPair& linkObj) const - { + for (SymlinkPair& linkObj : hierObj.refSubLinks()) linkObj.setActive(include); - } - - void operator()(zen::DirPair& dirObj) const + for (DirPair& dirObj : hierObj.refSubDirs()) { dirObj.setActive(include); - execute(dirObj); //recursion + inOrExcludeAllRows<include>(dirObj); //recurse } -}; +} +} void zen::setActiveStatus(bool newStatus, zen::FolderComparison& folderCmp) { if (newStatus) - std::for_each(begin(folderCmp), end(folderCmp), InOrExcludeAllRows<true>()); //include all rows + std::for_each(begin(folderCmp), end(folderCmp), [](BaseDirPair& baseDirObj) { inOrExcludeAllRows<true>(baseDirObj); }); //include all rows else - std::for_each(begin(folderCmp), end(folderCmp), InOrExcludeAllRows<false>()); //exclude all rows + std::for_each(begin(folderCmp), end(folderCmp), [](BaseDirPair& baseDirObj) { inOrExcludeAllRows<false>(baseDirObj); }); //exclude all rows } @@ -804,9 +783,9 @@ void zen::setActiveStatus(bool newStatus, zen::FileSystemObject& fsObj) virtual void visit(const DirPair& dirObj) { if (newStatus_) - InOrExcludeAllRows<true>().execute(const_cast<DirPair&>(dirObj)); //object is not physically const here anyway + inOrExcludeAllRows<true>(const_cast<DirPair&>(dirObj)); //object is not physically const here anyway else - InOrExcludeAllRows<false>().execute(const_cast<DirPair&>(dirObj)); // + inOrExcludeAllRows<false>(const_cast<DirPair&>(dirObj)); // } private: const bool newStatus_; @@ -851,29 +830,34 @@ template <FilterStrategy strategy> class ApplyHardFilter { public: - ApplyHardFilter(const HardFilter& filterProcIn) : filterProc(filterProcIn) {} + static void execute(HierarchyObject& hierObj, const HardFilter& filterProcIn) { ApplyHardFilter(hierObj, filterProcIn); } + +private: + ApplyHardFilter(HierarchyObject& hierObj, const HardFilter& filterProcIn) : filterProc(filterProcIn) { recurse(hierObj); } - void execute(zen::HierarchyObject& hierObj) const + void recurse(HierarchyObject& hierObj) const { - std::for_each(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), [&](FilePair& fileObj) { (*this)(fileObj); }); - std::for_each(hierObj.refSubLinks().begin(), hierObj.refSubLinks().end(), [&](SymlinkPair& linkObj) { (*this)(linkObj); }); - std::for_each(hierObj.refSubDirs ().begin(), hierObj.refSubDirs ().end(), [&](DirPair& dirObj) { (*this)(dirObj); }); + for (FilePair& fileObj : hierObj.refSubFiles()) + processFile(fileObj); + for (SymlinkPair& linkObj : hierObj.refSubLinks()) + processLink(linkObj); + for (DirPair& dirObj : hierObj.refSubDirs()) + processDir(dirObj); }; -private: - void operator()(zen::FilePair& fileObj) const + void processFile(FilePair& fileObj) const { if (Eval<strategy>().process(fileObj)) fileObj.setActive(filterProc.passFileFilter(fileObj.getObjRelativeName())); } - void operator()(zen::SymlinkPair& linkObj) const + void processLink(SymlinkPair& linkObj) const { if (Eval<strategy>().process(linkObj)) linkObj.setActive(filterProc.passFileFilter(linkObj.getObjRelativeName())); } - void operator()(zen::DirPair& dirObj) const + void processDir(DirPair& dirObj) const { bool subObjMightMatch = true; const bool filterPassed = filterProc.passDirFilter(dirObj.getObjRelativeName(), &subObjMightMatch); @@ -883,11 +867,11 @@ private: if (!subObjMightMatch) //use same logic like directory traversing here: evaluate filter in subdirs only if objects could match { - InOrExcludeAllRows<false>().execute(dirObj); //exclude all files dirs in subfolders + inOrExcludeAllRows<false>(dirObj); //exclude all files dirs in subfolders return; } - execute(dirObj); //recursion + recurse(dirObj); } const HardFilter& filterProc; @@ -901,17 +885,22 @@ template <FilterStrategy strategy> class ApplySoftFilter //falsify only! -> can run directly after "hard/base filter" { public: - ApplySoftFilter(const SoftFilter& timeSizeFilter) : timeSizeFilter_(timeSizeFilter) {} + static void execute(HierarchyObject& hierObj, const SoftFilter& timeSizeFilter) { ApplySoftFilter(hierObj, timeSizeFilter); } - void execute(zen::HierarchyObject& hierObj) const +private: + ApplySoftFilter(HierarchyObject& hierObj, const SoftFilter& timeSizeFilter) : timeSizeFilter_(timeSizeFilter) { recurse(hierObj); } + + void recurse(zen::HierarchyObject& hierObj) const { - std::for_each(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), [&](FilePair& fileObj) { (*this)(fileObj); }); - std::for_each(hierObj.refSubLinks().begin(), hierObj.refSubLinks().end(), [&](SymlinkPair& linkObj) { (*this)(linkObj); }); - std::for_each(hierObj.refSubDirs ().begin(), hierObj.refSubDirs ().end(), [&](DirPair& dirObj) { (*this)(dirObj); }); + for (FilePair& fileObj : hierObj.refSubFiles()) + processFile(fileObj); + for (SymlinkPair& linkObj : hierObj.refSubLinks()) + processLink(linkObj); + for (DirPair& dirObj : hierObj.refSubDirs()) + processDir(dirObj); }; -private: - void operator()(zen::FilePair& fileObj) const + void processFile(FilePair& fileObj) const { if (Eval<strategy>().process(fileObj)) { @@ -926,14 +915,14 @@ private: //the only case with partially unclear semantics: //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 - ST |X|X|X|X| T := match time only - ------------ - := no match + ST S T - ST := match size and time + --------- S := match size only + ST |X|X|X|X| T := match time only + ------------ - := no match S |X|O|?|O| - ------------ X := include row - T |X|?|O|O| O := exclude row - ------------ ? := unclear + ------------ X := include row + T |X|?|O|O| O := exclude row + ------------ ? := unclear - |X|O|O|O| ------------ */ @@ -946,7 +935,7 @@ private: } } - void operator()(zen::SymlinkPair& linkObj) const + void processLink(SymlinkPair& linkObj) const { if (Eval<strategy>().process(linkObj)) { @@ -960,12 +949,12 @@ private: } } - void operator()(zen::DirPair& dirObj) const + void processDir(DirPair& dirObj) const { if (Eval<strategy>().process(dirObj)) dirObj.setActive(timeSizeFilter_.matchFolder()); //if date filter is active we deactivate all folders: effectively gets rid of empty folders! - execute(dirObj); //recursion + recurse(dirObj); } template <SelectedSide side, class T> @@ -987,14 +976,14 @@ private: void zen::addHardFiltering(BaseDirPair& baseDirObj, const Zstring& excludeFilter) { - ApplyHardFilter<STRATEGY_AND>(NameFilter(FilterConfig().includeFilter, excludeFilter)).execute(baseDirObj); + ApplyHardFilter<STRATEGY_AND>::execute(baseDirObj, NameFilter(FilterConfig().includeFilter, excludeFilter)); } void zen::addSoftFiltering(BaseDirPair& baseDirObj, const SoftFilter& timeSizeFilter) { if (!timeSizeFilter.isNull()) //since we use STRATEGY_AND, we may skip a "null" filter - ApplySoftFilter<STRATEGY_AND>(timeSizeFilter).execute(baseDirObj); + ApplySoftFilter<STRATEGY_AND>::execute(baseDirObj, timeSizeFilter); } @@ -1019,7 +1008,7 @@ void zen::applyFiltering(FolderComparison& folderCmp, const MainConfiguration& m const NormalizedFilter normFilter = normalizeFilters(mainCfg.globalFilter, it->localFilter); //"set" hard filter - ApplyHardFilter<STRATEGY_SET>(*normFilter.nameFilter).execute(baseDirectory); + ApplyHardFilter<STRATEGY_SET>::execute(baseDirectory, *normFilter.nameFilter); //"and" soft filter addSoftFiltering(baseDirectory, normFilter.timeSizeFilter); @@ -1030,20 +1019,26 @@ void zen::applyFiltering(FolderComparison& folderCmp, const MainConfiguration& m class FilterByTimeSpan { public: - FilterByTimeSpan(const Int64& timeFrom, + static void execute(HierarchyObject& hierObj, const Int64& timeFrom, const Int64& timeTo) { FilterByTimeSpan(hierObj, timeFrom, timeTo); } + +private: + FilterByTimeSpan(HierarchyObject& hierObj, + const Int64& timeFrom, const Int64& timeTo) : timeFrom_(timeFrom), - timeTo_(timeTo) {} + timeTo_(timeTo) { recurse(hierObj); } - void execute(zen::HierarchyObject& hierObj) const + void recurse(HierarchyObject& hierObj) const { - std::for_each(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), [&](FilePair& fileObj) { (*this)(fileObj); }); - std::for_each(hierObj.refSubLinks().begin(), hierObj.refSubLinks().end(), [&](SymlinkPair& linkObj) { (*this)(linkObj); }); - std::for_each(hierObj.refSubDirs ().begin(), hierObj.refSubDirs ().end(), [&](DirPair& dirObj) { (*this)(dirObj); }); + for (FilePair& fileObj : hierObj.refSubFiles()) + processFile(fileObj); + for (SymlinkPair& linkObj : hierObj.refSubLinks()) + processLink(linkObj); + for (DirPair& dirObj : hierObj.refSubDirs()) + processDir(dirObj); }; -private: - void operator()(zen::FilePair& fileObj) const + void processFile(FilePair& fileObj) const { if (fileObj.isEmpty<LEFT_SIDE>()) fileObj.setActive(matchTime<RIGHT_SIDE>(fileObj)); @@ -1054,7 +1049,7 @@ private: matchTime<LEFT_SIDE>(fileObj)); } - void operator()(zen::SymlinkPair& linkObj) const + void processLink(SymlinkPair& linkObj) const { if (linkObj.isEmpty<LEFT_SIDE>()) linkObj.setActive(matchTime<RIGHT_SIDE>(linkObj)); @@ -1065,10 +1060,10 @@ private: matchTime<LEFT_SIDE> (linkObj)); } - void operator()(zen::DirPair& dirObj) const + void processDir(DirPair& dirObj) const { dirObj.setActive(false); - execute(dirObj); //recursion + recurse(dirObj); } template <SelectedSide side, class T> @@ -1085,8 +1080,7 @@ private: void zen::applyTimeSpanFilter(FolderComparison& folderCmp, const Int64& timeFrom, const Int64& timeTo) { - FilterByTimeSpan spanFilter(timeFrom, timeTo); - std::for_each(begin(folderCmp), end(folderCmp), [&](BaseDirPair& baseDirObj) { spanFilter.execute(baseDirObj); }); + std::for_each(begin(folderCmp), end(folderCmp), [&](BaseDirPair& baseDirObj) { FilterByTimeSpan::execute(baseDirObj, timeFrom, timeTo); }); } @@ -1235,9 +1229,9 @@ struct ItemDeleter : public FSObjectVisitor //throw FileError, but nothrow cons { if (useRecycleBin_) { - txtRemovingFile = _("Moving file %x to recycle bin" ); - txtRemovingDirectory = _("Moving folder %x to recycle bin" ); - txtRemovingSymlink = _("Moving symbolic link %x to recycle bin"); + txtRemovingFile = _("Moving file %x to the recycle bin" ); + txtRemovingDirectory = _("Moving folder %x to the recycle bin" ); + txtRemovingSymlink = _("Moving symbolic link %x to the recycle bin"); } else { @@ -1264,17 +1258,12 @@ struct ItemDeleter : public FSObjectVisitor //throw FileError, but nothrow cons if (useRecycleBin_) zen::recycleOrDelete(linkObj.getFullName<side>()); //throw FileError else - switch (getSymlinkType(linkObj.getFullName<side>())) - { - case SYMLINK_TYPE_DIR: - zen::removeDirectory(linkObj.getFullName<side>()); //throw FileError - break; - - case SYMLINK_TYPE_FILE: - case SYMLINK_TYPE_UNKNOWN: - zen::removeFile(linkObj.getFullName<side>()); //throw FileError - break; - } + { + if (dirExists(linkObj.getFullName<side>())) //dir symlink + zen::removeDirectory(linkObj.getFullName<side>()); //throw FileError + else //file symlink, broken symlink + zen::removeFile(linkObj.getFullName<side>()); //throw FileError + } } virtual void visit(const DirPair& dirObj) @@ -1386,7 +1375,7 @@ void zen::deleteFromGridAndHD(const std::vector<FileSystemObject*>& rowsToDelete { SyncDirection newDir = SyncDirection::NONE; - if (cfgIter->second.var == DirectionConfig::AUTOMATIC) + if (cfgIter->second.var == DirectionConfig::TWOWAY) newDir = fsObj.isEmpty<LEFT_SIDE>() ? SyncDirection::RIGHT : SyncDirection::LEFT; else { @@ -1420,7 +1409,7 @@ void zen::deleteFromGridAndHD(const std::vector<FileSystemObject*>& rowsToDelete if (useRecycleBin && std::any_of(hasRecyclerBuffer.begin(), hasRecyclerBuffer.end(), [](std::pair<Zstring, bool> item) { return !item.second; })) { - std::wstring msg = _("The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:") + L"\n"; + std::wstring msg = _("The recycle bin is not available for the following folders. Files will be deleted permanently instead:") + L"\n"; for (auto it = hasRecyclerBuffer.begin(); it != hasRecyclerBuffer.end(); ++it) if (!it->second) diff --git a/comparison.cpp b/comparison.cpp index c674269e..cdf2308f 100644 --- a/comparison.cpp +++ b/comparison.cpp @@ -74,7 +74,6 @@ void checkForIncompleteInput(const std::vector<FolderPairCfg>& folderPairsForm, _("The corresponding folder will be considered as empty."), warningInputFieldEmpty); } - std::set<Zstring, LessFilename> determineExistentDirs(const std::set<Zstring, LessFilename>& dirnames, bool allowUserInteraction, ProcessCallback& callback) @@ -83,26 +82,6 @@ std::set<Zstring, LessFilename> determineExistentDirs(const std::set<Zstring, Le tryReportingError2([&] { - warn_static("remove after test") -#if 0 - dirsEx.clear(); - std::for_each(dirnames.begin(), dirnames.end(), - [&](const Zstring& dirname) - { - if (!dirname.empty()) - { - loginNetworkShare(dirname, allowUserInteraction); - - const DWORD attr = ::GetFileAttributes(applyLongPathPrefix(dirname).c_str()); - if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY) != 0) //returns true for (dir-)symlinks also - dirsEx.insert(dirname); - else - throw FileError(_("Cannot find the following folders:") + L"\n" + std::wstring(L"\n") + dirname, - attr == INVALID_FILE_ATTRIBUTES ? formatSystemError(L"GetFileAttributes", getLastError()) : L"not a directory!"); - } - }); - -#else dirsEx = getExistingDirsUpdating(dirnames, allowUserInteraction, callback); //check *all* directories on each try! //get list of not existing directories @@ -115,7 +94,6 @@ std::set<Zstring, LessFilename> determineExistentDirs(const std::set<Zstring, Le std::for_each(dirsMissing.begin(), dirsMissing.end(), [&](const Zstring& dirname) { msg += std::wstring(L"\n") + dirname; }); throw FileError(msg, _("You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.")); } -#endif }, callback); return dirsEx; @@ -425,8 +403,8 @@ void categorizeSymlinkByContent(SymlinkPair& linkObj, size_t fileTimeTolerance, if (targetPathRawL == targetPathRawR #ifdef ZEN_WIN //type of symbolic link is relevant for Windows only && - getSymlinkType(linkObj.getFullName<LEFT_SIDE >()) == - getSymlinkType(linkObj.getFullName<RIGHT_SIDE>()) + dirExists(linkObj.getFullName<LEFT_SIDE >()) == //check if dir-symlink + dirExists(linkObj.getFullName<RIGHT_SIDE>()) // #endif ) { @@ -565,16 +543,16 @@ private: template <SelectedSide side> void MergeSides::fillOneSide(const DirContainer& dirCont, HierarchyObject& output) { - for (auto it = dirCont.files.cbegin(); it != dirCont.files.cend(); ++it) - output.addSubFile<side>(it->first, it->second); + for (const auto& file : dirCont.files) + output.addSubFile<side>(file.first, file.second); - for (auto it = dirCont.links.cbegin(); it != dirCont.links.cend(); ++it) - output.addSubLink<side>(it->first, it->second); + for (const auto& link : dirCont.links) + output.addSubLink<side>(link.first, link.second); - for (auto it = dirCont.dirs.cbegin(); it != dirCont.dirs.cend(); ++it) + for (const auto& dir : dirCont.dirs) { - DirPair& newDirMap = output.addSubDir<side>(it->first); - fillOneSide<side>(it->second, newDirMap); //recurse + DirPair& newDirMap = output.addSubDir<side>(dir.first); + fillOneSide<side>(dir.second, newDirMap); //recurse } } @@ -681,22 +659,18 @@ void MergeSides::execute(const DirContainer& leftSide, const DirContainer& right } //mark excluded directories (see fillBuffer()) + remove superfluous excluded subdirectories -//note: this cannot be done while traversing directory, since both sides need to be taken into account, both for filtering AND removing subdirs! void removeFilteredDirs(HierarchyObject& hierObj, const HardFilter& filterProc) { - auto& subDirs = hierObj.refSubDirs(); - //process subdirs recursively - std::for_each(subDirs.begin(), subDirs.end(), - [&](DirPair& dirObj) + for (DirPair& dirObj : hierObj.refSubDirs()) { dirObj.setActive(filterProc.passDirFilter(dirObj.getObjRelativeName(), nullptr)); //subObjMightMatch is always true in this context! removeFilteredDirs(dirObj, filterProc); - }); + } //remove superfluous directories -> note: this does not invalidate "std::vector<FilePair*>& undefinedFiles", since we delete folders only //and there is no side-effect for memory positions of FilePair and SymlinkPair thanks to zen::FixedList! - subDirs.remove_if([](DirPair& dirObj) + hierObj.refSubDirs().remove_if([](DirPair& dirObj) { return !dirObj.isActive() && dirObj.refSubDirs ().empty() && @@ -741,14 +715,13 @@ std::shared_ptr<BaseDirPair> ComparisonBuffer::performComparison(const FolderPai if (bufValueLeft ) filterAddFailedItemReads(bufValueLeft ->failedItemReads); if (bufValueRight) filterAddFailedItemReads(bufValueRight->failedItemReads); - //a pity VC11 screws up on std::make_shared with 7 arguments... - std::shared_ptr<BaseDirPair> output(new BaseDirPair(fpCfg.leftDirectoryFmt, - bufValueLeft != nullptr, //dir existence must be checked only once: available iff buffer entry exists! - fpCfg.rightDirectoryFmt, - bufValueRight != nullptr, - fpCfg.filter.nameFilter, - fpCfg.compareVar, - fileTimeTolerance)); + std::shared_ptr<BaseDirPair> output = std::make_shared<BaseDirPair>(fpCfg.leftDirectoryFmt, + bufValueLeft != nullptr, //dir existence must be checked only once: available iff buffer entry exists! + fpCfg.rightDirectoryFmt, + bufValueRight != nullptr, + fpCfg.filter.nameFilter, + fpCfg.compareVar, + fileTimeTolerance); //PERF_START; MergeSides(undefinedFiles, undefinedLinks).execute(bufValueLeft ? bufValueLeft ->dirCont : DirContainer(), bufValueRight ? bufValueRight->dirCont : DirContainer(), *output); @@ -865,8 +838,7 @@ void zen::compare(size_t fileTimeTolerance, //process binary comparison in one block std::vector<FolderPairCfg> workLoadByContent; - std::for_each(cfgList.begin(), cfgList.end(), [&](const FolderPairCfg& fpCfg) - { + for (const FolderPairCfg& fpCfg : cfgList) switch (fpCfg.compareVar) { case CMP_BY_TIME_SIZE: @@ -875,12 +847,10 @@ void zen::compare(size_t fileTimeTolerance, workLoadByContent.push_back(fpCfg); break; } - }); std::list<std::shared_ptr<BaseDirPair>> outputByContent = cmpBuff.compareByContent(workLoadByContent); //write output in order - std::for_each(cfgList.begin(), cfgList.end(), [&](const FolderPairCfg& fpCfg) - { + for (const FolderPairCfg& fpCfg : cfgList) switch (fpCfg.compareVar) { case CMP_BY_TIME_SIZE: @@ -895,7 +865,6 @@ void zen::compare(size_t fileTimeTolerance, } break; } - }); } assert(outputTmp.size() == cfgList.size()); diff --git a/file_hierarchy.cpp b/file_hierarchy.cpp index c20b971e..ac62d605 100644 --- a/file_hierarchy.cpp +++ b/file_hierarchy.cpp @@ -30,7 +30,7 @@ void HierarchyObject::removeEmptyRec() if (emptyExisting) //notify if actual deletion happened notifySyncCfgChanged(); //mustn't call this in ~FileSystemObject(), since parent, usually a DirPair, is already partially destroyed and existing as a pure HierarchyObject! - for (auto& subDir : refSubDirs()) + for (DirPair& subDir : refSubDirs()) subDir.removeEmptyRec(); //recurse } diff --git a/file_hierarchy.h b/file_hierarchy.h index 1675d223..ce3a96b0 100644 --- a/file_hierarchy.h +++ b/file_hierarchy.h @@ -173,8 +173,8 @@ public: const FileDescriptor& right); template <SelectedSide side> - FilePair& addSubFile(const Zstring& shortNameRight, //file exists on one side only - const FileDescriptor& right); + FilePair& addSubFile(const Zstring& shortName, //file exists on one side only + const FileDescriptor& descr); SymlinkPair& addSubLink(const Zstring& shortNameLeft, const LinkDescriptor& left, //link exists on both sides @@ -833,9 +833,12 @@ void FileSystemObject::flip() inline void HierarchyObject::flip() { - std::for_each(refSubFiles().begin(), refSubFiles().end(), std::mem_fun_ref(&FilePair ::flip)); - std::for_each(refSubDirs ().begin(), refSubDirs ().end(), std::mem_fun_ref(&DirPair ::flip)); - std::for_each(refSubLinks().begin(), refSubLinks().end(), std::mem_fun_ref(&SymlinkPair::flip)); + for (FilePair& fileObj : refSubFiles()) + fileObj.flip(); + for (SymlinkPair& linkObj : refSubLinks()) + linkObj.flip(); + for (DirPair& dirObj : refSubDirs()) + dirObj.flip(); } @@ -942,18 +945,24 @@ void DirPair::flip() inline void DirPair::removeObjectL() { - std::for_each(refSubFiles().begin(), refSubFiles().end(), std::mem_fun_ref(&FileSystemObject::removeObject<LEFT_SIDE>)); - std::for_each(refSubLinks().begin(), refSubLinks().end(), std::mem_fun_ref(&FileSystemObject::removeObject<LEFT_SIDE>)); - std::for_each(refSubDirs(). begin(), refSubDirs() .end(), std::mem_fun_ref(&FileSystemObject::removeObject<LEFT_SIDE>)); + for (FilePair& fileObj : refSubFiles()) + fileObj.removeObject<LEFT_SIDE>(); + for (SymlinkPair& linkObj : refSubLinks()) + linkObj.removeObject<LEFT_SIDE>(); + for (DirPair& dirObj : refSubDirs()) + dirObj.removeObject<LEFT_SIDE>(); } inline void DirPair::removeObjectR() { - std::for_each(refSubFiles().begin(), refSubFiles().end(), std::mem_fun_ref(&FileSystemObject::removeObject<RIGHT_SIDE>)); - std::for_each(refSubLinks().begin(), refSubLinks().end(), std::mem_fun_ref(&FileSystemObject::removeObject<RIGHT_SIDE>)); - std::for_each(refSubDirs(). begin(), refSubDirs(). end(), std::mem_fun_ref(&FileSystemObject::removeObject<RIGHT_SIDE>)); + for (FilePair& fileObj : refSubFiles()) + fileObj.removeObject<RIGHT_SIDE>(); + for (SymlinkPair& linkObj : refSubLinks()) + linkObj.removeObject<RIGHT_SIDE>(); + for (DirPair& dirObj : refSubDirs()) + dirObj.removeObject<RIGHT_SIDE>(); } diff --git a/lib/ShadowCopy/Shadow_Server2003.vcxproj b/lib/ShadowCopy/Shadow_Server2003.vcxproj deleted file mode 100644 index a9b8f740..00000000 --- a/lib/ShadowCopy/Shadow_Server2003.vcxproj +++ /dev/null @@ -1,239 +0,0 @@ -<?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"> - <ProjectName>Server2003</ProjectName> - <ProjectGuid>{2F2994D6-FB89-4BAA-A5DF-03BAF7337FF2}</ProjectGuid> - <RootNamespace>ShadowDll</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <UseOfAtl>false</UseOfAtl> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> - <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> - <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> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Shadow_$(ProjectName)_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Shadow_$(ProjectName)_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Shadow_$(ProjectName)_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Shadow_$(ProjectName)_$(Platform)</TargetName> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>EditAndContinue</DebugInformationFormat> - <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> - <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> - <SmallerTypeCheck>true</SmallerTypeCheck> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> - <SubSystem>Windows</SubSystem> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX86</TargetMachine> - <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage\lib</AdditionalLibraryDirectories> - <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> - <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> - <SmallerTypeCheck>true</SmallerTypeCheck> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> - <SubSystem>Windows</SubSystem> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX64</TargetMachine> - <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage_x64\lib</AdditionalLibraryDirectories> - <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <FunctionLevelLinking>true</FunctionLevelLinking> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> - <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX86</TargetMachine> - <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage\lib</AdditionalLibraryDirectories> - <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <FunctionLevelLinking>true</FunctionLevelLinking> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> - <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX64</TargetMachine> - <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage_x64\lib</AdditionalLibraryDirectories> - <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\..\zen\debug_memory_leaks.cpp" /> - <ClCompile Include="shadow.cpp" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="shadow.h" /> - </ItemGroup> - <ItemGroup> - <Library Include="Server 2003\lib\$(Platform)\vssapi.lib" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/lib/ShadowCopy/Shadow_Windows7.vcxproj b/lib/ShadowCopy/Shadow_Windows7.vcxproj index 7c6f1f1d..1f02e675 100644 --- a/lib/ShadowCopy/Shadow_Windows7.vcxproj +++ b/lib/ShadowCopy/Shadow_Windows7.vcxproj @@ -30,23 +30,23 @@ <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> <UseOfAtl>false</UseOfAtl> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> @@ -88,7 +88,7 @@ <ClCompile> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> + <MinimalRebuild>false</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <PrecompiledHeader> @@ -99,6 +99,7 @@ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> <SmallerTypeCheck>true</SmallerTypeCheck> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> @@ -123,7 +124,7 @@ </Midl> <ClCompile> <Optimization>Disabled</Optimization> - <MinimalRebuild>true</MinimalRebuild> + <MinimalRebuild>false</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <PrecompiledHeader> @@ -135,6 +136,7 @@ <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions> <SmallerTypeCheck>true</SmallerTypeCheck> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> @@ -168,11 +170,12 @@ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> + <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> @@ -206,11 +209,12 @@ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> + <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> diff --git a/lib/ShadowCopy/Shadow_XP.vcxproj b/lib/ShadowCopy/Shadow_XP.vcxproj deleted file mode 100644 index 0d54f2e4..00000000 --- a/lib/ShadowCopy/Shadow_XP.vcxproj +++ /dev/null @@ -1,240 +0,0 @@ -<?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"> - <ProjectName>XP</ProjectName> - <ProjectGuid>{70394AEF-5897-4911-AFA1-82EAF0581EFA}</ProjectGuid> - <RootNamespace>ShadowDll</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> - <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> - <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> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> - <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\</OutDir> - <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir> - <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Shadow_$(ProjectName)_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Shadow_$(ProjectName)_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Shadow_$(ProjectName)_$(Platform)</TargetName> - <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Shadow_$(ProjectName)_$(Platform)</TargetName> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>EditAndContinue</DebugInformationFormat> - <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed> - <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> - <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> - <SmallerTypeCheck>true</SmallerTypeCheck> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> - <SubSystem>Windows</SubSystem> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX86</TargetMachine> - <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage\lib</AdditionalLibraryDirectories> - <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> - <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed> - <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> - <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> - <SmallerTypeCheck>true</SmallerTypeCheck> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> - <SubSystem>Windows</SubSystem> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX64</TargetMachine> - <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage_x64\lib</AdditionalLibraryDirectories> - <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <FunctionLevelLinking>true</FunctionLevelLinking> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> - <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX86</TargetMachine> - <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage\lib</AdditionalLibraryDirectories> - <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <BuildLog> - <Path>$(IntDir)Build.html</Path> - </BuildLog> - <Midl> - <TargetEnvironment>X64</TargetEnvironment> - </Midl> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - <FunctionLevelLinking>true</FunctionLevelLinking> - <PrecompiledHeader> - </PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <SuppressStartupBanner>true</SuppressStartupBanner> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> - <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> - <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> - </ClCompile> - <Link> - <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> - <SubSystem>Windows</SubSystem> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> - <ProfileGuidedDatabase> - </ProfileGuidedDatabase> - <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> - <TargetMachine>MachineX64</TargetMachine> - <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage_x64\lib</AdditionalLibraryDirectories> - <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\..\zen\debug_memory_leaks.cpp" /> - <ClCompile Include="shadow.cpp" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="shadow.h" /> - </ItemGroup> - <ItemGroup> - <Library Include="XP\lib\$(Platform)\vssapi.lib" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project>
\ No newline at end of file diff --git a/lib/ShadowCopy/shadow.cpp b/lib/ShadowCopy/shadow.cpp index e915663f..adc7c5c2 100644 --- a/lib/ShadowCopy/shadow.cpp +++ b/lib/ShadowCopy/shadow.cpp @@ -89,8 +89,27 @@ shadow::ShadowData createShadowCopy(const wchar_t* volumeName) //throw SysError } ZEN_COM_CHECK(backupComp->InitializeForBackup()); //throw SysError + + //SetContext() only required if different than the default, VSS_CTX_BACKUP; not implemented on XP!!! + //ZEN_COM_CHECK(backupComp->SetContext(VSS_CTX_BACKUP)); //throw SysError + ZEN_COM_CHECK(backupComp->SetBackupState(false, false, VSS_BT_FULL)); //throw SysError + + //the Shadow Copy Optimization Writer removes items it considers non-essential, + //http://msdn.microsoft.com/en-US/library/bb968827#shadow_copy_optimization_writer + //like the exclusions in HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\BackupRestore\FilesNotToSnapshot + //http://msdn.microsoft.com/en-us/library/aa819132%28v=vs.85%29.aspx + //Outlook *.ost files in particular: + //https://sourceforge.net/p/freefilesync/discussion/help/thread/722dcbfb + const VSS_ID disabledWriters[] = { { 0x4dc3bdd4, 0xab48, 0x4d07, { 0xad, 0xb0, 0x3b, 0xee, 0x29, 0x26, 0xfd, 0x7f } } }; //Shadow Copy Optimization Writer + { + HRESULT hr = backupComp->DisableWriterClasses(disabledWriters, 1); + if (FAILED(hr) && hr != E_NOTIMPL) //DisableWriterClasses() is not implemented on Windows XP, although MSDN documented otherwise! + throw SysError(formatComError(L"Error calling \"backupComp->DisableWriterClasses\".", hr)); + } + + auto waitForComFuture = [](IVssAsync& fut) { ZEN_COM_CHECK(fut.Wait()); diff --git a/lib/Thumbnail/Thumbnail.vcxproj b/lib/Thumbnail/Thumbnail.vcxproj index 1ec016be..a4719ae7 100644 --- a/lib/Thumbnail/Thumbnail.vcxproj +++ b/lib/Thumbnail/Thumbnail.vcxproj @@ -28,23 +28,23 @@ <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> @@ -86,7 +86,7 @@ <ClCompile> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;ZEN_WIN;_DEBUG;_WINDOWS;_USRDLL;THUMBNAIL_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> + <MinimalRebuild>false</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <PrecompiledHeader> @@ -97,6 +97,7 @@ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> <SmallerTypeCheck>true</SmallerTypeCheck> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> @@ -121,7 +122,7 @@ <ClCompile> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;THUMBNAIL_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> + <MinimalRebuild>false</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <PrecompiledHeader> @@ -132,6 +133,7 @@ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> <SmallerTypeCheck>true</SmallerTypeCheck> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> @@ -164,11 +166,12 @@ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> + <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> @@ -201,11 +204,12 @@ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> + <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> diff --git a/lib/db_file.cpp b/lib/db_file.cpp index ab7f9212..1c2a34f3 100644 --- a/lib/db_file.cpp +++ b/lib/db_file.cpp @@ -24,16 +24,12 @@ namespace { //------------------------------------------------------------------------------------------------------------------------------- const char FILE_FORMAT_DESCR[] = "FreeFileSync"; -const int DB_FILE_FORMAT_VER = 9; - -warn_static("wee need two version ids!") -//const int DB_FILE_FORMAT_CONTAINER = 10; -//const int DB_FILE_FORMAT_STREAM = 1; - +const int DB_FORMAT_CONTAINER = 9; +const int DB_FORMAT_STREAM = 1; //------------------------------------------------------------------------------------------------------------------------------- typedef std::string UniqueId; -typedef std::map<UniqueId, BinaryStream> StreamMapping; //list of streams ordered by session UUID +typedef std::map<UniqueId, BinaryStream> DbStreams; //list of streams ordered by session UUID //----------------------------------------------------------------------------------- //| ensure 32/64 bit portability: use fixed size data types only e.g. std::uint32_t | @@ -58,7 +54,7 @@ Zstring getDBFilename(const BaseDirPair& baseDirObj, bool tempfile = false) //####################################################################################################################################### -void saveStreams(const StreamMapping& streamList, const Zstring& filename) //throw FileError +void saveStreams(const DbStreams& streamList, const Zstring& filename) //throw FileError { BinStreamOut streamOut; @@ -66,15 +62,15 @@ void saveStreams(const StreamMapping& streamList, const Zstring& filename) //thr writeArray(streamOut, FILE_FORMAT_DESCR, sizeof(FILE_FORMAT_DESCR)); //save file format version - writeNumber<std::int32_t>(streamOut, DB_FILE_FORMAT_VER); + writeNumber<std::int32_t>(streamOut, DB_FORMAT_CONTAINER); //save stream list writeNumber<std::uint32_t>(streamOut, static_cast<std::uint32_t>(streamList.size())); //number of streams, one for each sync-pair - for (auto it = streamList.begin(); it != streamList.end(); ++it) + for (const auto& stream : streamList) { - writeContainer<std::string >(streamOut, it->first ); - writeContainer<BinaryStream>(streamOut, it->second); + writeContainer<std::string >(streamOut, stream.first ); + writeContainer<BinaryStream>(streamOut, stream.second); } assert(!somethingExists(filename)); //orphan tmp files should be cleaned up already at this point! @@ -87,7 +83,7 @@ void saveStreams(const StreamMapping& streamList, const Zstring& filename) //thr } -StreamMapping loadStreams(const Zstring& filename) //throw FileError, FileErrorDatabaseNotExisting +DbStreams loadStreams(const Zstring& filename) //throw FileError, FileErrorDatabaseNotExisting { try { @@ -101,12 +97,12 @@ StreamMapping loadStreams(const Zstring& filename) //throw FileError, FileErrorD throw FileError(replaceCpy(_("Database file %x is incompatible."), L"%x", fmtFileName(filename))); const int version = readNumber<std::int32_t>(streamIn); //throw UnexpectedEndOfStreamError - if (version != DB_FILE_FORMAT_VER) //read file format version number + if (version != DB_FORMAT_CONTAINER) //read file format version number throw FileError(replaceCpy(_("Database file %x is incompatible."), L"%x", fmtFileName(filename))); - //read stream lists - StreamMapping output; + DbStreams output; + //read stream lists size_t dbCount = readNumber<std::uint32_t>(streamIn); //number of streams, one for each sync-pair while (dbCount-- != 0) { @@ -159,16 +155,16 @@ public: { /* Zlib: optimal level - testcase 1 million files level/size [MB]/time [ms] - 0 49.54 272 (uncompressed) - 1 14.53 1013 - 2 14.13 1106 - 3 13.76 1288 - best compromise between speed and compression - 4 13.20 1526 - 5 12.73 1916 - 6 12.58 2765 - 7 12.54 3633 - 8 12.51 9032 - 9 12.50 19698 (maximal compression) */ + 0 49.54 272 (uncompressed) + 1 14.53 1013 + 2 14.13 1106 + 3 13.76 1288 - best compromise between speed and compression + 4 13.20 1526 + 5 12.73 1916 + 6 12.58 2765 + 7 12.54 3633 + 8 12.51 9032 + 9 12.50 19698 (maximal compression) */ return compress(stream, 3); //throw ZlibInternalError } catch (ZlibInternalError&) @@ -181,14 +177,18 @@ public: const BinaryStream tmpR = compStream(generator.outputRight.get(), filenameR); const BinaryStream tmpB = compStream(generator.outputBoth .get(), filenameL + Zstr("/") + filenameR); - //distribute "outputBoth" over left and right streams: BinStreamOut outL; BinStreamOut outR; - writeNumber<bool>(outL, true); //this side contains first part of "outputBoth" - writeNumber<bool>(outR, false); + //save format version + writeNumber<std::int32_t>(outL, DB_FORMAT_STREAM); + writeNumber<std::int32_t>(outR, DB_FORMAT_STREAM); + + //distribute "outputBoth" over left and right streams: + writeNumber<std::int8_t>(outL, true); //this side contains first part of "outputBoth" + writeNumber<std::int8_t>(outR, false); - size_t size1stPart = tmpB.size() / 2; - size_t size2ndPart = tmpB.size() - size1stPart; + const size_t size1stPart = tmpB.size() / 2; + const size_t size2ndPart = tmpB.size() - size1stPart; writeNumber<std::uint64_t>(outL, size1stPart); writeNumber<std::uint64_t>(outR, size2ndPart); @@ -207,24 +207,42 @@ public: private: void recurse(const InSyncDir& container) { - // for (const auto& dbFile : container.files) { processFile(dbFile); }); ! - writeNumber<std::uint32_t>(outputBoth, static_cast<std::uint32_t>(container.files.size())); - std::for_each(container.files.begin(), container.files.end(), [&](const std::pair<Zstring, InSyncFile>& dbFile) { this->process(dbFile); }); + for (const auto& dbFile : container.files) + { + writeUtf8(outputBoth, dbFile.first); + writeNumber<std::int32_t>(outputBoth, dbFile.second.cmpVar); + writeNumber<std::uint64_t>(outputBoth, to<std::uint64_t>(dbFile.second.fileSize)); + + writeFile(outputLeft, dbFile.second.left); + writeFile(outputRight, dbFile.second.right); + } writeNumber<std::uint32_t>(outputBoth, static_cast<std::uint32_t>(container.symlinks.size())); - std::for_each(container.symlinks.begin(), container.symlinks.end(), [&](const std::pair<Zstring, InSyncSymlink>& dbSymlink) { this->process(dbSymlink); }); + for (const auto& dbSymlink : container.symlinks) + { + writeUtf8(outputBoth, dbSymlink.first); + writeNumber<std::int32_t>(outputBoth, dbSymlink.second.cmpVar); + + writeLink(outputLeft, dbSymlink.second.left); + writeLink(outputRight, dbSymlink.second.right); + } writeNumber<std::uint32_t>(outputBoth, static_cast<std::uint32_t>(container.dirs.size())); - std::for_each(container.dirs.begin(), container.dirs.end(), [&](const std::pair<Zstring, InSyncDir>& dbDir) { this->process(dbDir); }); + for (const auto& dbDir : container.dirs) + { + writeUtf8(outputBoth, dbDir.first); + writeNumber<std::int32_t>(outputBoth, dbDir.second.status); + + recurse(dbDir.second); + } } static void writeUtf8(BinStreamOut& output, const Zstring& str) { writeContainer(output, utfCvrtTo<Zbase<char>>(str)); } - static void writeFile(BinStreamOut& output, const InSyncDescrFile& descr, const UInt64& fileSize) + static void writeFile(BinStreamOut& output, const InSyncDescrFile& descr) { writeNumber<std:: int64_t>(output, to<std:: int64_t>(descr.lastWriteTimeRaw)); - writeNumber<std::uint64_t>(output, to<std::uint64_t>(fileSize)); writeNumber<std::uint64_t>(output, descr.fileId.first); writeNumber<std::uint64_t>(output, descr.fileId.second); assert_static(sizeof(descr.fileId.first ) <= sizeof(std::uint64_t)); @@ -234,47 +252,6 @@ private: static void writeLink(BinStreamOut& output, const InSyncDescrLink& descr) { writeNumber<std::int64_t>(output, to<std:: int64_t>(descr.lastWriteTimeRaw)); - - warn_static("implement proper migration!") - //writeUtf8(output, descr.targetPath); - writeUtf8(output, Zstring()); - //writeNumber<std::int32_t>(output, descr.type); - writeNumber<std::int32_t>(output, 0); - } - - static void writeDir(BinStreamOut& output, const InSyncDir::InSyncStatus& status) - { - writeNumber<std::int32_t>(output, status); - } - - void process(const std::pair<Zstring, InSyncFile>& dbFile) - { - writeUtf8(outputBoth, dbFile.first); - writeNumber<std::int32_t>(outputBoth, dbFile.second.inSyncType); - - warn_static("implement proper migration: get rid of duplicate fileSize!") - - writeFile(outputLeft, dbFile.second.left, dbFile.second.fileSize); - writeFile(outputRight, dbFile.second.right, dbFile.second.fileSize); - } - - void process(const std::pair<Zstring, InSyncSymlink>& dbSymlink) - { - writeUtf8(outputBoth, dbSymlink.first); - - warn_static("new parameter: imp proper migration!") - //writeNumber<std::int32_t>(outputBoth, dbSymlink.second.inSyncType); - - writeLink(outputLeft, dbSymlink.second.left); - writeLink(outputRight, dbSymlink.second.right); - } - - void process(const std::pair<Zstring, InSyncDir>& dbDir) - { - writeUtf8(outputBoth, dbDir.first); - writeDir(outputBoth, dbDir.second.status); - - recurse(dbDir.second); } BinStreamOut outputLeft; //data related to one side only @@ -283,7 +260,7 @@ private: }; -class StreamParser //for db-file back-wards compatibility we stick with two output streams until further +class StreamParser { public: static std::shared_ptr<InSyncDir> execute(const BinaryStream& streamL, //throw FileError @@ -308,8 +285,33 @@ public: BinStreamIn inL(streamL); BinStreamIn inR(streamR); - bool has1stPartL = readNumber<bool>(inL); //throw UnexpectedEndOfStreamError - bool has1stPartR = readNumber<bool>(inR); // + const int streamVersion = readNumber<std::int32_t>(inL); //throw UnexpectedEndOfStreamError + warn_static("remove this case after migration:") + bool migrateStreamFromOldFormat = streamVersion != DB_FORMAT_STREAM; + if (migrateStreamFromOldFormat) + inL = BinStreamIn(streamL); + else + { + const int streamVersionRef = readNumber<std::int32_t>(inR); //throw UnexpectedEndOfStreamError + if (streamVersionRef != streamVersion) //throw UnexpectedEndOfStreamError + throw FileError(replaceCpy(_("Database file %x is incompatible."), L"%x", fmtFileName(filenameR), L"stream format mismatch")); + if (streamVersion != DB_FORMAT_STREAM) + throw FileError(replaceCpy(_("Database file %x is incompatible."), L"%x", fmtFileName(filenameL), L"stream format")); + } + + bool has1stPartL = false; + bool has1stPartR = false; + if (migrateStreamFromOldFormat) + { + has1stPartL = readNumber<bool>(inL) != 0; //throw UnexpectedEndOfStreamError + has1stPartR = readNumber<bool>(inR) != 0; // + } + else + { + has1stPartL = readNumber<std::int8_t>(inL) != 0; //throw UnexpectedEndOfStreamError + has1stPartR = readNumber<std::int8_t>(inR) != 0; // + } + if (has1stPartL == has1stPartR) throw UnexpectedEndOfStreamError(); @@ -320,7 +322,7 @@ public: const size_t size2ndPart = static_cast<size_t>(readNumber<std::uint64_t>(in2ndPart)); BinaryStream tmpB; - tmpB.resize(size1stPart + size2ndPart); + tmpB.resize(size1stPart + size2ndPart); //throw bad_alloc readArray(in1stPart, &*tmpB.begin(), size1stPart); readArray(in2ndPart, &*tmpB.begin() + size1stPart, size2ndPart); @@ -330,7 +332,7 @@ public: auto output = std::make_shared<InSyncDir>(InSyncDir::DIR_STATUS_IN_SYNC); StreamParser parser(decompStream(tmpL, filenameL), decompStream(tmpR, filenameR), - decompStream(tmpB, filenameL + Zstr("/") + filenameR)); + decompStream(tmpB, filenameL + Zstr("/") + filenameR), migrateStreamFromOldFormat); parser.recurse(*output); //throw UnexpectedEndOfStreamError return output; } @@ -338,7 +340,7 @@ public: { throw FileError(_("Database file is corrupt:") + L"\n" + fmtFileName(filenameL) + L"\n" + fmtFileName(filenameR)); } - catch (const std::bad_alloc& e) //still required? + catch (const std::bad_alloc& e) { throw FileError(_("Database file is corrupt:") + L"\n" + fmtFileName(filenameL) + L"\n" + fmtFileName(filenameR), _("Out of memory.") + L" " + utfCvrtTo<std::wstring>(e.what())); @@ -348,57 +350,47 @@ public: private: StreamParser(const BinaryStream& bufferL, const BinaryStream& bufferR, - const BinaryStream& bufferB) : + const BinaryStream& bufferB, + bool migrateStreamFromOldFormat) : + migrateStreamFromOldFormat_(migrateStreamFromOldFormat), inputLeft (bufferL), inputRight(bufferR), inputBoth (bufferB) {} - static Zstring readUtf8(BinStreamIn& input) { return utfCvrtTo<Zstring>(readContainer<Zbase<char>>(input)); } //throw UnexpectedEndOfStreamError - - static InSyncDescrFile readFile(BinStreamIn& input, UInt64& fileSize) - { - //attention: order of function argument evaluation is undefined! So do it one after the other... - auto lastWriteTimeRaw = readNumber<std::int64_t>(input); //throw UnexpectedEndOfStreamError - warn_static("implement proper migration!") - fileSize = readNumber<std::uint64_t>(input); - auto devId = static_cast<DeviceId >(readNumber<std::uint64_t>(input)); // - auto fileIdx = static_cast<FileIndex>(readNumber<std::uint64_t>(input)); //silence "loss of precision" compiler warnings - return InSyncDescrFile(lastWriteTimeRaw, FileId(devId, fileIdx)); - } - - static InSyncDescrLink readLink(BinStreamIn& input) - { - auto lastWriteTimeRaw = readNumber<std::int64_t>(input); - - warn_static("implement proper migration!") - //descr.targetPath = readUtf8(input); - readUtf8(input); - //descr.type = static_cast<LinkDescriptor::LinkType>(readNumber<std::int32_t>(input)); - readNumber<std::int32_t>(input); - - return InSyncDescrLink(lastWriteTimeRaw); - } - - static void readDir(BinStreamIn& input, InSyncDir::InSyncStatus& status) - { - status = static_cast<InSyncDir::InSyncStatus>(readNumber<std::int32_t>(input)); - } - void recurse(InSyncDir& container) { size_t fileCount = readNumber<std::uint32_t>(inputBoth); while (fileCount-- != 0) { - warn_static("migrate from InSyncType to CompareVariant!!!") const Zstring shortName = readUtf8(inputBoth); - const auto inSyncType = static_cast<InSyncType>(readNumber<std::int32_t>(inputBoth)); - warn_static("implement proper migration: get rid of duplicate fileSize!") - - UInt64 fileSize; - const InSyncDescrFile dataL = readFile(inputLeft, fileSize); - const InSyncDescrFile dataR = readFile(inputRight, fileSize); - container.addFile(shortName, dataL, dataR, inSyncType, fileSize); + if (migrateStreamFromOldFormat_) + { + const auto inSyncType = readNumber<std::int32_t>(inputBoth); + const CompareVariant cmpVar = inSyncType == 0 ? CMP_BY_CONTENT : CMP_BY_TIME_SIZE; + + auto lastWriteTimeRawL = readNumber<std::int64_t>(inputLeft); //throw UnexpectedEndOfStreamError + const UInt64 fileSize = readNumber<std::uint64_t>(inputLeft); + auto devIdL = static_cast<DeviceId >(readNumber<std::uint64_t>(inputLeft)); // + auto fileIdxL = static_cast<FileIndex>(readNumber<std::uint64_t>(inputLeft)); //silence "loss of precision" compiler warnings + const InSyncDescrFile dataL = InSyncDescrFile(lastWriteTimeRawL, FileId(devIdL, fileIdxL)); + + auto lastWriteTimeRaw = readNumber<std::int64_t>(inputRight); //throw UnexpectedEndOfStreamError + readNumber<std::uint64_t>(inputRight); + auto devId = static_cast<DeviceId >(readNumber<std::uint64_t>(inputRight)); // + auto fileIdx = static_cast<FileIndex>(readNumber<std::uint64_t>(inputRight)); //silence "loss of precision" compiler warnings + const InSyncDescrFile dataR = InSyncDescrFile(lastWriteTimeRaw, FileId(devId, fileIdx)); + + container.addFile(shortName, dataL, dataR, cmpVar, fileSize); + } + else + { + const auto cmpVar = static_cast<CompareVariant>(readNumber<std::int32_t>(inputBoth)); + const UInt64 fileSize = readNumber<std::uint64_t>(inputBoth); + const InSyncDescrFile dataL = readFile(inputLeft); + const InSyncDescrFile dataR = readFile(inputRight); + container.addFile(shortName, dataL, dataR, cmpVar, fileSize); + } } size_t linkCount = readNumber<std::uint32_t>(inputBoth); @@ -406,28 +398,61 @@ private: { const Zstring shortName = readUtf8(inputBoth); - warn_static("new parameter: imp proper migration!") - const auto inSyncType = IN_SYNC_BINARY_EQUAL; - //const auto inSyncType = static_cast<InSyncType>(readNumber<std::int32_t>(inputBoth)); - - InSyncDescrLink dataL = readLink(inputLeft); - InSyncDescrLink dataR = readLink(inputRight); - container.addSymlink(shortName, dataL, dataR, inSyncType); + if (migrateStreamFromOldFormat_) + { + const CompareVariant cmpVar = CMP_BY_CONTENT; + auto lastWriteTimeRaw = readNumber<std::int64_t>(inputLeft); + readUtf8(inputLeft);//descr.targetPath = readUtf8(input); + readNumber<std::int32_t>(inputLeft);//descr.type = static_cast<LinkDescriptor::LinkType>(readNumber<std::int32_t>(input)); + InSyncDescrLink dataL = InSyncDescrLink(lastWriteTimeRaw); + + auto lastWriteTimeRawR = readNumber<std::int64_t>(inputRight); + readUtf8(inputRight);//descr.targetPath = readUtf8(input); + readNumber<std::int32_t>(inputRight);//descr.type = static_cast<LinkDescriptor::LinkType>(readNumber<std::int32_t>(input)); + InSyncDescrLink dataR = InSyncDescrLink(lastWriteTimeRawR); + + container.addSymlink(shortName, dataL, dataR, cmpVar); + } + else + { + const auto cmpVar = static_cast<CompareVariant>(readNumber<std::int32_t>(inputBoth)); + InSyncDescrLink dataL = readLink(inputLeft); + InSyncDescrLink dataR = readLink(inputRight); + container.addSymlink(shortName, dataL, dataR, cmpVar); + } } size_t dirCount = readNumber<std::uint32_t>(inputBoth); while (dirCount-- != 0) { const Zstring shortName = readUtf8(inputBoth); - - InSyncDir::InSyncStatus status = InSyncDir::DIR_STATUS_STRAW_MAN; - readDir(inputBoth, status); + auto status = static_cast<InSyncDir::InSyncStatus>(readNumber<std::int32_t>(inputBoth)); InSyncDir& subDir = container.addDir(shortName, status); recurse(subDir); } } + static Zstring readUtf8(BinStreamIn& input) { return utfCvrtTo<Zstring>(readContainer<Zbase<char>>(input)); } //throw UnexpectedEndOfStreamError + + static InSyncDescrFile readFile(BinStreamIn& input) + { + //attention: order of function argument evaluation is undefined! So do it one after the other... + auto lastWriteTimeRaw = readNumber<std::int64_t>(input); //throw UnexpectedEndOfStreamError + auto devId = static_cast<DeviceId >(readNumber<std::uint64_t>(input)); // + auto fileIdx = static_cast<FileIndex>(readNumber<std::uint64_t>(input)); //silence "loss of precision" compiler warnings + return InSyncDescrFile(lastWriteTimeRaw, FileId(devId, fileIdx)); + } + + static InSyncDescrLink readLink(BinStreamIn& input) + { + auto lastWriteTimeRaw = readNumber<std::int64_t>(input); + return InSyncDescrLink(lastWriteTimeRaw); + } + + warn_static("remove after migration") + bool migrateStreamFromOldFormat_; + BinStreamIn inputLeft; //data related to one side only BinStreamIn inputRight; // BinStreamIn inputBoth; //data concerning both sides @@ -446,24 +471,14 @@ class UpdateLastSynchronousState public: static void execute(const BaseDirPair& baseDirObj, InSyncDir& dir) { - bool binaryComparison = false; - switch (baseDirObj.getCompVariant()) - { - case CMP_BY_TIME_SIZE: - break; - case CMP_BY_CONTENT: - binaryComparison = true; - break; - } - - UpdateLastSynchronousState updater(baseDirObj.getFilter(), binaryComparison); + UpdateLastSynchronousState updater(baseDirObj.getCompVariant(), baseDirObj.getFilter()); updater.recurse(baseDirObj, dir); } private: - UpdateLastSynchronousState(const HardFilter& filter, bool binaryComparison) : + UpdateLastSynchronousState(CompareVariant activeCmpVar, const HardFilter& filter) : filter_(filter), - binaryComparison_(binaryComparison) {} + activeCmpVar_(activeCmpVar) {} void recurse(const HierarchyObject& hierObj, InSyncDir& dir) { @@ -516,8 +531,7 @@ private: void process(const HierarchyObject::SubFileVec& currentFiles, const Zstring& parentRelativeNamePf, InSyncDir::FileList& dbFiles) { hash_set<const InSyncFile*> toPreserve; //referencing fixed-in-memory std::map elements - std::for_each(currentFiles.begin(), currentFiles.end(), [&](const FilePair& fileObj) - { + for (const FilePair& fileObj : currentFiles) if (!fileObj.isEmpty()) { if (fileObj.getCategory() == FILE_EQUAL) //data in sync: write current state @@ -534,9 +548,7 @@ private: fileObj.getFileId <LEFT_SIDE>()), InSyncDescrFile(fileObj.getLastWriteTime<RIGHT_SIDE>(), fileObj.getFileId <RIGHT_SIDE>()), - binaryComparison_ ? - IN_SYNC_BINARY_EQUAL : - IN_SYNC_ATTRIBUTES_EQUAL, + activeCmpVar_, fileObj.getFileSize<LEFT_SIDE>())); toPreserve.insert(&file); } @@ -547,7 +559,6 @@ private: toPreserve.insert(&it->second); } } - }); warn_static("consider temporarily excluded items due to traveral error just like a fixed file filter here!?") //delete removed items (= "in-sync") from database @@ -564,8 +575,7 @@ private: void process(const HierarchyObject::SubLinkVec& currentLinks, const Zstring& parentRelativeNamePf, InSyncDir::LinkList& dbLinks) { hash_set<const InSyncSymlink*> toPreserve; - std::for_each(currentLinks.begin(), currentLinks.end(), [&](const SymlinkPair& linkObj) - { + for (const SymlinkPair& linkObj : currentLinks) if (!linkObj.isEmpty()) { if (linkObj.getLinkCategory() == SYMLINK_EQUAL) //data in sync: write current state @@ -576,9 +586,7 @@ private: InSyncSymlink& link = updateItem(dbLinks, linkObj.getObjShortName(), InSyncSymlink(InSyncDescrLink(linkObj.getLastWriteTime<LEFT_SIDE>()), InSyncDescrLink(linkObj.getLastWriteTime<RIGHT_SIDE>()), - binaryComparison_ ? - IN_SYNC_BINARY_EQUAL : - IN_SYNC_ATTRIBUTES_EQUAL)); + activeCmpVar_)); toPreserve.insert(&link); } else //not in sync: preserve last synchronous state @@ -588,7 +596,6 @@ private: toPreserve.insert(&it->second); } } - }); //delete removed items (= "in-sync") from database map_remove_if(dbLinks, [&](const InSyncDir::LinkList::value_type& v) -> bool @@ -604,8 +611,7 @@ private: void process(const HierarchyObject::SubDirVec& currentDirs, const Zstring& parentRelativeNamePf, InSyncDir::DirList& dbDirs) { hash_set<const InSyncDir*> toPreserve; - std::for_each(currentDirs.begin(), currentDirs.end(), [&](const DirPair& dirObj) - { + for (const DirPair& dirObj : currentDirs) if (!dirObj.isEmpty()) switch (dirObj.getDirCategory()) { @@ -659,7 +665,6 @@ private: } break; } - }); //delete removed items (= "in-sync") from database map_remove_if(dbDirs, [&](const InSyncDir::DirList::value_type& v) -> bool @@ -676,7 +681,7 @@ private: } const HardFilter& filter_; //filter used while scanning directory: generates view on actual files! - const bool binaryComparison_; + const CompareVariant activeCmpVar_; }; } @@ -698,17 +703,17 @@ std::shared_ptr<InSyncDir> zen::loadLastSynchronousState(const BaseDirPair& base } //read file data: list of session ID + DirInfo-stream - const StreamMapping streamListLeft = ::loadStreams(fileNameLeft); //throw FileError, FileErrorDatabaseNotExisting - const StreamMapping streamListRight = ::loadStreams(fileNameRight); // + const DbStreams streamsLeft = ::loadStreams(fileNameLeft); //throw FileError, FileErrorDatabaseNotExisting + const DbStreams streamsRight = ::loadStreams(fileNameRight); // //find associated session: there can be at most one session within intersection of left and right ids - for (auto iterLeft = streamListLeft.begin(); iterLeft != streamListLeft.end(); ++iterLeft) + for (const auto& streamLeft : streamsLeft) { - auto iterRight = streamListRight.find(iterLeft->first); - if (iterRight != streamListRight.end()) + auto itRight = streamsRight.find(streamLeft.first); + if (itRight != streamsRight.end()) { - return StreamParser::execute(iterLeft ->second, //throw FileError - iterRight->second, + return StreamParser::execute(streamLeft.second, //throw FileError + itRight->second, fileNameLeft, fileNameRight); } @@ -732,38 +737,37 @@ void zen::saveLastSynchronousState(const BaseDirPair& baseDirObj) //throw FileEr removeFile(dbNameRightTmp); //throw FileError //(try to) load old database files... - StreamMapping streamListLeft; - StreamMapping streamListRight; + DbStreams streamsLeft; //list of session ID + DirInfo-stream + DbStreams streamsRight; - //read file data: list of session ID + DirInfo-stream - try { streamListLeft = ::loadStreams(dbNameLeft ); } + try { streamsLeft = ::loadStreams(dbNameLeft ); } catch (FileError&) {} - try { streamListRight = ::loadStreams(dbNameRight); } + try { streamsRight = ::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 - auto streamIterLeftOld = streamListLeft .cend(); - auto streamIterRightOld = streamListRight.cend(); - for (auto iterLeft = streamListLeft.begin(); iterLeft != streamListLeft.end(); ++iterLeft) + auto itStreamLeftOld = streamsLeft .cend(); + auto itStreamRightOld = streamsRight.cend(); + for (auto iterLeft = streamsLeft.begin(); iterLeft != streamsLeft.end(); ++iterLeft) { - auto iterRight = streamListRight.find(iterLeft->first); - if (iterRight != streamListRight.end()) + auto iterRight = streamsRight.find(iterLeft->first); + if (iterRight != streamsRight.end()) { - streamIterLeftOld = iterLeft; - streamIterRightOld = iterRight; + itStreamLeftOld = iterLeft; + itStreamRightOld = iterRight; break; } } //load last synchrounous state std::shared_ptr<InSyncDir> lastSyncState = std::make_shared<InSyncDir>(InSyncDir::DIR_STATUS_IN_SYNC); - if (streamIterLeftOld != streamListLeft .end() && - streamIterRightOld != streamListRight.end()) + if (itStreamLeftOld != streamsLeft .end() && + itStreamRightOld != streamsRight.end()) try { - lastSyncState = StreamParser::execute(streamIterLeftOld ->second, //throw FileError - streamIterRightOld->second, + lastSyncState = StreamParser::execute(itStreamLeftOld ->second, //throw FileError + itStreamRightOld->second, dbNameLeft, dbNameRight); } @@ -782,28 +786,28 @@ void zen::saveLastSynchronousState(const BaseDirPair& baseDirObj) //throw FileEr updatedStreamRight); //throw FileError //check if there is some work to do at all - if (streamIterLeftOld != streamListLeft .end() && updatedStreamLeft == streamIterLeftOld ->second && - streamIterRightOld != streamListRight.end() && updatedStreamRight == streamIterRightOld->second) + if (itStreamLeftOld != streamsLeft .end() && updatedStreamLeft == itStreamLeftOld ->second && + itStreamRightOld != streamsRight.end() && updatedStreamRight == itStreamRightOld->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 (streamIterLeftOld != streamListLeft.end()) - streamListLeft.erase(streamIterLeftOld); - if (streamIterRightOld != streamListRight.end()) - streamListRight.erase(streamIterRightOld); + if (itStreamLeftOld != streamsLeft.end()) + streamsLeft.erase(itStreamLeftOld); + if (itStreamRightOld != streamsRight.end()) + streamsRight.erase(itStreamRightOld); //create new session data const std::string sessionID = zen::generateGUID(); - streamListLeft [sessionID] = std::move(updatedStreamLeft); - streamListRight[sessionID] = std::move(updatedStreamRight); + streamsLeft [sessionID] = std::move(updatedStreamLeft); + streamsRight[sessionID] = std::move(updatedStreamRight); //write (temp-) files... zen::ScopeGuard guardTempFileLeft = zen::makeGuard([&] {zen::removeFile(dbNameLeftTmp); }); - saveStreams(streamListLeft, dbNameLeftTmp); //throw FileError + saveStreams(streamsLeft, dbNameLeftTmp); //throw FileError zen::ScopeGuard guardTempFileRight = zen::makeGuard([&] {zen::removeFile(dbNameRightTmp); }); - saveStreams(streamListRight, dbNameRightTmp); //throw FileError + saveStreams(streamsRight, dbNameRightTmp); //throw FileError //operation finished: rename temp files -> this should work transactionally: //if there were no write access, creation of temp files would have failed diff --git a/lib/db_file.h b/lib/db_file.h index b352ba5d..c432704d 100644 --- a/lib/db_file.h +++ b/lib/db_file.h @@ -14,12 +14,6 @@ namespace zen { const Zstring SYNC_DB_FILE_ENDING = Zstr(".ffs_db"); -enum InSyncType -{ - IN_SYNC_BINARY_EQUAL, //checked file content - IN_SYNC_ATTRIBUTES_EQUAL, //only "looks" like they're equal -}; - struct InSyncDescrFile //subset of FileDescriptor { InSyncDescrFile(const Int64& lastWriteTimeRawIn, @@ -41,19 +35,19 @@ struct InSyncDescrLink //artificial hierarchy of last synchronous state: struct InSyncFile { - InSyncFile(const InSyncDescrFile& l, const InSyncDescrFile& r, InSyncType type, const UInt64& fileSizeIn) : left(l), right(r), inSyncType(type), fileSize(fileSizeIn) {} + InSyncFile(const InSyncDescrFile& l, const InSyncDescrFile& r, CompareVariant cv, const UInt64& fileSizeIn) : left(l), right(r), cmpVar(cv), fileSize(fileSizeIn) {} InSyncDescrFile left; InSyncDescrFile right; - InSyncType inSyncType; + CompareVariant cmpVar; //the one active while finding "file in sync" UInt64 fileSize; //file size must be identical on both sides! }; struct InSyncSymlink { - InSyncSymlink(const InSyncDescrLink& l, const InSyncDescrLink& r, InSyncType type) : left(l), right(r), inSyncType(type) {} + InSyncSymlink(const InSyncDescrLink& l, const InSyncDescrLink& r, CompareVariant cv) : left(l), right(r), cmpVar(cv) {} InSyncDescrLink left; InSyncDescrLink right; - InSyncType inSyncType; + CompareVariant cmpVar; }; struct InSyncDir @@ -86,14 +80,14 @@ struct InSyncDir return dirs.insert(std::make_pair(shortName, InSyncDir(st))).first->second; } - void addFile(const Zstring& shortName, const InSyncDescrFile& dataL, const InSyncDescrFile& dataR, InSyncType type, const UInt64& fileSize) + void addFile(const Zstring& shortName, const InSyncDescrFile& dataL, const InSyncDescrFile& dataR, CompareVariant cmpVar, const UInt64& fileSize) { - files.insert(std::make_pair(shortName, InSyncFile(dataL, dataR, type, fileSize))); + files.insert(std::make_pair(shortName, InSyncFile(dataL, dataR, cmpVar, fileSize))); } - void addSymlink(const Zstring& shortName, const InSyncDescrLink& dataL, const InSyncDescrLink& dataR, InSyncType type) + void addSymlink(const Zstring& shortName, const InSyncDescrLink& dataL, const InSyncDescrLink& dataR, CompareVariant cmpVar) { - symlinks.insert(std::make_pair(shortName, InSyncSymlink(dataL, dataR, type))); + symlinks.insert(std::make_pair(shortName, InSyncSymlink(dataL, dataR, cmpVar))); } }; diff --git a/lib/dir_exist_async.h b/lib/dir_exist_async.h index 39ae6aff..7eb4827e 100644 --- a/lib/dir_exist_async.h +++ b/lib/dir_exist_async.h @@ -44,7 +44,8 @@ std::set<Zstring, LessFilename> getExistingDirsUpdating(const std::set<Zstring, }); std::set<Zstring, LessFilename> output; - const boost::system_time endTime = boost::get_system_time() + boost::posix_time::seconds(10); //10 sec should be enough even if Win32 waits much longer + //don't wait (almost) endlessly like win32 would on not existing network shares: + const boost::system_time endTime = boost::get_system_time() + boost::posix_time::seconds(20); //consider CD-rom insert or hard disk spin up time from sleep auto itDirname = dirnames.begin(); for (auto it = dirEx.begin(); it != dirEx.end(); (void)++it, ++itDirname) //void: prevent ADL from dragging in boost's ,-overload: "MSVC warning C4913: user defined binary operator ',' exists but no overload could convert all operands" diff --git a/lib/dir_lock.cpp b/lib/dir_lock.cpp index d7e3ba56..b58e018b 100644 --- a/lib/dir_lock.cpp +++ b/lib/dir_lock.cpp @@ -506,7 +506,7 @@ void releaseLock(const Zstring& lockfilename) //throw () { removeFile(lockfilename); //throw FileError } - catch (...) {} + catch (FileError&) {} } diff --git a/lib/hard_filter.cpp b/lib/hard_filter.cpp index 39cb07f6..687aecd8 100644 --- a/lib/hard_filter.cpp +++ b/lib/hard_filter.cpp @@ -65,52 +65,65 @@ const Zstring asteriskSepAsterisk = asteriskSep + asterisk; } -void addFilterEntry(const Zstring& filtername, std::vector<Zstring>& fileFilter, std::vector<Zstring>& directoryFilter) +void addFilterEntry(const Zstring& filterPhrase, std::vector<Zstring>& fileFilter, std::vector<Zstring>& directoryFilter) { - Zstring filterFormatted = filtername; - #if defined ZEN_WIN || defined ZEN_MAC //Windows does NOT distinguish between upper/lower-case + Zstring filterFormatted = filterPhrase; makeUpper(filterFormatted); #elif defined ZEN_LINUX + const Zstring& filterFormatted = filterPhrase; //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! - - //some syntactic sugar: - if (filterFormatted == asteriskSepAsterisk) // *\* := match everything except files directly in base directory - { - fileFilter. push_back(filterFormatted); - directoryFilter.push_back(asterisk); - return; - } - //more syntactic sugar: handle beginning of filtername - else if (startsWith(filterFormatted, asteriskSep)) // *\abc - { - 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.push_back(candidate); //only relevant for directory filtering - } - else if (endsWith(filterFormatted, sepAsterisk)) // abc\* + /* + phrase | action + +---------+-------- + | \blah | remove \ + | \*blah | remove \ + | \*\blah | remove \ + | \*\* | remove \ + +---------+-------- + | *blah | + | *\blah | -> add blah + | *\*blah | -> add *blah + +---------+-------- + | blah\ | remove \; directory only + | blah*\ | remove \; directory only + | blah\*\ | remove \; directory only + +---------+-------- + | blah* | + | blah\* | add blah for directory only + | blah*\* | add blah* for directory only + +---------+-------- + */ + auto processTail = [&fileFilter, &directoryFilter](const Zstring& phrase) { - fileFilter .push_back(filterFormatted); - directoryFilter.push_back(filterFormatted); + if (endsWith(phrase, FILE_NAME_SEPARATOR)) //only relevant for directory filtering + { + const Zstring dirPhrase = beforeLast(phrase, FILE_NAME_SEPARATOR); + if (!dirPhrase.empty()) + directoryFilter.push_back(dirPhrase); + } + else if (!phrase.empty()) + { + fileFilter .push_back(phrase); + directoryFilter.push_back(phrase); + if (endsWith(phrase, sepAsterisk)) // abc\* + { + const Zstring dirPhrase = beforeLast(phrase, sepAsterisk); + if (!dirPhrase.empty()) + directoryFilter.push_back(dirPhrase); + } + } + }; - const Zstring candidate = beforeLast(filterFormatted, FILE_NAME_SEPARATOR); - if (!candidate.empty()) - directoryFilter.push_back(candidate); //only relevant for directory filtering - } - else if (!filterFormatted.empty()) + if (startsWith(filterFormatted, FILE_NAME_SEPARATOR)) // \abc + processTail(afterFirst(filterFormatted, FILE_NAME_SEPARATOR)); + else { - fileFilter. push_back(filterFormatted); - directoryFilter.push_back(filterFormatted); + processTail(filterFormatted); + if (startsWith(filterFormatted, asteriskSep)) // *\abc + processTail(afterFirst(filterFormatted, asteriskSep)); } } diff --git a/lib/hard_filter.h b/lib/hard_filter.h index e47047a0..e721fe4f 100644 --- a/lib/hard_filter.h +++ b/lib/hard_filter.h @@ -4,8 +4,8 @@ // * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved * // ************************************************************************** -#ifndef FFS_FILTER_H_INCLUDED -#define FFS_FILTER_H_INCLUDED +#ifndef HARD_FILTER_H_825780275842758345 +#define HARD_FILTER_H_825780275842758345 #include <vector> #include <memory> @@ -267,5 +267,4 @@ HardFilter::FilterRef combineFilters(const HardFilter::FilterRef& first, } -#endif // FFS_FILTER_H_INCLUDED - +#endif //HARD_FILTER_H_825780275842758345 diff --git a/lib/icon_buffer.cpp b/lib/icon_buffer.cpp index b0874d83..e78b308e 100644 --- a/lib/icon_buffer.cpp +++ b/lib/icon_buffer.cpp @@ -102,13 +102,7 @@ public: return wxBitmap(fileIcon); #elif defined ZEN_LINUX -#if wxCHECK_VERSION(2, 9, 4) return wxBitmap(release()); //ownership passed! -#else - wxBitmap newIcon; - newIcon.SetPixbuf(release()); //ownership passed! - return newIcon; -#endif #elif defined ZEN_MAC ZEN_ON_SCOPE_EXIT(IconHolder().swap(*this)); //destroy after extraction @@ -358,7 +352,7 @@ IconHolder getAssociatedIcon(const Zstring& filename, IconBuffer::IconSize sz) 0, //DWORD dwFileAttributes, &fileInfo, //_Inout_ SHFILEINFO *psfi, sizeof(fileInfo), //UINT cbFileInfo, - SHGFI_SYSICONINDEX | SHGFI_ATTRIBUTES)) //UINT uFlags + SHGFI_SYSICONINDEX /*| SHGFI_ATTRIBUTES*/)) //UINT uFlags { (void)imgList; //imgList->Release(); //empiric study: crash on XP if we release this! Seems we do not own it... -> also no GDI leak on Win7 -> okay @@ -368,13 +362,13 @@ IconHolder getAssociatedIcon(const Zstring& filename, IconBuffer::IconSize sz) // for example, for use in a list view. Conversely, an HIMAGELIST can be cast as a pointer to an IImageList." //http://msdn.microsoft.com/en-us/library/windows/desktop/bb762185(v=vs.85).aspx -#ifndef SFGAO_LINK //Shobjidl.h +#ifdef __MINGW32__ //Shobjidl.h #define SFGAO_LINK 0x00010000L // Shortcut (link) or symlinks #endif warn_static("support SFGAO_GHOSTED or hidden?") - - const bool isLink = (fileInfo.dwAttributes & SFGAO_LINK) != 0; + //requires SHGFI_ATTRIBUTES + //const bool isLink = (fileInfo.dwAttributes & SFGAO_LINK) != 0; if (getIconByIndex && releaseImageData) if (const thumb::ImageData* imgData = getIconByIndex(fileInfo.iIcon, getThumbSizeType(sz))) @@ -398,7 +392,7 @@ IconHolder getAssociatedIcon(const Zstring& filename, IconBuffer::IconSize sz) { return IconHolder(new osx::ImageData(osx::getFileIcon(filename.c_str(), IconBuffer::getSize(sz)))); //throw SysError } - catch (zen::SysError&) {} + catch (zen::SysError&) { assert(false); } #endif return ::getGenericFileIcon(sz); //make sure this does not internally call getAssociatedIcon("someDefaultFile.txt")!!! => endless recursion! } @@ -454,7 +448,7 @@ class Buffer { public: //called by main and worker thread: - bool hasFileIcon(const Zstring& fileName) + bool hasFileIcon(const Zstring& fileName) const { boost::lock_guard<boost::mutex> dummy(lockIconList); return iconList.find(fileName) != iconList.end(); @@ -519,7 +513,7 @@ private: //- prohibit even wxBitmap() default constructor - better be safe than sorry! }; - boost::mutex lockIconList; + mutable boost::mutex lockIconList; std::map<Zstring, IconData, LessFilename> iconList; //shared resource; Zstring is thread-safe like an int std::queue<Zstring> iconSequence; //save sequence of buffer entry to delete oldest elements }; diff --git a/lib/norm_filter.h b/lib/norm_filter.h index 2d878da2..552931e2 100644 --- a/lib/norm_filter.h +++ b/lib/norm_filter.h @@ -66,8 +66,8 @@ bool isNullFilter(const FilterConfig& filterCfg) inline NormalizedFilter normalizeFilters(const FilterConfig& global, const FilterConfig& local) { - HardFilter::FilterRef globalName(new NameFilter(global.includeFilter, global.excludeFilter)); - HardFilter::FilterRef localName (new NameFilter(local .includeFilter, local .excludeFilter)); + HardFilter::FilterRef globalName = std::make_shared<NameFilter>(global.includeFilter, global.excludeFilter); + HardFilter::FilterRef localName = std::make_shared<NameFilter>(local .includeFilter, local .excludeFilter); SoftFilter globalTimeSize(global.timeSpan, global.unitTimeSpan, global.sizeMin, global.unitSizeMin, diff --git a/lib/osx_file_icon.mm b/lib/osx_file_icon.mm index 4db6642a..fb3c6490 100644 --- a/lib/osx_file_icon.mm +++ b/lib/osx_file_icon.mm @@ -65,7 +65,7 @@ osx::ImageData extractBytes(NSImage* nsImg, int requestedSize) //throw SysError; ::CGContextDrawImage(ctxRef, CGRectMake(0, 0, trgWidth, trgHeight), imgRef); //can this fail? not documented - //CGContextFlush(ctxRef); //"If you pass [...] a bitmap context, this function does nothing." + //::CGContextFlush(ctxRef); //"If you pass [...] a bitmap context, this function does nothing." osx::ImageData imgOut(trgWidth, trgHeight); diff --git a/lib/parallel_scan.cpp b/lib/parallel_scan.cpp index 2bac5690..433647ca 100644 --- a/lib/parallel_scan.cpp +++ b/lib/parallel_scan.cpp @@ -368,30 +368,24 @@ DirCallback::HandleLink DirCallback::onSymlink(const Zchar* shortName, const Zst { boost::this_thread::interruption_point(); + //update status information no matter whether object is excluded or not! + cfg.acb_.reportCurrentFile(fullName, cfg.threadID_); + switch (cfg.handleSymlinks_) { - case SYMLINK_IGNORE: + case SYMLINK_EXCLUDE: return LINK_SKIP; case SYMLINK_USE_DIRECTLY: - { - //update status information no matter whether object is excluded or not! - cfg.acb_.reportCurrentFile(fullName, cfg.threadID_); - - //------------------------------------------------------------------------------------ - const Zstring& relName = relNameParentPf_ + shortName; - - //apply filter before processing (use relative name!) - if (cfg.filterInstance->passFileFilter(relName)) //always use file filter: Link type may not be "stable" on Linux! + if (cfg.filterInstance->passFileFilter(relNameParentPf_ + shortName)) //always use file filter: Link type may not be "stable" on Linux! { output_.addSubLink(shortName, LinkDescriptor(details.lastWriteTime)); cfg.acb_.incItemsScanned(); //add 1 element to the progress indicator } - } - return LINK_SKIP; + return LINK_SKIP; case SYMLINK_FOLLOW_LINK: - return LINK_FOLLOW; + return cfg.filterInstance->passFileFilter(relNameParentPf_ + shortName) ? LINK_FOLLOW : LINK_SKIP; //filter broken symlinks before trying to follow them! } assert(false); @@ -546,32 +540,28 @@ void zen::fillBuffer(const std::set<DirectoryKey>& keysToRead, //in zen::ScopeGuard guardWorker = zen::makeGuard([&] { - std::for_each(worker.begin(), worker.end(), [](boost::thread& wt) { wt.interrupt(); }); //interrupt all at once first, then join - std::for_each(worker.begin(), worker.end(), [](boost::thread& wt) - { + for (boost::thread& wt : worker) + wt.interrupt(); //interrupt all at once first, then join + for (boost::thread& wt : worker) if (wt.joinable()) //= precondition of thread::join(), which throws an exception if violated! wt.join(); //in this context it is possible a thread is *not* joinable anymore due to the thread::timed_join() below! - }); }); auto acb = std::make_shared<AsyncCallback>(); //init worker threads - std::for_each(keysToRead.begin(), keysToRead.end(), - [&](const DirectoryKey& key) + for (const DirectoryKey& key : keysToRead) { assert(buf.find(key) == buf.end()); DirectoryValue& dirOutput = buf[key]; const long threadId = static_cast<long>(worker.size()); worker.emplace_back(WorkerThread(threadId, acb, key, dirOutput)); - }); + } //wait until done - for (auto it = worker.begin(); it != worker.end(); ++it) + for (boost::thread& wt : worker) { - boost::thread& wt = *it; - do { //update status diff --git a/lib/parse_lng.h b/lib/parse_lng.h index be47b66b..9aa62816 100644 --- a/lib/parse_lng.h +++ b/lib/parse_lng.h @@ -107,10 +107,10 @@ public: template <class Function, class Function2> void visitItems(Function onTrans, Function2 onPluralTrans) const //onTrans takes (const TranslationMap::value_type&), onPluralTrans takes (const TranslationPluralMap::value_type&) { - for (auto it = sequence.begin(); it != sequence.end(); ++it) - if (auto regular = dynamic_cast<const RegularItem*>(it->get())) + for (const auto& item : sequence) + if (auto regular = dynamic_cast<const RegularItem*>(item.get())) onTrans(regular->value); - else if (auto plural = dynamic_cast<const PluralItem*>(it->get())) + else if (auto plural = dynamic_cast<const PluralItem*>(item.get())) onPluralTrans(plural->value); else assert(false); } @@ -637,11 +637,10 @@ std::string generateLng(const TranslationUnorderedList& in, const TransHeader& h out += KnownTokens::text(Token::TK_SRC_END) + '\n'; out += KnownTokens::text(Token::TK_TRG_BEGIN); - if (!forms.empty()) out += '\n'; + out += '\n'; - for (PluralForms::const_iterator j = forms.begin(); j != forms.end(); ++j) + for (std::string plForm : forms) { - std::string plForm = *j; formatMultiLineText(plForm); out += KnownTokens::text(Token::TK_PLURAL_BEGIN); diff --git a/lib/process_xml.cpp b/lib/process_xml.cpp index 49e4c711..4640e472 100644 --- a/lib/process_xml.cpp +++ b/lib/process_xml.cpp @@ -14,15 +14,14 @@ using namespace zen; using namespace xmlAccess; //functionally needed for correct overload resolution!!! - using namespace std::rel_ops; namespace { //------------------------------------------------------------------------------------------------------------------------------- const int XML_FORMAT_VER_GLOBAL = 1; -const int XML_FORMAT_VER_FFS_GUI = 1; -const int XML_FORMAT_VER_FFS_BATCH = 1; +const int XML_FORMAT_VER_FFS_GUI = 2; +const int XML_FORMAT_VER_FFS_BATCH = 2; //------------------------------------------------------------------------------------------------------------------------------- } @@ -49,7 +48,7 @@ XmlType xmlAccess::getXmlType(const Zstring& filename) //throw() { try { - //do NOT use zen::loadStream as it will superfluously load even huge files! + //do NOT use zen::loadStream as it will needlessly load even huge files! XmlDoc doc = loadXmlDocument(filename); //throw FfsXmlError, quick exit if file is not an FFS XML return ::getXmlType(doc); } @@ -78,6 +77,7 @@ void setXmlType(XmlDoc& doc, XmlType type) //throw() break; } } + //################################################################################################################ Zstring xmlAccess::getGlobalConfigFile() @@ -110,8 +110,8 @@ xmlAccess::XmlGuiConfig xmlAccess::convertBatchToGui(const xmlAccess::XmlBatchCo switch (batchCfg.handleError) { - case ON_ERROR_EXIT: case ON_ERROR_POPUP: + case ON_ERROR_ABORT: output.handleError = ON_GUIERROR_POPUP; break; case ON_ERROR_IGNORE: @@ -186,10 +186,10 @@ void writeText(const CompareVariant& value, std::string& output) switch (value) { case zen::CMP_BY_TIME_SIZE: - output = "ByTimeAndSize"; + output = "TimeAndSize"; break; case zen::CMP_BY_CONTENT: - output = "ByContent"; + output = "Content"; break; } } @@ -199,12 +199,19 @@ bool readText(const std::string& input, CompareVariant& value) { std::string tmp = input; zen::trim(tmp); - if (tmp == "ByTimeAndSize") + warn_static("remove after migration. 2013.08.20") + if (tmp == "ByTimeAndSize") //obsolete value = zen::CMP_BY_TIME_SIZE; - else if (tmp == "ByContent") + else if (tmp == "ByContent") //obsolete value = zen::CMP_BY_CONTENT; else - return false; + + if (tmp == "TimeAndSize") + value = zen::CMP_BY_TIME_SIZE; + else if (tmp == "Content") + value = zen::CMP_BY_CONTENT; + else + return false; return true; } @@ -251,12 +258,12 @@ void writeText(const OnError& value, std::string& output) case ON_ERROR_IGNORE: output = "Ignore"; break; - case ON_ERROR_EXIT: - output = "Exit"; - break; case ON_ERROR_POPUP: output = "Popup"; break; + case ON_ERROR_ABORT: + output = "Abort"; + break; } } @@ -265,14 +272,19 @@ bool readText(const std::string& input, OnError& value) { std::string tmp = input; zen::trim(tmp); - if (tmp == "Ignore") - value = ON_ERROR_IGNORE; - else if (tmp == "Exit") - value = ON_ERROR_EXIT; - else if (tmp == "Popup") - value = ON_ERROR_POPUP; + warn_static("remove after migration. 2013.08.20") + if (tmp == "Exit") //obsolete + value = ON_ERROR_ABORT; else - return false; + + if (tmp == "Ignore") + value = ON_ERROR_IGNORE; + else if (tmp == "Popup") + value = ON_ERROR_POPUP; + else if (tmp == "Abort") + value = ON_ERROR_ABORT; + else + return false; return true; } @@ -372,7 +384,7 @@ bool readText(const std::string& input, DeletionPolicy& value) else if (tmp == "MoveToCustomDirectory")//obsolete name value = DELETE_TO_VERSIONING; else - //------------------ + if (tmp == "Permanent") value = DELETE_PERMANENTLY; else if (tmp == "RecycleBin") @@ -390,14 +402,14 @@ void writeText(const SymLinkHandling& value, std::string& output) { switch (value) { - case SYMLINK_IGNORE: - output = "Ignore"; + case SYMLINK_EXCLUDE: + output = "Exclude"; break; case SYMLINK_USE_DIRECTLY: - output = "UseDirectly"; + output = "Direct"; break; case SYMLINK_FOLLOW_LINK: - output = "FollowLink"; + output = "Follow"; break; } } @@ -407,58 +419,23 @@ bool readText(const std::string& input, SymLinkHandling& value) { std::string tmp = input; zen::trim(tmp); - if (tmp == "Ignore") - value = SYMLINK_IGNORE; - else if (tmp == "UseDirectly") + warn_static("remove after migration. 2013.08.20") + if (tmp == "UseDirectly") //obsolete! value = SYMLINK_USE_DIRECTLY; - else if (tmp == "FollowLink") + else if (tmp == "FollowLink") //obsolete! value = SYMLINK_FOLLOW_LINK; + else if (tmp == "Ignore") //obsolete! + value = SYMLINK_EXCLUDE; else - return false; - return true; -} - -template <> inline -void writeText(const UnitTime& value, std::string& output) -{ - switch (value) - { - case UTIME_NONE: - output = "Inactive"; - break; - case UTIME_TODAY: - output = "Today"; - break; - case UTIME_THIS_MONTH: - output = "Month"; - break; - case UTIME_THIS_YEAR: - output = "Year"; - break; - case UTIME_LAST_X_DAYS: - output = "x-days"; - break; - } -} - -template <> inline -bool readText(const std::string& input, UnitTime& value) -{ - std::string tmp = input; - zen::trim(tmp); - if (tmp == "Inactive") - value = UTIME_NONE; - else if (tmp == "Today") - value = UTIME_TODAY; - 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; + if (tmp == "Exclude") + value = SYMLINK_EXCLUDE; + else if (tmp == "Direct") + value = SYMLINK_USE_DIRECTLY; + else if (tmp == "Follow") + value = SYMLINK_FOLLOW_LINK; + else + return false; return true; } @@ -557,7 +534,7 @@ void writeText(const UnitSize& value, std::string& output) switch (value) { case USIZE_NONE: - output = "Inactive"; + output = "None"; break; case USIZE_BYTE: output = "Byte"; @@ -576,19 +553,71 @@ bool readText(const std::string& input, UnitSize& value) { std::string tmp = input; zen::trim(tmp); - if (tmp == "Inactive") + warn_static("remove after migration. 2013.08.20") + if (tmp == "Inactive") //obsolete! value = USIZE_NONE; - else if (tmp == "Byte") - value = USIZE_BYTE; - else if (tmp == "KB") - value = USIZE_KB; - else if (tmp == "MB") - value = USIZE_MB; else - return false; + + if (tmp == "None") + value = USIZE_NONE; + else if (tmp == "Byte") + value = USIZE_BYTE; + else if (tmp == "KB") + value = USIZE_KB; + else if (tmp == "MB") + value = USIZE_MB; + else + return false; return true; } +template <> inline +void writeText(const UnitTime& value, std::string& output) +{ + switch (value) + { + case UTIME_NONE: + output = "None"; + break; + case UTIME_TODAY: + output = "Today"; + break; + case UTIME_THIS_MONTH: + output = "Month"; + break; + case UTIME_THIS_YEAR: + output = "Year"; + break; + case UTIME_LAST_X_DAYS: + output = "x-days"; + break; + } +} + +template <> inline +bool readText(const std::string& input, UnitTime& value) +{ + std::string tmp = input; + zen::trim(tmp); + warn_static("remove after migration. 2013.08.20") + if (tmp == "Inactive") //obsolete! + value = UTIME_NONE; + else + + if (tmp == "None") + value = UTIME_NONE; + else if (tmp == "Today") + value = UTIME_TODAY; + 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; +} template <> inline void writeText(const VersioningStyle& value, std::string& output) @@ -599,7 +628,7 @@ void writeText(const VersioningStyle& value, std::string& output) output = "Replace"; break; case VER_STYLE_ADD_TIMESTAMP: - output = "AddTimeStamp"; + output = "TimeStamp"; break; } } @@ -609,12 +638,17 @@ bool readText(const std::string& input, VersioningStyle& value) { std::string tmp = input; zen::trim(tmp); - if (tmp == "Replace") - value = VER_STYLE_REPLACE; - else if (tmp == "AddTimeStamp") + warn_static("remove after migration. 2013.08.20") + if (tmp == "AddTimeStamp") //obsolete value = VER_STYLE_ADD_TIMESTAMP; else - return false; + + if (tmp == "Replace") + value = VER_STYLE_REPLACE; + else if (tmp == "TimeStamp") + value = VER_STYLE_ADD_TIMESTAMP; + else + return false; return true; } @@ -624,8 +658,8 @@ void writeText(const DirectionConfig::Variant& value, std::string& output) { switch (value) { - case DirectionConfig::AUTOMATIC: - output = "Automatic"; + case DirectionConfig::TWOWAY: + output = "TwoWay"; break; case DirectionConfig::MIRROR: output = "Mirror"; @@ -644,16 +678,21 @@ bool readText(const std::string& input, DirectionConfig::Variant& value) { std::string tmp = input; zen::trim(tmp); - if (tmp == "Automatic") - value = DirectionConfig::AUTOMATIC; - else if (tmp == "Mirror") - value = DirectionConfig::MIRROR; - else if (tmp == "Update") - value = DirectionConfig::UPDATE; - else if (tmp == "Custom") - value = DirectionConfig::CUSTOM; + warn_static("remove after migration. 2013.08.20") + if (tmp == "Automatic") //obsolete! + value = DirectionConfig::TWOWAY; else - return false; + + if (tmp == "TwoWay") + value = DirectionConfig::TWOWAY; + else if (tmp == "Mirror") + value = DirectionConfig::MIRROR; + else if (tmp == "Update") + value = DirectionConfig::UPDATE; + else if (tmp == "Custom") + value = DirectionConfig::CUSTOM; + else + return false; return true; } @@ -781,6 +820,10 @@ void readConfig(const XmlIn& in, DirectionConfig& directCfg) inCustDir["RightNewer"](directCfg.custom.rightNewer); inCustDir["Different" ](directCfg.custom.different); inCustDir["Conflict" ](directCfg.custom.conflict); + + warn_static("remove check after migration. 2013.08.17") + if (in["DetectMovedFiles"]) //new value: remove check + in["DetectMovedFiles"](directCfg.detectMovedFiles); } @@ -1052,7 +1095,7 @@ void readConfig(const XmlIn& in, XmlGlobalSettings& config) //########################################################### inWnd["ViewFilterDefault"](config.gui.viewFilterDefault); - inWnd["Perspective" ](config.gui.guiPerspectiveLast); + inWnd["Perspective2" ](config.gui.guiPerspectiveLast); std::vector<Zstring> tmp = splitFilterByLines(config.gui.defaultExclusionFilter); //default value inGui["DefaultExclusionFilter"](tmp); @@ -1236,6 +1279,8 @@ void writeConfig(const DirectionConfig& directCfg, XmlOut& out) outCustDir["RightNewer"](directCfg.custom.rightNewer); outCustDir["Different" ](directCfg.custom.different); outCustDir["Conflict" ](directCfg.custom.conflict); + + out["DetectMovedFiles"](directCfg.detectMovedFiles); } @@ -1431,7 +1476,7 @@ void writeConfig(const XmlGlobalSettings& config, XmlOut& out) //########################################################### outWnd["ViewFilterDefault"](config.gui.viewFilterDefault); - outWnd["Perspective" ](config.gui.guiPerspectiveLast); + outWnd["Perspective2" ](config.gui.guiPerspectiveLast); outGui["DefaultExclusionFilter"](splitFilterByLines(config.gui.defaultExclusionFilter)); diff --git a/lib/process_xml.h b/lib/process_xml.h index b189e51f..85f2d461 100644 --- a/lib/process_xml.h +++ b/lib/process_xml.h @@ -29,9 +29,9 @@ XmlType getXmlType(const Zstring& filename); //throw() enum OnError { - ON_ERROR_POPUP, ON_ERROR_IGNORE, - ON_ERROR_EXIT + ON_ERROR_POPUP, + ON_ERROR_ABORT }; enum OnGuiError diff --git a/lib/resolve_path.cpp b/lib/resolve_path.cpp index f4049590..083b1007 100644 --- a/lib/resolve_path.cpp +++ b/lib/resolve_path.cpp @@ -115,12 +115,8 @@ private: //================================================================================================ //SHGetKnownFolderPath: API available only with Windows Vista and later: -#ifdef __MINGW32__ //MinGW is clueless about Vista... -#define REFKNOWNFOLDERID const GUID& +#ifdef __MINGW32__ #define KF_FLAG_DONT_VERIFY 0x00004000 - const GUID FOLDERID_Downloads = { 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b} }; - const GUID FOLDERID_PublicDownloads = { 0x3d644c9b, 0x1fb8, 0x4f30, { 0x9b, 0x45, 0xf6, 0x70, 0x23, 0x5f, 0x79, 0xc0} }; - const GUID FOLDERID_QuickLaunch = { 0x52a4f021, 0x7b75, 0x48a9, { 0x9f, 0x6b, 0x4b, 0x87, 0xa2, 0x10, 0xbc, 0x8f} }; #endif typedef HRESULT (STDAPICALLTYPE* SHGetKnownFolderPathFunc)(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR* ppszPath); const SysDllFun<SHGetKnownFolderPathFunc> shGetKnownFolderPath(L"Shell32.dll", "SHGetKnownFolderPath"); @@ -598,7 +594,7 @@ void zen::loginNetworkShare(const Zstring& dirnameOrig, bool allowUserInteractio user account: <Domain>\<user> e.g. WIN-XP\ZenJu network share: \\<server>\<share> e.g. \\WIN-XP\test - Windows Command Line: + Windows Command Line: - list *all* active network connections, including deviceless ones which are hidden in Explorer: net use - delete active connection: diff --git a/lib/shadow.cpp b/lib/shadow.cpp index 71372270..808b3b68 100644 --- a/lib/shadow.cpp +++ b/lib/shadow.cpp @@ -53,19 +53,19 @@ public: //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(_("Cannot access Volume Shadow Copy Service."), + throw FileError(_("Cannot access the Volume Shadow Copy Service."), _("Please use FreeFileSync 64-bit version to create shadow copies on this system.")); //check if shadow copy dll was loaded correctly if (!createShadowCopy || !releaseShadowCopy || !getShadowVolume || !getLastError) - throw FileError(_("Cannot access Volume Shadow Copy Service."), + throw FileError(_("Cannot access the Volume Shadow Copy Service."), replaceCpy(_("Cannot load file %x."), L"%x", fmtFileName(getDllName()))); //--------------------------------------------------------------------------------------------------------- //start volume shadow copy service: backupHandle = createShadowCopy(volumeNamePf.c_str()); if (!backupHandle) - throw FileError(_("Cannot access Volume Shadow Copy Service."), + throw FileError(_("Cannot access the Volume Shadow Copy Service."), getLastError() + std::wstring(L" Volume: ") + fmtFileName(volumeNamePf)); shadowVolPf = appendSeparator(getShadowVolume(backupHandle)); //shadowVolName NEVER has a trailing backslash diff --git a/lib/soft_filter.h b/lib/soft_filter.h index 1073cd43..010a8913 100644 --- a/lib/soft_filter.h +++ b/lib/soft_filter.h @@ -18,7 +18,7 @@ namespace zen Semantics of SoftFilter: 1. It potentially may match only one side => it MUST NOT be applied while traversing a single folder to avoid mismatches 2. => it is applied after traversing and just marks rows, (NO deletions after comparison are allowed) -3. => equivalent to a user temporarily (de-)selecting rows -> not relevant for <Automatic>-mode! ;) +3. => equivalent to a user temporarily (de-)selecting rows => not relevant for <two way>-mode! */ class SoftFilter @@ -61,14 +61,6 @@ private: - - - - - - - - // ----------------------- implementation ----------------------- namespace zen { diff --git a/lib/versioning.cpp b/lib/versioning.cpp index a6458196..65373499 100644 --- a/lib/versioning.cpp +++ b/lib/versioning.cpp @@ -120,23 +120,22 @@ void moveItemToVersioning(const Zstring& fullName, //throw FileError //move source to target across volumes -//no need to check if: - super-directories of target exist - source exists +//no need to check if: - super-directories of target exist - source exists: done by moveItemToVersioning() //if target already exists, it is overwritten, even if it is a different type, e.g. a directory! template <class Function> void moveObject(const Zstring& sourceFile, //throw FileError const Zstring& targetFile, Function copyDelete) //throw FileError; fallback if move failed { - assert(!dirExists(sourceFile) || symlinkExists(sourceFile)); //we process files and symlinks only + assert(fileExists(sourceFile) || symlinkExists(sourceFile) || !somethingExists(sourceFile)); //we process files and symlinks only auto removeTarget = [&] { //remove target object - if (fileExists(targetFile)) //file or symlink - removeFile(targetFile); //throw FileError - else if (dirExists(targetFile)) //directory or symlink + if (dirExists(targetFile)) //directory or dir-symlink removeDirectory(targetFile); //throw FileError; we do not expect targetFile to be a directory in general => no callback required - //else assert(false); -> may simply not exist if ErrorDifferentVolume! + else //file or (broken) file-symlink + removeFile(targetFile); //throw FileError }; //first try to move directly without copying @@ -212,17 +211,10 @@ private: virtual HandleLink onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) { - switch (getSymlinkType(fullName)) - { - case SYMLINK_TYPE_DIR: - dirs_.push_back(shortName); - break; - - case SYMLINK_TYPE_FILE: - case SYMLINK_TYPE_UNKNOWN: - files_.push_back(shortName); - break; - } + if (dirExists(fullName)) //dir symlink + dirs_.push_back(shortName); + else //file symlink, broken symlink + files_.push_back(shortName); return LINK_SKIP; } diff --git a/lib/xml_base.cpp b/lib/xml_base.cpp index 123060f4..f504d19a 100644 --- a/lib/xml_base.cpp +++ b/lib/xml_base.cpp @@ -101,7 +101,7 @@ void xmlAccess::saveXmlDocument(const zen::XmlDoc& doc, const Zstring& filename) FileOutput outputFile(filename, FileOutput::ACC_OVERWRITE); //throw FileError outputFile.write(stream.c_str(), stream.length()); // } - catch (const FileError& error) //more detailed error messages than with wxWidgets + catch (const FileError& error) { throw FfsXmlError(error.toString()); } diff --git a/structures.cpp b/structures.cpp index 3bc2c181..e5dc08fd 100644 --- a/structures.cpp +++ b/structures.cpp @@ -32,7 +32,7 @@ std::wstring zen::getVariantName(DirectionConfig::Variant var) { switch (var) { - case DirectionConfig::AUTOMATIC: + case DirectionConfig::TWOWAY: return L"<- " + _("Two way") + L" ->"; case DirectionConfig::MIRROR: return _("Mirror") + L" ->>"; @@ -51,7 +51,7 @@ DirectionSet zen::extractDirections(const DirectionConfig& cfg) DirectionSet output; switch (cfg.var) { - case DirectionConfig::AUTOMATIC: + case DirectionConfig::TWOWAY: throw std::logic_error("there are no predefined directions for automatic mode!"); case DirectionConfig::MIRROR: @@ -80,7 +80,26 @@ DirectionSet zen::extractDirections(const DirectionConfig& cfg) } -DirectionSet zen::getTwoWaySet() +bool zen::detectMovedFilesSelectable(const DirectionConfig& cfg) +{ + if (cfg.var == DirectionConfig::TWOWAY) + return false; //moved files are always detected since we have the database file anyway + + const DirectionSet tmp = zen::extractDirections(cfg); + return (tmp.exLeftSideOnly == SyncDirection::RIGHT && + tmp.exRightSideOnly == SyncDirection::RIGHT) || + (tmp.exLeftSideOnly == SyncDirection::LEFT&& + tmp.exRightSideOnly == SyncDirection::LEFT); +} + + +bool zen::detectMovedFilesEnabled(const DirectionConfig& cfg) +{ + return detectMovedFilesSelectable(cfg) ? cfg.detectMovedFiles : cfg.var == DirectionConfig::TWOWAY; +} + + +DirectionSet zen::getTwoWayUpdateSet() { DirectionSet output; output.exLeftSideOnly = SyncDirection::RIGHT; @@ -100,10 +119,10 @@ std::wstring MainConfiguration::getCompVariantName() const cmpConfig.compareVar; //fallback to main sync cfg //test if there's a deviating variant within the additional folder pairs - for (auto fp = additionalPairs.begin(); fp != additionalPairs.end(); ++fp) + for (const FolderPairEnh& fp : additionalPairs) { - const CompareVariant thisVariant = fp->altCmpConfig.get() ? - fp->altCmpConfig->compareVar : + const CompareVariant thisVariant = fp.altCmpConfig.get() ? + fp.altCmpConfig->compareVar : cmpConfig.compareVar; //fallback to main sync cfg if (thisVariant != firstVariant) return _("Multiple..."); @@ -121,10 +140,10 @@ std::wstring MainConfiguration::getSyncVariantName() const syncCfg.directionCfg.var; //fallback to main sync cfg //test if there's a deviating variant within the additional folder pairs - for (auto fp = additionalPairs.begin(); fp != additionalPairs.end(); ++fp) + for (const FolderPairEnh& fp : additionalPairs) { - const DirectionConfig::Variant thisVariant = fp->altSyncConfig.get() ? - fp->altSyncConfig->directionCfg.var : + const DirectionConfig::Variant thisVariant = fp.altSyncConfig.get() ? + fp.altSyncConfig->directionCfg.var : syncCfg.directionCfg.var; if (thisVariant != firstVariant) return _("Multiple..."); @@ -317,28 +336,14 @@ void zen::resolveUnits(size_t timeSpan, UnitTime unitTimeSpan, namespace { -bool sameFilter(const std::vector<FolderPairEnh>& folderPairs) -{ - if (folderPairs.empty()) - return true; - - for (std::vector<FolderPairEnh>::const_iterator fp = folderPairs.begin(); fp != folderPairs.end(); ++fp) - if (!(fp->localFilter == folderPairs[0].localFilter)) - return false; - - return true; -} - - FilterConfig mergeFilterConfig(const FilterConfig& global, const FilterConfig& local) { FilterConfig out = local; //hard filter - - //pragmatism: if both global and local include filter contain data, only local filter is preserved if (out.includeFilter == FilterConfig().includeFilter) out.includeFilter = global.includeFilter; + //else: if both global and local include filter contain data, only local filter is preserved trim(out.excludeFilter, true, false); out.excludeFilter = global.excludeFilter + Zstr("\n") + out.excludeFilter; @@ -386,9 +391,14 @@ FilterConfig mergeFilterConfig(const FilterConfig& global, const FilterConfig& l inline -bool isEmpty(const FolderPairEnh& fp) +bool effectivelyEmpty(const FolderPairEnh& fp) { - return fp == FolderPairEnh(); + auto isEmpty = [](Zstring dirname) + { + trim(dirname); + return dirname.empty(); + }; + return isEmpty(fp.leftDirectory) && isEmpty(fp.rightDirectory); } } @@ -404,28 +414,28 @@ MainConfiguration zen::merge(const std::vector<MainConfiguration>& mainCfgs) //merge folder pair config std::vector<FolderPairEnh> fpMerged; - for (auto iterMain = mainCfgs.begin(); iterMain != mainCfgs.end(); ++iterMain) + for (const MainConfiguration& mainCfg : mainCfgs) { std::vector<FolderPairEnh> fpTmp; - //list non-empty local configurations - if (!isEmpty(iterMain->firstPair)) - fpTmp.push_back(iterMain->firstPair); - std::copy_if(iterMain->additionalPairs.begin(), iterMain->additionalPairs.end(), std::back_inserter(fpTmp), - [](const FolderPairEnh& fp) { return !isEmpty(fp); }); + //skip empty folder pairs + if (!effectivelyEmpty(mainCfg.firstPair)) + fpTmp.push_back(mainCfg.firstPair); + for (const FolderPairEnh& fp : mainCfg.additionalPairs) + if (!effectivelyEmpty(fp)) + fpTmp.push_back(fp); //move all configuration down to item level - for (std::vector<FolderPairEnh>::iterator fp = fpTmp.begin(); fp != fpTmp.end(); ++fp) + for (FolderPairEnh& fp : fpTmp) { - if (!fp->altCmpConfig.get()) - fp->altCmpConfig = std::make_shared<CompConfig>(iterMain->cmpConfig); + if (!fp.altCmpConfig.get()) + fp.altCmpConfig = std::make_shared<CompConfig>(mainCfg.cmpConfig); - if (!fp->altSyncConfig.get()) - fp->altSyncConfig = std::make_shared<SyncConfig>(iterMain->syncCfg); + if (!fp.altSyncConfig.get()) + fp.altSyncConfig = std::make_shared<SyncConfig>(mainCfg.syncCfg); - fp->localFilter = mergeFilterConfig(iterMain->globalFilter, fp->localFilter); + fp.localFilter = mergeFilterConfig(mainCfg.globalFilter, fp.localFilter); } - fpMerged.insert(fpMerged.end(), fpTmp.begin(), fpTmp.end()); } @@ -438,23 +448,24 @@ MainConfiguration zen::merge(const std::vector<MainConfiguration>& mainCfgs) //find out which comparison and synchronization setting are used most often and use them as new "header" std::vector<std::pair<CompConfig, int>> cmpCfgStat; std::vector<std::pair<SyncConfig, int>> syncCfgStat; - for (auto fp = fpMerged.begin(); fp != fpMerged.end(); ++fp) //rather inefficient algorithm, but it does not require a less-than operator! + for (const FolderPairEnh& fp : fpMerged) { + //rather inefficient algorithm, but it does not require a less-than operator: { - const CompConfig& cmpCfg = *fp->altCmpConfig; + const CompConfig& cmpCfg = *fp.altCmpConfig; auto it = std::find_if(cmpCfgStat.begin(), cmpCfgStat.end(), - [&](const std::pair<CompConfig, int>& entry) { return entry.first == cmpCfg; }); + [&](const std::pair<CompConfig, int>& entry) { return effectivelyEqual(entry.first, cmpCfg); }); if (it == cmpCfgStat.end()) cmpCfgStat.push_back(std::make_pair(cmpCfg, 1)); else ++(it->second); } { - const SyncConfig& syncCfg = *fp->altSyncConfig; + const SyncConfig& syncCfg = *fp.altSyncConfig; auto it = std::find_if(syncCfgStat.begin(), syncCfgStat.end(), - [&](const std::pair<SyncConfig, int>& entry) { return entry.first == syncCfg; }); + [&](const std::pair<SyncConfig, int>& entry) { return effectivelyEqual(entry.first, syncCfg); }); if (it == syncCfgStat.end()) syncCfgStat.push_back(std::make_pair(syncCfg, 1)); else @@ -462,7 +473,7 @@ MainConfiguration zen::merge(const std::vector<MainConfiguration>& mainCfgs) } } - //set most-used comparison and synchronization settions as new header options + //set most-used comparison and synchronization settings as new header options const CompConfig cmpCfgHead = cmpCfgStat.empty() ? CompConfig() : std::max_element(cmpCfgStat.begin(), cmpCfgStat.end(), [](const std::pair<CompConfig, int>& lhs, const std::pair<CompConfig, int>& rhs) { return lhs.second < rhs.second; })->first; @@ -473,24 +484,24 @@ MainConfiguration zen::merge(const std::vector<MainConfiguration>& mainCfgs) //######################################################################################################################## FilterConfig globalFilter; - const bool equalFilters = sameFilter(fpMerged); - if (equalFilters) + const bool allFiltersEqual = std::all_of(fpMerged.begin(), fpMerged.end(), [&](const FolderPairEnh& fp) { return fp.localFilter == fpMerged[0].localFilter; }); + if (allFiltersEqual) globalFilter = fpMerged[0].localFilter; //strip redundancy... - for (auto fp = fpMerged.begin(); fp != fpMerged.end(); ++fp) + for (FolderPairEnh& fp : fpMerged) { //if local config matches output global config we don't need local one - if (fp->altCmpConfig && - *fp->altCmpConfig == cmpCfgHead) - fp->altCmpConfig.reset(); + if (fp.altCmpConfig && + effectivelyEqual(*fp.altCmpConfig, cmpCfgHead)) + fp.altCmpConfig.reset(); - if (fp->altSyncConfig && - *fp->altSyncConfig == syncCfgHead) - fp->altSyncConfig.reset(); + if (fp.altSyncConfig && + effectivelyEqual(*fp.altSyncConfig, syncCfgHead)) + fp.altSyncConfig.reset(); - if (equalFilters) //use global filter in this case - fp->localFilter = FilterConfig(); + if (allFiltersEqual) //use global filter in this case + fp.localFilter = FilterConfig(); } //final assembly @@ -501,6 +512,5 @@ MainConfiguration zen::merge(const std::vector<MainConfiguration>& mainCfgs) cfgOut.firstPair = fpMerged[0]; cfgOut.additionalPairs.assign(fpMerged.begin() + 1, fpMerged.end()); cfgOut.onCompletion = mainCfgs[0].onCompletion; - return cfgOut; } diff --git a/structures.h b/structures.h index 1d3f5d4c..4b4cdb8a 100644 --- a/structures.h +++ b/structures.h @@ -25,7 +25,7 @@ std::wstring getVariantName(CompareVariant var); enum SymLinkHandling { - SYMLINK_IGNORE, + SYMLINK_EXCLUDE, SYMLINK_USE_DIRECTLY, SYMLINK_FOLLOW_LINK }; @@ -98,7 +98,7 @@ enum SyncOperation SO_UNRESOLVED_CONFLICT }; -std::wstring getSymbol (SyncOperation op); //method used for exporting .csv file only! +std::wstring getSymbol(SyncOperation op); //method used for exporting .csv file only! struct DirectionSet @@ -119,7 +119,7 @@ struct DirectionSet SyncDirection conflict; }; -DirectionSet getTwoWaySet(); +DirectionSet getTwoWayUpdateSet(); inline bool operator==(const DirectionSet& lhs, const DirectionSet& rhs) @@ -136,39 +136,49 @@ struct DirectionConfig //technical representation of sync-config { enum Variant { - AUTOMATIC, //use sync-database to determine directions + TWOWAY, //use sync-database to determine directions MIRROR, //predefined UPDATE, // CUSTOM //use custom directions }; - DirectionConfig() : var(AUTOMATIC) {} + DirectionConfig() : var(TWOWAY), detectMovedFiles(false) {} Variant var; - - //custom sync directions - DirectionSet custom; + DirectionSet custom; //custom sync directions + bool detectMovedFiles; //dependent from Variant: e.g. always active for DirectionConfig::TWOWAY! => use functions below for evaluation! }; inline bool operator==(const DirectionConfig& lhs, const DirectionConfig& rhs) { - return lhs.var == rhs.var && - (lhs.var != DirectionConfig::CUSTOM || lhs.custom == rhs.custom); //directions are only relevant if variant "custom" is active + return lhs.var == rhs.var && + lhs.custom == rhs.custom && + lhs.detectMovedFiles == rhs.detectMovedFiles; + //adapt effectivelyEqual() on changes, too! } -//get sync directions: DON'T call for variant AUTOMATIC! -DirectionSet extractDirections(const DirectionConfig& cfg); +bool detectMovedFilesSelectable(const DirectionConfig& cfg); +bool detectMovedFilesEnabled (const DirectionConfig& cfg); + +DirectionSet extractDirections(const DirectionConfig& cfg); //get sync directions: DON'T call for DirectionConfig::TWOWAY! std::wstring getVariantName(DirectionConfig::Variant var); +inline +bool effectivelyEqual(const DirectionConfig& lhs, const DirectionConfig& rhs) +{ + return (lhs.var == DirectionConfig::TWOWAY) == (rhs.var == DirectionConfig::TWOWAY) && //either both two-way or none + (lhs.var == DirectionConfig::TWOWAY || extractDirections(lhs) == extractDirections(rhs)) && + detectMovedFilesEnabled(lhs) == detectMovedFilesEnabled(rhs); +} struct CompConfig { CompConfig() : compareVar(CMP_BY_TIME_SIZE), - handleSymlinks(SYMLINK_IGNORE) {} + handleSymlinks(SYMLINK_EXCLUDE) {} CompareVariant compareVar; SymLinkHandling handleSymlinks; @@ -181,6 +191,9 @@ bool operator==(const CompConfig& lhs, const CompConfig& rhs) lhs.handleSymlinks == rhs.handleSymlinks; } +inline +bool effectivelyEqual(const CompConfig& lhs, const CompConfig& rhs) { return lhs == rhs; } //no change in behavior + enum DeletionPolicy { @@ -211,10 +224,22 @@ struct SyncConfig //int versionCountLimit; //max versions per file (DELETE_TO_VERSIONING); < 0 := no limit }; + inline bool operator==(const SyncConfig& lhs, const SyncConfig& rhs) { - return lhs.directionCfg == rhs.directionCfg && + return lhs.directionCfg == rhs.directionCfg && + lhs.handleDeletion == rhs.handleDeletion && + lhs.versioningStyle == rhs.versioningStyle && + lhs.versioningDirectory == rhs.versioningDirectory; + //adapt effectivelyEqual() on changes, too! +} + + +inline +bool effectivelyEqual(const SyncConfig& lhs, const SyncConfig& rhs) +{ + return effectivelyEqual(lhs.directionCfg, rhs.directionCfg) && lhs.handleDeletion == rhs.handleDeletion && (lhs.handleDeletion != DELETE_TO_VERSIONING || //only compare deletion directory if required! (lhs.versioningStyle == rhs.versioningStyle && @@ -373,6 +398,7 @@ bool operator==(const MainConfiguration& lhs, const MainConfiguration& rhs) lhs.onCompletion == rhs.onCompletion; } + //facilitate drag & drop config merge: MainConfiguration merge(const std::vector<MainConfiguration>& mainCfgs); } diff --git a/synchronization.cpp b/synchronization.cpp index a0f19d27..bfb0743f 100644 --- a/synchronization.cpp +++ b/synchronization.cpp @@ -75,7 +75,7 @@ SyncStatistics::SyncStatistics(const HierarchyObject& hierObj) SyncStatistics::SyncStatistics(const FilePair& fileObj) { init(); - calcStats(fileObj); + processFile(fileObj); rowsTotal += 1; } @@ -83,9 +83,12 @@ SyncStatistics::SyncStatistics(const FilePair& fileObj) inline void SyncStatistics::recurse(const HierarchyObject& hierObj) { - std::for_each(hierObj.refSubDirs ().begin(), hierObj.refSubDirs ().end(), [&](const DirPair& dirObj ) { calcStats(dirObj ); }); - std::for_each(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), [&](const FilePair& fileObj) { calcStats(fileObj); }); - std::for_each(hierObj.refSubLinks().begin(), hierObj.refSubLinks().end(), [&](const SymlinkPair& linkObj) { calcStats(linkObj); }); + for (const FilePair& fileObj : hierObj.refSubFiles()) + processFile(fileObj); + for (const SymlinkPair& linkObj : hierObj.refSubLinks()) + processLink(linkObj); + for (const DirPair& dirObj : hierObj.refSubDirs()) + processDir(dirObj); rowsTotal += hierObj.refSubDirs(). size(); rowsTotal += hierObj.refSubFiles().size(); @@ -94,7 +97,7 @@ void SyncStatistics::recurse(const HierarchyObject& hierObj) inline -void SyncStatistics::calcStats(const FilePair& fileObj) +void SyncStatistics::processFile(const FilePair& fileObj) { switch (fileObj.getSyncOperation()) //evaluate comparison result and sync direction { @@ -158,7 +161,7 @@ void SyncStatistics::calcStats(const FilePair& fileObj) inline -void SyncStatistics::calcStats(const SymlinkPair& linkObj) +void SyncStatistics::processLink(const SymlinkPair& linkObj) { switch (linkObj.getSyncOperation()) //evaluate comparison result and sync direction { @@ -205,7 +208,7 @@ void SyncStatistics::calcStats(const SymlinkPair& linkObj) inline -void SyncStatistics::calcStats(const DirPair& dirObj) +void SyncStatistics::processDir(const DirPair& dirObj) { switch (dirObj.getSyncOperation()) //evaluate comparison result and sync direction { @@ -266,12 +269,12 @@ std::vector<zen::FolderPairSyncCfg> zen::extractSyncCfg(const MainConfiguration& std::vector<FolderPairSyncCfg> output; //process all pairs - for (auto it = allPairs.begin(); it != allPairs.end(); ++it) + for (const FolderPairEnh& fp : allPairs) { - SyncConfig syncCfg = it->altSyncConfig.get() ? *it->altSyncConfig : mainCfg.syncCfg; + SyncConfig syncCfg = fp.altSyncConfig.get() ? *fp.altSyncConfig : mainCfg.syncCfg; output.push_back( - FolderPairSyncCfg(syncCfg.directionCfg.var == DirectionConfig::AUTOMATIC, + FolderPairSyncCfg(syncCfg.directionCfg.var == DirectionConfig::TWOWAY || detectMovedFilesEnabled(syncCfg.directionCfg), syncCfg.handleDeletion, syncCfg.versioningStyle, getFormattedDirectoryName(syncCfg.versioningDirectory))); @@ -313,7 +316,10 @@ public: ProcessCallback& procCallback); ~DeletionHandling() { - try { tryCleanup(false); } + try + { + tryCleanup(false); //throw FileError + } catch (...) {} //always (try to) clean up, even if synchronization is aborted! /* may block heavily, but still do not allow user callback: @@ -388,9 +394,9 @@ DeletionHandling::DeletionHandling(DeletionPolicy handleDel, //nothrow! break; case DELETE_TO_RECYCLER: - txtRemovingFile = _("Moving file %x to recycle bin" ); - txtRemovingDirectory = _("Moving folder %x to recycle bin" ); - txtRemovingSymlink = _("Moving symbolic link %x to recycle bin"); + txtRemovingFile = _("Moving file %x to the recycle bin" ); + txtRemovingDirectory = _("Moving folder %x to the recycle bin" ); + txtRemovingSymlink = _("Moving symbolic link %x to the recycle bin"); break; case DELETE_TO_VERSIONING: @@ -410,7 +416,7 @@ class CallbackMassRecycling : public CallbackRecycling public: CallbackMassRecycling(ProcessCallback& statusHandler) : statusHandler_(statusHandler), - txtRecyclingFile(_("Moving file %x to recycle bin")) {} + txtRecyclingFile(_("Moving file %x to the recycle bin")) {} //may throw: first exception is swallowed, updateStatus() is then called again where it should throw again and the exception will propagate as expected virtual void updateStatus(const Zstring& currentItem) @@ -675,79 +681,82 @@ void DeletionHandling::removeFileUpdating(const Zstring& fullName, auto guardStatistics = makeGuard([&] { procCallback_.updateTotalData(0, bytesReported); }); //error = unexpected increase of total workload bool deleted = false; - switch (deletionPolicy_) - { - case DELETE_PERMANENTLY: - deleted = zen::removeFile(fullName); //[!] scope specifier resolves nameclash! - break; + if (endsWith(relativeName, TEMP_FILE_ENDING)) //special rule for .ffs_tmp files: always delete permanently! + deleted = zen::removeFile(fullName); + else + switch (deletionPolicy_) + { + case DELETE_PERMANENTLY: + deleted = zen::removeFile(fullName); //[!] scope specifier resolves nameclash! + break; - case DELETE_TO_RECYCLER: + case DELETE_TO_RECYCLER: #ifdef ZEN_WIN - { - const Zstring targetFile = getOrCreateRecyclerTempDirPf() + relativeName; //throw FileError - - auto moveToTempDir = [&] { + const Zstring targetFile = getOrCreateRecyclerTempDirPf() + relativeName; //throw FileError + + auto moveToTempDir = [&] + { + try + { + //performance optimization: Instead of moving each object into recycle bin separately, + //we rename them one by one into a temporary directory and batch-recycle this directory after sync + renameFile(fullName, targetFile); //throw FileError, ErrorDifferentVolume + this->toBeRecycled.push_back(targetFile); + deleted = true; + } + catch (ErrorDifferentVolume&) //MoveFileEx() returns ERROR_PATH_NOT_FOUND *before* considering ERROR_NOT_SAME_DEVICE! => we have to create targetDir in any case! + { + deleted = recycleOrDelete(fullName); //throw FileError + } + }; + try { - //performance optimization: Instead of moving each object into recycle bin separately, - //we rename them one by one into a temporary directory and batch-recycle this directory after sync - renameFile(fullName, targetFile); //throw FileError, ErrorDifferentVolume - this->toBeRecycled.push_back(targetFile); - deleted = true; + moveToTempDir(); //throw FileError, ErrorDifferentVolume } - catch (ErrorDifferentVolume&) //MoveFileEx() returns ERROR_PATH_NOT_FOUND *before* considering ERROR_NOT_SAME_DEVICE! => we have to create targetDir in any case! + catch (FileError&) { - deleted = recycleOrDelete(fullName); //throw FileError - } - }; - - try - { - moveToTempDir(); //throw FileError, ErrorDifferentVolume - } - catch (FileError&) - { - if (somethingExists(fullName)) - { - const Zstring targetDir = beforeLast(targetFile, FILE_NAME_SEPARATOR); - if (!dirExists(targetDir)) + if (somethingExists(fullName)) { - makeDirectory(targetDir); //throw FileError -> may legitimately fail on Linux if permissions are missing - moveToTempDir(); //throw FileError -> this should work now! + const Zstring targetDir = beforeLast(targetFile, FILE_NAME_SEPARATOR); + if (!dirExists(targetDir)) + { + makeDirectory(targetDir); //throw FileError -> may legitimately fail on Linux if permissions are missing + moveToTempDir(); //throw FileError -> this should work now! + } + else + throw; } - else - throw; } } - } #elif defined ZEN_LINUX || defined ZEN_MAC - deleted = recycleOrDelete(fullName); //throw FileError + deleted = recycleOrDelete(fullName); //throw FileError #endif - break; + break; - case DELETE_TO_VERSIONING: - { - struct CallbackMoveFileImpl : public CallbackMoveFile + case DELETE_TO_VERSIONING: { - CallbackMoveFileImpl(ProcessCallback& callback, Int64& bytes) : callback_(callback), bytesReported_(bytes) {} - - private: - virtual void updateStatus(Int64 bytesDelta) + struct CallbackMoveFileImpl : public CallbackMoveFile { - callback_.updateProcessedData(0, bytesDelta); //throw()! -> ensure client and service provider are in sync! - bytesReported_ += bytesDelta; // + CallbackMoveFileImpl(ProcessCallback& callback, Int64& bytes) : callback_(callback), bytesReported_(bytes) {} - callback_.requestUiRefresh(); //may throw - } - ProcessCallback& callback_; - Int64& bytesReported_; - } cb(procCallback_, bytesReported); + private: + virtual void updateStatus(Int64 bytesDelta) + { + callback_.updateProcessedData(0, bytesDelta); //throw()! -> ensure client and service provider are in sync! + bytesReported_ += bytesDelta; // + + callback_.requestUiRefresh(); //may throw + } + ProcessCallback& callback_; + Int64& bytesReported_; + } cb(procCallback_, bytesReported); - deleted = getOrCreateVersioner().revisionFile(fullName, relativeName, cb); //throw FileError + deleted = getOrCreateVersioner().revisionFile(fullName, relativeName, cb); //throw FileError + } + break; } - break; - } if (deleted) notifyItemDeletion(); @@ -761,15 +770,10 @@ void DeletionHandling::removeFileUpdating(const Zstring& fullName, template <class Function> inline void DeletionHandling::removeLinkUpdating(const Zstring& fullName, const Zstring& relativeName, const Int64& bytesExpected, Function notifyItemDeletion) //throw FileError { - switch (getSymlinkType(fullName)) - { - case SYMLINK_TYPE_DIR: - return removeDirUpdating(fullName, relativeName, bytesExpected, notifyItemDeletion); //throw FileError - - case SYMLINK_TYPE_FILE: - case SYMLINK_TYPE_UNKNOWN: - return removeFileUpdating(fullName, relativeName, bytesExpected, notifyItemDeletion); //throw FileError - } + if (dirExists(fullName)) //dir symlink + return removeDirUpdating(fullName, relativeName, bytesExpected, notifyItemDeletion); //throw FileError + else //file symlink, broken symlink + return removeFileUpdating(fullName, relativeName, bytesExpected, notifyItemDeletion); //throw FileError } //------------------------------------------------------------------------------------------------------------ @@ -1330,30 +1334,23 @@ template <SynchronizeFolderPair::PassId pass> void SynchronizeFolderPair::runPass(HierarchyObject& hierObj) { //synchronize files: - std::for_each(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), - [&](FilePair& fileObj) - { + for (FilePair& fileObj : hierObj.refSubFiles()) if (pass == this->getPass(fileObj)) //"this->" required by two-pass lookup as enforced by GCC 4.7 tryReportingError2([&] { synchronizeFile(fileObj); }, procCallback_); - }); //synchronize symbolic links: - std::for_each(hierObj.refSubLinks().begin(), hierObj.refSubLinks().end(), - [&](SymlinkPair& linkObj) - { + for (SymlinkPair& linkObj : hierObj.refSubLinks()) if (pass == this->getPass(linkObj)) tryReportingError2([&] { synchronizeLink(linkObj); }, procCallback_); - }); //synchronize folders: - std::for_each(hierObj.refSubDirs().begin(), hierObj.refSubDirs().end(), - [&](DirPair& dirObj) + for (DirPair& dirObj : hierObj.refSubDirs()) { if (pass == this->getPass(dirObj)) tryReportingError2([&] { synchronizeFolder(dirObj); }, procCallback_); this->runPass<pass>(dirObj); //recurse - }); + } } //--------------------------------------------------------------------------------------------------------------- @@ -2032,18 +2029,17 @@ void zen::synchronize(const TimeComp& timeStamp, folderPairStat.getUpdate<RIGHT_SIDE>() + folderPairStat.getDelete<RIGHT_SIDE>() > 0; - //skip folder pair if there is nothing to do (except for automatic mode, where data base needs to be written even in this case) + //skip folder pair if there is nothing to do (except for two-way mode and move-detection, where DB files need to be written) if (!writeLeft && !writeRight && - !folderPairCfg.inAutomaticMode) + !folderPairCfg.saveSyncDB_) { skipFolderPair[folderIndex] = true; //skip creating (not yet existing) base directories in particular if there's no need continue; } - - //check empty input fields: basically this only makes sense if empty field is not target (and not automatic mode: because of db file creation) - if ((j->getBaseDirPf<LEFT_SIDE >().empty() && (writeLeft || folderPairCfg.inAutomaticMode)) || - (j->getBaseDirPf<RIGHT_SIDE>().empty() && (writeRight || folderPairCfg.inAutomaticMode))) + //check empty input fields: this only makes sense if empty field is source (and no DB files need to be created) + if ((j->getBaseDirPf<LEFT_SIDE >().empty() && (writeLeft || folderPairCfg.saveSyncDB_)) || + (j->getBaseDirPf<RIGHT_SIDE>().empty() && (writeRight || folderPairCfg.saveSyncDB_))) { callback.reportFatalError(_("Target folder input field must not be empty.")); skipFolderPair[folderIndex] = true; @@ -2208,7 +2204,7 @@ void zen::synchronize(const TimeComp& timeStamp, dirListMissingRecycler += std::wstring(L"\n") + it->first; if (!dirListMissingRecycler.empty()) - callback.reportWarning(_("The Recycle Bin is not available for the following folders. Files will be deleted permanently instead:") + L"\n" + dirListMissingRecycler, warnings.warningRecyclerMissing); + callback.reportWarning(_("The recycle bin is not available for the following folders. Files will be deleted permanently instead:") + L"\n" + dirListMissingRecycler, warnings.warningRecyclerMissing); } #endif @@ -2272,9 +2268,9 @@ void zen::synchronize(const TimeComp& timeStamp, //update synchronization database (automatic sync only) ScopeGuard guardUpdateDb = makeGuard([&] { - if (folderPairCfg.inAutomaticMode) + if (folderPairCfg.saveSyncDB_) try { zen::saveLastSynchronousState(*j); } //throw FileError - catch (...) {} + catch (FileError&) {} }); //guarantee removal of invalid entries (where element on both sides is empty) @@ -2332,8 +2328,8 @@ void zen::synchronize(const TimeComp& timeStamp, tryReportingError2([&] { delHandlerL.tryCleanup(); }, callback); //show error dialog if necessary tryReportingError2([&] { delHandlerR.tryCleanup(); }, callback); // - //(try to gracefully) write database file (will be done in ~EnforceUpdateDatabase anyway...) - if (folderPairCfg.inAutomaticMode) + //(try to gracefully) write database file + if (folderPairCfg.saveSyncDB_) { callback.reportStatus(_("Generating database...")); callback.forceUiRefresh(); @@ -2438,7 +2434,7 @@ FileAttrib SynchronizeFolderPair::copyFileUpdating(const Zstring& sourceFile, source = shadowCopyHandler_->makeShadowCopy(source, //throw FileError [&](const Zstring& volumeName) { - procCallback_.reportStatus(replaceCpy(_("Creating Volume Shadow Copy for %x..."), L"%x", fmtFileName(volumeName))); + procCallback_.reportStatus(replaceCpy(_("Creating a Volume Shadow Copy for %x..."), L"%x", fmtFileName(volumeName))); procCallback_.forceUiRefresh(); }); } diff --git a/synchronization.h b/synchronization.h index 9fb0ef06..75612d8b 100644 --- a/synchronization.h +++ b/synchronization.h @@ -45,9 +45,9 @@ private: void recurse(const HierarchyObject& hierObj); - void calcStats(const FilePair& fileObj); - void calcStats(const SymlinkPair& linkObj); - void calcStats(const DirPair& dirObj); + void processFile(const FilePair& fileObj); + void processLink(const SymlinkPair& linkObj); + void processDir(const DirPair& dirObj); int createLeft, createRight; int updateLeft, updateRight; @@ -60,16 +60,16 @@ private: struct FolderPairSyncCfg { - FolderPairSyncCfg(bool automaticMode, + FolderPairSyncCfg(bool saveSyncDB, const DeletionPolicy handleDel, VersioningStyle versioningStyle, const Zstring& versioningDirFmt) : - inAutomaticMode(automaticMode), + saveSyncDB_(saveSyncDB), handleDeletion(handleDel), versioningStyle_(versioningStyle), versioningFolder(versioningDirFmt) {} - bool inAutomaticMode; //update database if in automatic mode + bool saveSyncDB_; //save database if in automatic mode or dection of moved files is active DeletionPolicy handleDeletion; VersioningStyle versioningStyle_; Zstring versioningFolder; //formatted directory name diff --git a/ui/IFileDialog_Vista/IFileDialog_Vista.vcxproj b/ui/IFileDialog_Vista/IFileDialog_Vista.vcxproj index 31c87839..b1abe5a4 100644 --- a/ui/IFileDialog_Vista/IFileDialog_Vista.vcxproj +++ b/ui/IFileDialog_Vista/IFileDialog_Vista.vcxproj @@ -35,23 +35,23 @@ <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> @@ -93,7 +93,7 @@ <ClCompile> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;IFILE_DIALOG_VISTA_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> + <MinimalRebuild>false</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <PrecompiledHeader> @@ -104,6 +104,7 @@ <DisableSpecificWarnings>4100</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> <SmallerTypeCheck>true</SmallerTypeCheck> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> @@ -129,7 +130,7 @@ <ClCompile> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;IFILE_DIALOG_VISTA_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> + <MinimalRebuild>false</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <PrecompiledHeader> @@ -140,6 +141,7 @@ <DisableSpecificWarnings>4100</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> <SmallerTypeCheck>true</SmallerTypeCheck> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> @@ -175,11 +177,12 @@ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> <SmallerTypeCheck>false</SmallerTypeCheck> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> + <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> @@ -214,11 +217,12 @@ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> <SmallerTypeCheck>false</SmallerTypeCheck> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> + <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> diff --git a/ui/Taskbar_Seven/Taskbar_Seven.vcxproj b/ui/Taskbar_Seven/Taskbar_Seven.vcxproj index 02c4b67b..e7fec802 100644 --- a/ui/Taskbar_Seven/Taskbar_Seven.vcxproj +++ b/ui/Taskbar_Seven/Taskbar_Seven.vcxproj @@ -28,23 +28,23 @@ <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> @@ -86,7 +86,7 @@ <ClCompile> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;TASKBAR_SEVEN_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> + <MinimalRebuild>false</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <PrecompiledHeader> @@ -97,6 +97,7 @@ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> <SmallerTypeCheck>true</SmallerTypeCheck> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> @@ -121,7 +122,7 @@ <ClCompile> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;TASKBAR_SEVEN_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> + <MinimalRebuild>false</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <PrecompiledHeader> @@ -132,6 +133,7 @@ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> <SmallerTypeCheck>true</SmallerTypeCheck> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> @@ -164,11 +166,12 @@ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> + <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> @@ -201,11 +204,12 @@ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> + <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> diff --git a/ui/batch_config.cpp b/ui/batch_config.cpp index bf3436f1..1ccb1223 100644 --- a/ui/batch_config.cpp +++ b/ui/batch_config.cpp @@ -43,7 +43,7 @@ private: virtual void OnSaveBatchJob(wxCommandEvent& event); virtual void OnErrorPopup (wxCommandEvent& event) { localBatchCfg.handleError = ON_ERROR_POPUP; updateGui(); } virtual void OnErrorIgnore(wxCommandEvent& event) { localBatchCfg.handleError = ON_ERROR_IGNORE; updateGui(); } - virtual void OnErrorExit (wxCommandEvent& event) { localBatchCfg.handleError = ON_ERROR_EXIT; updateGui(); } + virtual void OnErrorAbort (wxCommandEvent& event) { localBatchCfg.handleError = ON_ERROR_ABORT; updateGui(); } virtual void OnToggleGenerateLogfile(wxCommandEvent& event) { updateGui(); } virtual void OnToggleLogfilesLimit (wxCommandEvent& event) { updateGui(); } @@ -76,6 +76,8 @@ BatchDialog::BatchDialog(wxWindow* parent, wxWindowUpdateLocker dummy(this); //avoid display distortion setRelativeFontSize(*m_staticTextHeader, 1.25); + m_staticTextDescr->SetLabel(replaceCpy(m_staticTextDescr->GetLabel(), L"%x", L"FreeFileSync.exe <" + _("job name") + L">.ffs_batch")); + m_comboBoxExecFinished->initHistory(onCompletionHistory, onCompletionHistoryMax); m_bpButtonHelp ->SetBitmapLabel(getResourceImage(L"help")); @@ -101,7 +103,7 @@ void BatchDialog::updateGui() //re-evaluate gui after config changes m_toggleBtnErrorIgnore->SetValue(false); m_toggleBtnErrorPopup ->SetValue(false); - m_toggleBtnErrorExit ->SetValue(false); + m_toggleBtnErrorAbort ->SetValue(false); switch (cfg.handleError) //*not* owned by GUI controls { case ON_ERROR_IGNORE: @@ -110,8 +112,8 @@ void BatchDialog::updateGui() //re-evaluate gui after config changes case ON_ERROR_POPUP: m_toggleBtnErrorPopup->SetValue(true); break; - case ON_ERROR_EXIT: - m_toggleBtnErrorExit->SetValue(true); + case ON_ERROR_ABORT: + m_toggleBtnErrorAbort->SetValue(true); break; } } diff --git a/ui/batch_status_handler.cpp b/ui/batch_status_handler.cpp index a72aab3e..3c916fdf 100644 --- a/ui/batch_status_handler.cpp +++ b/ui/batch_status_handler.cpp @@ -225,12 +225,12 @@ BatchStatusHandler::~BatchStatusHandler() if (!abortIsRequested()) //if aborted (manually), we don't execute the command { const std::wstring finalCommand = progressDlg->getExecWhenFinishedCommand(); //final value (after possible user modification) - if (isCloseProgressDlgCommand(finalCommand)) - showFinalResults = false; //take precedence over current visibility status - else if (!finalCommand.empty()) + if (!finalCommand.empty()) { - auto cmdexp = expandMacros(utfCvrtTo<Zstring>(finalCommand)); - shellExecute(cmdexp); + if (isCloseProgressDlgCommand(finalCommand)) + showFinalResults = false; //take precedence over current visibility status + else + shellExecute(expandMacros(utfCvrtTo<Zstring>(finalCommand))); } } @@ -329,7 +329,7 @@ void BatchStatusHandler::reportWarning(const std::wstring& warningMessage, bool& } break; //keep it! last switch might not find match - case xmlAccess::ON_ERROR_EXIT: //abort + case xmlAccess::ON_ERROR_ABORT: abortThisProcess(); break; @@ -374,7 +374,7 @@ ProcessCallback::Response BatchStatusHandler::reportError(const std::wstring& er } break; //used if last switch didn't find a match - case xmlAccess::ON_ERROR_EXIT: //abort + case xmlAccess::ON_ERROR_ABORT: abortThisProcess(); break; @@ -416,7 +416,7 @@ void BatchStatusHandler::reportFatalError(const std::wstring& errorMessage) } break; - case xmlAccess::ON_ERROR_EXIT: //abort + case xmlAccess::ON_ERROR_ABORT: abortThisProcess(); break; diff --git a/ui/column_attr.h b/ui/column_attr.h index 399f553b..070e6dd8 100644 --- a/ui/column_attr.h +++ b/ui/column_attr.h @@ -7,7 +7,6 @@ #ifndef COL_ATTR_HEADER_189467891346732143214 #define COL_ATTR_HEADER_189467891346732143214 -#include <stddef.h> //size_t #include <vector> namespace zen @@ -34,18 +33,18 @@ struct ColumnAttributeRim bool visible_; }; - +warn_static("two stretched oclumsn: hide vergrößert range!") inline std::vector<ColumnAttributeRim> getDefaultColumnAttributesLeft() { std::vector<ColumnAttributeRim> attr; - attr.push_back(ColumnAttributeRim(COL_TYPE_FULL_PATH, 250, 0, false)); - attr.push_back(ColumnAttributeRim(COL_TYPE_DIRECTORY, 200, 0, false)); - attr.push_back(ColumnAttributeRim(COL_TYPE_REL_PATH, 200, 0, true)); - attr.push_back(ColumnAttributeRim(COL_TYPE_FILENAME, -280, 1, true)); //stretch to full width and substract sum of fixed size widths! - attr.push_back(ColumnAttributeRim(COL_TYPE_DATE, 112, 0, false)); - attr.push_back(ColumnAttributeRim(COL_TYPE_SIZE, 80, 0, true)); - attr.push_back(ColumnAttributeRim(COL_TYPE_EXTENSION, 60, 0, false)); + attr.push_back(ColumnAttributeRim(COL_TYPE_FULL_PATH, 250, 0, false)); + attr.push_back(ColumnAttributeRim(COL_TYPE_DIRECTORY, 200, 0, false)); + attr.push_back(ColumnAttributeRim(COL_TYPE_REL_PATH, 200, 0, true)); + attr.push_back(ColumnAttributeRim(COL_TYPE_FILENAME, -280, 1, true)); //stretch to full width and substract sum of fixed size widths! + attr.push_back(ColumnAttributeRim(COL_TYPE_DATE, 112, 0, false)); + attr.push_back(ColumnAttributeRim(COL_TYPE_SIZE, 80, 0, true)); + attr.push_back(ColumnAttributeRim(COL_TYPE_EXTENSION, 60, 0, false)); return attr; } diff --git a/ui/custom_grid.cpp b/ui/custom_grid.cpp index 59e80100..d2188f22 100644 --- a/ui/custom_grid.cpp +++ b/ui/custom_grid.cpp @@ -166,6 +166,7 @@ public: GridDataBase(Grid& grid, const std::shared_ptr<const zen::GridView>& gridDataView) : grid_(grid), gridDataView_(gridDataView) {} void holdOwnership(const std::shared_ptr<GridEventManager>& evtMgr) { evtMgr_ = evtMgr; } + GridEventManager* getEventManager() { return evtMgr_.get(); } protected: Grid& refGrid() { return grid_; } @@ -557,7 +558,7 @@ private: } } - virtual size_t getBestSize(wxDC& dc, size_t row, ColumnType colType) + virtual int getBestSize(wxDC& dc, size_t row, ColumnType colType) { // Partitioning: // ________________________________ @@ -1011,9 +1012,9 @@ private: case COL_TYPE_CHECKBOX: break; case COL_TYPE_CMP_CATEGORY: - return _("Category"); + return _("Category") + L" (F9)"; case COL_TYPE_SYNC_ACTION: - return _("Action"); + return _("Action") + L" (F9)"; } return wxEmptyString; } @@ -1335,6 +1336,8 @@ public: ~GridEventManager() { assert(!scrollbarUpdatePending); } + void setScrollMaster(const Grid& grid) { scrollMaster = &grid; } + private: void onCenterSelectBegin(GridClickEvent& event) { @@ -1422,14 +1425,14 @@ private: void onResizeColumnL(GridColumnResizeEvent& event) { resizeOtherSide(gridL_, gridR_, event.colType_, event.offset_); } void onResizeColumnR(GridColumnResizeEvent& event) { resizeOtherSide(gridR_, gridL_, event.colType_, event.offset_); } - void resizeOtherSide(const Grid& src, Grid& trg, ColumnType type, ptrdiff_t offset) + void resizeOtherSide(const Grid& src, Grid& trg, ColumnType type, int offset) { //find stretch factor of resized column: type is unique due to makeConsistent()! std::vector<Grid::ColumnAttribute> cfgSrc = src.getColumnConfig(); auto it = std::find_if(cfgSrc.begin(), cfgSrc.end(), [&](Grid::ColumnAttribute& ca) { return ca.type_ == type; }); if (it == cfgSrc.end()) return; - const ptrdiff_t stretchSrc = it->stretch_; + const int stretchSrc = it->stretch_; //we do not propagate resizings on stretched columns to the other side: awkward user experience if (stretchSrc > 0) @@ -1706,11 +1709,23 @@ void gridview::refresh(Grid& gridLeft, Grid& gridCenter, Grid& gridRight) } +void gridview::setScrollMaster(Grid& grid) +{ + if (auto prov = dynamic_cast<GridDataBase*>(grid.getDataProvider())) + if (auto evtMgr = prov->getEventManager()) + { + evtMgr->setScrollMaster(grid); + return; + } + assert(false); +} + + void gridview::setNavigationMarker(Grid& gridLeft, hash_set<const FileSystemObject*>&& markedFilesAndLinks, hash_set<const HierarchyObject*>&& markedContainer) { - if (auto* provLeft = dynamic_cast<GridDataLeft*>(gridLeft.getDataProvider())) + if (auto provLeft = dynamic_cast<GridDataLeft*>(gridLeft.getDataProvider())) provLeft->setNavigationMarker(std::move(markedFilesAndLinks), std::move(markedContainer)); else assert(false); @@ -1720,7 +1735,7 @@ void gridview::setNavigationMarker(Grid& gridLeft, void gridview::highlightSyncAction(Grid& gridCenter, bool value) { - if (auto* provMiddle = dynamic_cast<GridDataMiddle*>(gridCenter.getDataProvider())) + if (auto provMiddle = dynamic_cast<GridDataMiddle*>(gridCenter.getDataProvider())) provMiddle->highlightSyncAction(value); else assert(false); diff --git a/ui/custom_grid.h b/ui/custom_grid.h index da6387f3..32beee01 100644 --- a/ui/custom_grid.h +++ b/ui/custom_grid.h @@ -29,6 +29,8 @@ void setupIcons(Grid& gridLeft, Grid& gridCenter, Grid& gridRight, bool show, Ic void clearSelection(Grid& gridLeft, Grid& gridCenter, Grid& gridRight); //clear all components void refresh(Grid& gridLeft, Grid& gridCenter, Grid& gridRight); +void setScrollMaster(Grid& grid); + //mark rows selected in navigation/compressed tree and navigate to leading object void setNavigationMarker(Grid& gridLeft, hash_set<const FileSystemObject*>&& markedFilesAndLinks,//mark files/symlinks directly within a container diff --git a/ui/dir_name.cpp b/ui/dir_name.cpp index 356b0888..cbaafe78 100644 --- a/ui/dir_name.cpp +++ b/ui/dir_name.cpp @@ -220,7 +220,7 @@ void DirectoryName<NameControl>::onSelectDir(wxCommandEvent& event) }; //some random GUID => have Windows save IFileDialog state separately from other file/dir pickers! showFolderPicker(static_cast<HWND>(selectButton_.GetHWND()), //in; ==HWND - defaultDirname.empty() ? nullptr : defaultDirname.c_str(), //in, optional! + defaultDirname.empty() ? static_cast<const wchar_t*>(nullptr) : defaultDirname.c_str(), //in, optional! &guid, selectedFolder, //out: call freeString() after use! cancelled, //out @@ -235,7 +235,7 @@ void DirectoryName<NameControl>::onSelectDir(wxCommandEvent& event) newFolder = make_unique<wxString>(selectedFolder); } } -#endif +#endif if (!newFolder.get()) { wxDirDialog dirPicker(&selectButton_, _("Select a folder"), defaultDirname); //put modal wxWidgets dialogs on stack: creating on freestore leads to memleak! diff --git a/ui/folder_pair.h b/ui/folder_pair.h index 11be1e8c..f677df4f 100644 --- a/ui/folder_pair.h +++ b/ui/folder_pair.h @@ -10,7 +10,7 @@ #include <wx/event.h> #include <wx/menu.h> #include <wx+/context_menu.h> -#include <wx+/button.h> +#include <wx+/bitmap_button.h> #include <wx+/image_tools.h> #include "dir_name.h" #include "small_dlgs.h" @@ -86,12 +86,12 @@ private: //test for Null-filter if (!isNullFilter(localFilter)) { - setImage(*basicPanel_.m_bpButtonLocalFilter, getResourceImage(L"filterSmall")); + setImage(*basicPanel_.m_bpButtonLocalFilter, getResourceImage(L"filter_small")); basicPanel_.m_bpButtonLocalFilter->SetToolTip(_("Filter is active")); } else { - setImage(*basicPanel_.m_bpButtonLocalFilter, greyScale(getResourceImage(L"filterSmall"))); + setImage(*basicPanel_.m_bpButtonLocalFilter, greyScale(getResourceImage(L"filter_small"))); basicPanel_.m_bpButtonLocalFilter->SetToolTip(_("No filter selected")); } } diff --git a/ui/grid_view.cpp b/ui/grid_view.cpp index fa1e9915..e1e16e47 100644 --- a/ui/grid_view.cpp +++ b/ui/grid_view.cpp @@ -297,34 +297,26 @@ void GridView::removeInvalidRows() class GridView::SerializeHierarchy { public: + static void execute(HierarchyObject& hierObj, std::vector<GridView::RefIndex>& sortedRef, size_t index) { SerializeHierarchy(sortedRef, index).recurse(hierObj); } + +private: SerializeHierarchy(std::vector<GridView::RefIndex>& sortedRef, size_t index) : index_(index), sortedRef_(sortedRef) {} - void execute(HierarchyObject& hierObj) - { - std::for_each(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), *this); - std::for_each(hierObj.refSubLinks().begin(), hierObj.refSubLinks().end(), *this); - std::for_each(hierObj.refSubDirs ().begin(), hierObj.refSubDirs ().end(), *this); - } - - void operator()(FilePair& fileObj) - { - sortedRef_.push_back(RefIndex(index_, fileObj.getId())); - } - - void operator()(SymlinkPair& linkObj) - { - sortedRef_.push_back(RefIndex(index_, linkObj.getId())); - } - - void operator()(DirPair& dirObj) + void recurse(HierarchyObject& hierObj) { - sortedRef_.push_back(RefIndex(index_, dirObj.getId())); - execute(dirObj); //add recursion here to list sub-objects directly below parent! + for (FilePair& fileObj : hierObj.refSubFiles()) + sortedRef_.push_back(RefIndex(index_, fileObj.getId())); + for (SymlinkPair& linkObj : hierObj.refSubLinks()) + sortedRef_.push_back(RefIndex(index_, linkObj.getId())); + for (DirPair& dirObj : hierObj.refSubDirs()) + { + sortedRef_.push_back(RefIndex(index_, dirObj.getId())); + recurse(dirObj); //add recursion here to list sub-objects directly below parent! + } } -private: size_t index_; std::vector<GridView::RefIndex>& sortedRef_; }; @@ -345,7 +337,7 @@ void GridView::setData(FolderComparison& folderCmp) }); for (auto it = begin(folderCmp); it != end(folderCmp); ++it) - SerializeHierarchy(sortedRef, it - begin(folderCmp)).execute(*it); + SerializeHierarchy::execute(*it, sortedRef, it - begin(folderCmp)); } diff --git a/ui/gui_generated.cpp b/ui/gui_generated.cpp index 21f5f82d..19794897 100644 --- a/ui/gui_generated.cpp +++ b/ui/gui_generated.cpp @@ -5,14 +5,13 @@ // PLEASE DO "NOT" EDIT THIS FILE! /////////////////////////////////////////////////////////////////////////// -#include "../wx+/button.h" +#include "../wx+/bitmap_button.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 "triple_splitter.h" -#include "wx_form_build_hide_warnings.h" #include "gui_generated.h" @@ -25,11 +24,6 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_menubar1 = new wxMenuBar( 0 ); m_menuFile = new wxMenu(); m_menuItemNew = new wxMenuItem( m_menuFile, wxID_NEW, wxString( _("&New") ) + wxT('\t') + wxT("Ctrl+N"), wxEmptyString, wxITEM_NORMAL ); - #ifdef __WXMSW__ - m_menuItemNew->SetBitmaps( wxNullBitmap ); - #elif defined( __WXGTK__ ) - m_menuItemNew->SetBitmap( wxNullBitmap ); - #endif m_menuFile->Append( m_menuItemNew ); m_menuItemLoad = new wxMenuItem( m_menuFile, wxID_OPEN, wxString( _("&Open...") ) + wxT('\t') + wxT("Ctrl+O"), wxEmptyString, wxITEM_NORMAL ); @@ -47,19 +41,9 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_menuFile->AppendSeparator(); m_menuItem10 = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("1. &Compare") ) + wxT('\t') + wxT("F5"), wxEmptyString, wxITEM_NORMAL ); - #ifdef __WXMSW__ - m_menuItem10->SetBitmaps( wxNullBitmap ); - #elif defined( __WXGTK__ ) - m_menuItem10->SetBitmap( wxNullBitmap ); - #endif m_menuFile->Append( m_menuItem10 ); - m_menuItem11 = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("2. &Synchronize") ) + wxT('\t') + wxT("F6"), wxEmptyString, wxITEM_NORMAL ); - #ifdef __WXMSW__ - m_menuItem11->SetBitmaps( wxNullBitmap ); - #elif defined( __WXGTK__ ) - m_menuItem11->SetBitmap( wxNullBitmap ); - #endif + m_menuItem11 = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("2. &Synchronize") ) + wxT('\t') + wxT("F8"), wxEmptyString, wxITEM_NORMAL ); m_menuFile->Append( m_menuItem11 ); m_menuFile->AppendSeparator(); @@ -80,7 +64,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_menuItem5 = new wxMenuItem( m_menuTools, wxID_ANY, wxString( _("&Export file list...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuTools->Append( m_menuItem5 ); - m_menuItemGlobSett = new wxMenuItem( m_menuTools, wxID_PREFERENCES, wxString( _("&Global settings...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuItemGlobSett = new wxMenuItem( m_menuTools, wxID_PREFERENCES, wxString( _("&Global settings") ) , wxEmptyString, wxITEM_NORMAL ); m_menuTools->Append( m_menuItemGlobSett ); m_menubar1->Append( m_menuTools, _("&Tools") ); @@ -116,80 +100,50 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizerTopButtons->Add( 15, 0, 0, wxALIGN_CENTER_VERTICAL, 5 ); - wxFlexGridSizer* fgSizer121; - fgSizer121 = new wxFlexGridSizer( 2, 2, 0, 0 ); - fgSizer121->SetFlexibleDirection( wxBOTH ); - fgSizer121->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - - m_staticTextCmpVariant = new wxStaticText( m_panelTopButtons, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextCmpVariant->Wrap( -1 ); - m_staticTextCmpVariant->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) ); - m_staticTextCmpVariant->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) ); - - fgSizer121->Add( m_staticTextCmpVariant, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxTOP, 1 ); - - - fgSizer121->Add( 0, 0, 1, 0, 5 ); - - wxBoxSizer* bSizer30; - bSizer30 = new wxBoxSizer( wxHORIZONTAL ); + wxBoxSizer* bSizer1721; + bSizer1721 = new wxBoxSizer( wxHORIZONTAL ); - m_buttonCompare = new zen::BitmapButton( m_panelTopButtons, wxID_OK, _("Compare"), wxDefaultPosition, wxSize( 180,-1 ), 0 ); + m_buttonCompare = new zen::BitmapTextButton( m_panelTopButtons, wxID_ANY, _("Compare"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); m_buttonCompare->SetDefault(); m_buttonCompare->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) ); m_buttonCompare->SetToolTip( _("dummy") ); - bSizer30->Add( m_buttonCompare, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + bSizer1721->Add( m_buttonCompare, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - m_buttonCancel = new zen::BitmapButton( m_panelTopButtons, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( 180,-1 ), 0 ); + m_buttonCancel = new zen::BitmapTextButton( m_panelTopButtons, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( 180,-1 ), 0 ); m_buttonCancel->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) ); m_buttonCancel->Enable( false ); m_buttonCancel->Hide(); - bSizer30->Add( m_buttonCancel, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - - fgSizer121->Add( bSizer30, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + bSizer1721->Add( m_buttonCancel, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_bpButtonCmpConfig = new wxBitmapButton( m_panelTopButtons, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 46,46 ), wxBU_AUTODRAW ); - m_bpButtonCmpConfig->SetToolTip( _("Comparison settings") ); + m_bpButtonCmpConfig->SetToolTip( _("dummy") ); - fgSizer121->Add( m_bpButtonCmpConfig, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 3 ); + bSizer1721->Add( m_bpButtonCmpConfig, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 3 ); - bSizerTopButtons->Add( fgSizer121, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 ); + bSizerTopButtons->Add( bSizer1721, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 4 ); bSizerTopButtons->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL, 5 ); - wxFlexGridSizer* fgSizer12; - fgSizer12 = new wxFlexGridSizer( 2, 2, 0, 0 ); - fgSizer12->SetFlexibleDirection( wxBOTH ); - fgSizer12->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - - - fgSizer12->Add( 0, 0, 1, wxEXPAND, 5 ); - - m_staticTextSyncVariant = new wxStaticText( m_panelTopButtons, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextSyncVariant->Wrap( -1 ); - m_staticTextSyncVariant->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) ); - m_staticTextSyncVariant->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) ); - - fgSizer12->Add( m_staticTextSyncVariant, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxTOP, 1 ); + wxBoxSizer* bSizer1731; + bSizer1731 = new wxBoxSizer( wxHORIZONTAL ); m_bpButtonSyncConfig = new wxBitmapButton( m_panelTopButtons, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 46,46 ), wxBU_AUTODRAW ); - m_bpButtonSyncConfig->SetToolTip( _("Synchronization settings") ); + m_bpButtonSyncConfig->SetToolTip( _("dummy") ); - fgSizer12->Add( m_bpButtonSyncConfig, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3 ); + bSizer1731->Add( m_bpButtonSyncConfig, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3 ); - m_buttonSync = new zen::BitmapButton( m_panelTopButtons, wxID_ANY, _("Synchronize"), wxDefaultPosition, wxSize( 180,-1 ), 0 ); + m_buttonSync = new zen::BitmapTextButton( m_panelTopButtons, wxID_ANY, _("Synchronize"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); m_buttonSync->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) ); m_buttonSync->SetToolTip( _("dummy") ); - fgSizer12->Add( m_buttonSync, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + bSizer1731->Add( m_buttonSync, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - bSizerTopButtons->Add( fgSizer12, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 ); + bSizerTopButtons->Add( bSizer1731, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 4 ); bSizerTopButtons->Add( 15, 0, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -422,7 +376,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizerStatusLeftFiles->Add( m_staticTextStatusLeftFiles, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); - bSizerStatusLeftFiles->Add( 10, 0, 0, 0, 5 ); + bSizerStatusLeftFiles->Add( 4, 0, 0, 0, 5 ); m_staticTextStatusLeftBytes = new wxStaticText( m_panelStatusBar, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextStatusLeftBytes->Wrap( -1 ); @@ -497,7 +451,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizerStatusRightFiles->Add( m_staticTextStatusRightFiles, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); - bSizerStatusRightFiles->Add( 10, 0, 0, 0, 5 ); + bSizerStatusRightFiles->Add( 4, 0, 0, 0, 5 ); m_staticTextStatusRightBytes = new wxStaticText( m_panelStatusBar, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextStatusRightBytes->Wrap( -1 ); @@ -536,6 +490,32 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer1711->Fit( m_panelCenter ); bSizerPanelHolder->Add( m_panelCenter, 1, wxEXPAND, 5 ); + m_panelSearch = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer1713; + bSizer1713 = new wxBoxSizer( wxHORIZONTAL ); + + m_bpButtonHideSearch = new wxBitmapButton( m_panelSearch, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 25,25 ), wxBU_AUTODRAW ); + m_bpButtonHideSearch->SetToolTip( _("Close search bar") ); + + bSizer1713->Add( m_bpButtonHideSearch, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_staticText101 = new wxStaticText( m_panelSearch, wxID_ANY, _("Find what:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText101->Wrap( -1 ); + bSizer1713->Add( m_staticText101, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlSearchTxt = new wxTextCtrl( m_panelSearch, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 220,-1 ), 0|wxWANTS_CHARS ); + m_textCtrlSearchTxt->SetMaxLength( 0 ); + bSizer1713->Add( m_textCtrlSearchTxt, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_checkBoxMatchCase = new wxCheckBox( m_panelSearch, wxID_ANY, _("Match case"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer1713->Add( m_checkBoxMatchCase, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + + m_panelSearch->SetSizer( bSizer1713 ); + m_panelSearch->Layout(); + bSizer1713->Fit( m_panelSearch ); + bSizerPanelHolder->Add( m_panelSearch, 0, 0, 5 ); + m_panelConfig = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); bSizerConfig = new wxBoxSizer( wxHORIZONTAL ); @@ -560,7 +540,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const 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 ); + m_listBoxHistory = new wxListBox( m_panelConfig, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED|wxLB_NEEDED_SB ); m_listBoxHistory->SetMinSize( wxSize( -1,40 ) ); bSizerConfig->Add( m_listBoxHistory, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); @@ -876,6 +856,8 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_bpButtonAddPair->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnAddFolderPair ), NULL, this ); m_bpButtonRemovePair->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnRemoveTopFolderPair ), NULL, this ); m_bpButtonSwapSides->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSwapSides ), NULL, this ); + m_bpButtonHideSearch->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnHideSearchPanel ), NULL, this ); + m_textCtrlSearchTxt->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( MainDialogGenerated::OnSearchGridEnter ), NULL, this ); m_bpButtonOpen->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnConfigLoad ), NULL, this ); m_bpButtonSave->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnConfigSave ), NULL, this ); m_bpButtonBatchJob->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSaveAsBatchJob ), NULL, this ); @@ -944,6 +926,8 @@ MainDialogGenerated::~MainDialogGenerated() m_bpButtonAddPair->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnAddFolderPair ), NULL, this ); m_bpButtonRemovePair->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnRemoveTopFolderPair ), NULL, this ); m_bpButtonSwapSides->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSwapSides ), NULL, this ); + m_bpButtonHideSearch->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnHideSearchPanel ), NULL, this ); + m_textCtrlSearchTxt->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( MainDialogGenerated::OnSearchGridEnter ), NULL, this ); m_bpButtonOpen->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnConfigLoad ), NULL, this ); m_bpButtonSave->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnConfigSave ), NULL, this ); m_bpButtonBatchJob->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSaveAsBatchJob ), NULL, this ); @@ -1085,7 +1069,6 @@ CompareProgressDlgGenerated::CompareProgressDlgGenerated( wxWindow* parent, wxWi bSizer182 = new wxBoxSizer( wxVERTICAL ); m_textCtrlStatus = new wxTextCtrl( this, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, wxTE_READONLY ); - m_textCtrlStatus->SetMaxLength( 0 ); m_textCtrlStatus->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); bSizer182->Add( m_textCtrlStatus, 0, wxEXPAND, 5 ); @@ -1249,8 +1232,6 @@ SyncProgressPanelGenerated::SyncProgressPanelGenerated( wxWindow* parent, wxWind bSizer42->Add( m_staticTextPhase, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 5 ); m_animCtrlSyncing = new wxAnimationCtrl( this, wxID_ANY, wxNullAnimation, wxDefaultPosition, wxSize( 32,32 ), wxAC_DEFAULT_STYLE ); - m_animCtrlSyncing->SetMinSize( wxSize( 32,32 ) ); - bSizer42->Add( m_animCtrlSyncing, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2 ); @@ -1733,7 +1714,7 @@ SyncConfirmationDlgGenerated::SyncConfirmationDlgGenerated( wxWindow* parent, wx wxBoxSizer* bSizer164; bSizer164 = new wxBoxSizer( wxVERTICAL ); - m_checkBoxDontShowAgain = new wxCheckBox( this, wxID_ANY, _("Don't show this dialog again"), wxDefaultPosition, wxDefaultSize, 0 ); + m_checkBoxDontShowAgain = new wxCheckBox( this, wxID_ANY, _("&Don't show this dialog again"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer164->Add( m_checkBoxDontShowAgain, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP|wxRIGHT|wxLEFT, 5 ); bSizerStdButtons = new wxBoxSizer( wxHORIZONTAL ); @@ -1927,48 +1908,111 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const wxFlexGridSizer* fgSizer1; fgSizer1 = new wxFlexGridSizer( 4, 2, 6, 8 ); - fgSizer1->SetFlexibleDirection( wxHORIZONTAL ); + fgSizer1->SetFlexibleDirection( wxBOTH ); fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + wxBoxSizer* bSizer171; + bSizer171 = new wxBoxSizer( wxVERTICAL ); + + + bSizer171->Add( 0, 0, 1, wxEXPAND, 5 ); + m_toggleBtnTwoWay = new wxToggleButton( m_panel37, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_toggleBtnTwoWay->SetValue( true ); m_toggleBtnTwoWay->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) ); - fgSizer1->Add( m_toggleBtnTwoWay, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + bSizer171->Add( m_toggleBtnTwoWay, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + + bSizer171->Add( 0, 0, 1, wxEXPAND, 5 ); + + + fgSizer1->Add( bSizer171, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_staticTextAutomatic = new wxStaticText( m_panel37, wxID_ANY, _("Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextAutomatic->Wrap( 480 ); fgSizer1->Add( m_staticTextAutomatic, 0, wxALIGN_CENTER_VERTICAL, 5 ); + wxBoxSizer* bSizer172; + bSizer172 = new wxBoxSizer( wxVERTICAL ); + + + bSizer172->Add( 0, 0, 1, wxEXPAND, 5 ); + m_toggleBtnMirror = new wxToggleButton( m_panel37, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_toggleBtnMirror->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) ); - fgSizer1->Add( m_toggleBtnMirror, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + bSizer172->Add( m_toggleBtnMirror, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + + bSizer172->Add( 0, 0, 1, wxEXPAND, 5 ); + + + fgSizer1->Add( bSizer172, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); m_staticTextMirror = new wxStaticText( m_panel37, wxID_ANY, _("Mirror backup of left folder. Right folder is modified to exactly match left folder after synchronization."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextMirror->Wrap( 480 ); fgSizer1->Add( m_staticTextMirror, 0, wxALIGN_CENTER_VERTICAL, 5 ); + wxBoxSizer* bSizer173; + bSizer173 = new wxBoxSizer( wxVERTICAL ); + + + bSizer173->Add( 0, 0, 1, wxEXPAND, 5 ); + m_toggleBtnUpdate = new wxToggleButton( m_panel37, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); m_toggleBtnUpdate->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) ); - fgSizer1->Add( m_toggleBtnUpdate, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + bSizer173->Add( m_toggleBtnUpdate, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + + bSizer173->Add( 0, 0, 1, wxEXPAND, 5 ); + + + fgSizer1->Add( bSizer173, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_staticTextUpdate = new wxStaticText( m_panel37, wxID_ANY, _("Copy new or updated files to right folder."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextUpdate->Wrap( 480 ); fgSizer1->Add( m_staticTextUpdate, 0, wxALIGN_CENTER_VERTICAL, 5 ); + wxBoxSizer* bSizer1741; + bSizer1741 = new wxBoxSizer( wxVERTICAL ); + + + bSizer1741->Add( 0, 0, 1, wxEXPAND, 5 ); + m_toggleBtnCustom = new wxToggleButton( m_panel37, wxID_ANY, _("Custom"), wxDefaultPosition, wxDefaultSize, 0 ); m_toggleBtnCustom->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) ); - fgSizer1->Add( m_toggleBtnCustom, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + bSizer1741->Add( m_toggleBtnCustom, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + + bSizer1741->Add( 0, 0, 1, wxEXPAND, 5 ); + + + fgSizer1->Add( bSizer1741, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); m_staticTextCustom = new wxStaticText( m_panel37, wxID_ANY, _("Configure your own synchronization rules."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextCustom->Wrap( 480 ); fgSizer1->Add( m_staticTextCustom, 0, wxALIGN_CENTER_VERTICAL, 5 ); - bSizer29->Add( fgSizer1, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + bSizer29->Add( fgSizer1, 0, wxRIGHT|wxLEFT, 5 ); + + wxBoxSizer* bSizer1751; + bSizer1751 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer1751->Add( 3, 0, 0, 0, 5 ); + + m_checkBoxDetectMove = new wxCheckBox( m_panel37, wxID_ANY, _("Detect moved files"), wxDefaultPosition, wxDefaultSize, 0 ); + m_checkBoxDetectMove->SetValue(true); + m_checkBoxDetectMove->SetToolTip( _("Requires database files. Not supported by all file systems.") ); + + bSizer1751->Add( m_checkBoxDetectMove, 1, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + + bSizer29->Add( bSizer1751, 0, wxEXPAND, 5 ); bSizerExtraConfig = new wxBoxSizer( wxVERTICAL ); @@ -2071,13 +2115,13 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const bSizer180->Add( m_toggleBtnPermanent, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - m_toggleBtnRecycler = new wxToggleButton( m_panel37, wxID_ANY, _("Recycle Bin"), wxDefaultPosition, wxDefaultSize, 0 ); - m_toggleBtnRecycler->SetToolTip( _("Use Recycle Bin for deleted and overwritten files") ); + m_toggleBtnRecycler = new wxToggleButton( m_panel37, wxID_ANY, _("Recycle bin"), wxDefaultPosition, wxDefaultSize, 0 ); + m_toggleBtnRecycler->SetToolTip( _("Back up deleted and overwritten files in the recycle bin") ); bSizer180->Add( m_toggleBtnRecycler, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 ); m_toggleBtnVersioning = new wxToggleButton( m_panel37, wxID_ANY, _("Versioning"), wxDefaultPosition, wxDefaultSize, 0 ); - m_toggleBtnVersioning->SetToolTip( _("Move files to user-defined folder") ); + m_toggleBtnVersioning->SetToolTip( _("Move files to a user-defined folder") ); bSizer180->Add( m_toggleBtnVersioning, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -2317,6 +2361,7 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const m_toggleBtnUpdate->Connect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncUpdate ), NULL, this ); m_toggleBtnCustom->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( SyncCfgDlgGenerated::OnSyncCustomDouble ), NULL, this ); m_toggleBtnCustom->Connect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncCustom ), NULL, this ); + m_checkBoxDetectMove->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnToggleDetectMovedFiles ), NULL, this ); m_toggleBtnErrorIgnore->Connect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnErrorIgnore ), NULL, this ); m_toggleBtnErrorPopup->Connect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnErrorPopup ), NULL, this ); m_toggleBtnPermanent->Connect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnDeletionPermanent ), NULL, this ); @@ -2345,6 +2390,7 @@ SyncCfgDlgGenerated::~SyncCfgDlgGenerated() m_toggleBtnUpdate->Disconnect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncUpdate ), NULL, this ); m_toggleBtnCustom->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( SyncCfgDlgGenerated::OnSyncCustomDouble ), NULL, this ); m_toggleBtnCustom->Disconnect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnSyncCustom ), NULL, this ); + m_checkBoxDetectMove->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnToggleDetectMovedFiles ), NULL, this ); m_toggleBtnErrorIgnore->Disconnect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnErrorIgnore ), NULL, this ); m_toggleBtnErrorPopup->Disconnect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnErrorPopup ), NULL, this ); m_toggleBtnPermanent->Disconnect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( SyncCfgDlgGenerated::OnDeletionPermanent ), NULL, this ); @@ -2382,9 +2428,9 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer72->Add( m_staticTextHeader, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - m_staticText44 = new wxStaticText( this, wxID_ANY, _("Create a batch file to automate synchronization. Double-click this file or schedule in your system's task planner: FreeFileSync.exe <job name>.ffs_batch"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText44->Wrap( 520 ); - bSizer72->Add( m_staticText44, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + m_staticTextDescr = new wxStaticText( this, wxID_ANY, _("Create a batch file for unattended synchronization. To start, double-click this file or schedule in a task planner: %x"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextDescr->Wrap( 520 ); + bSizer72->Add( m_staticTextDescr, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); bSizer72->Add( 0, 0, 1, wxEXPAND, 5 ); @@ -2429,10 +2475,10 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer169->Add( m_toggleBtnErrorPopup, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - m_toggleBtnErrorExit = new wxToggleButton( m_panel35, wxID_ANY, _("Exit"), wxDefaultPosition, wxDefaultSize, 0 ); - m_toggleBtnErrorExit->SetToolTip( _("Abort synchronization on first error") ); + m_toggleBtnErrorAbort = new wxToggleButton( m_panel35, wxID_ANY, _("Exit"), wxDefaultPosition, wxDefaultSize, 0 ); + m_toggleBtnErrorAbort->SetToolTip( _("Abort synchronization on first error") ); - bSizer169->Add( m_toggleBtnErrorExit, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer169->Add( m_toggleBtnErrorAbort, 0, wxALIGN_CENTER_VERTICAL, 5 ); bSizer171->Add( bSizer169, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -2533,7 +2579,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS m_bpButtonHelp->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnHelp ), NULL, this ); m_toggleBtnErrorIgnore->Connect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnErrorIgnore ), NULL, this ); m_toggleBtnErrorPopup->Connect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnErrorPopup ), NULL, this ); - m_toggleBtnErrorExit->Connect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnErrorExit ), NULL, this ); + m_toggleBtnErrorAbort->Connect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnErrorAbort ), NULL, this ); m_checkBoxGenerateLogfile->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnToggleGenerateLogfile ), NULL, this ); m_checkBoxLogfilesLimit->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnToggleLogfilesLimit ), NULL, this ); m_buttonSaveAs->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnSaveBatchJob ), NULL, this ); @@ -2547,7 +2593,7 @@ BatchDlgGenerated::~BatchDlgGenerated() m_bpButtonHelp->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnHelp ), NULL, this ); m_toggleBtnErrorIgnore->Disconnect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnErrorIgnore ), NULL, this ); m_toggleBtnErrorPopup->Disconnect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnErrorPopup ), NULL, this ); - m_toggleBtnErrorExit->Disconnect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnErrorExit ), NULL, this ); + m_toggleBtnErrorAbort->Disconnect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnErrorAbort ), NULL, this ); m_checkBoxGenerateLogfile->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnToggleGenerateLogfile ), NULL, this ); m_checkBoxLogfilesLimit->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnToggleLogfilesLimit ), NULL, this ); m_buttonSaveAs->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnSaveBatchJob ), NULL, this ); @@ -2555,310 +2601,6 @@ BatchDlgGenerated::~BatchDlgGenerated() } -AboutDlgGenerated::AboutDlgGenerated( 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->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) ); - - wxBoxSizer* bSizer31; - bSizer31 = new wxBoxSizer( wxVERTICAL ); - - m_panel41 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - m_panel41->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - - wxBoxSizer* bSizer162; - bSizer162 = new wxBoxSizer( wxVERTICAL ); - - m_bitmapLogo = new wxStaticBitmap( m_panel41, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer162->Add( m_bitmapLogo, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - m_staticline341 = new wxStaticLine( m_panel41, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - bSizer162->Add( m_staticline341, 0, wxEXPAND, 5 ); - - m_build = new wxStaticText( m_panel41, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); - m_build->Wrap( -1 ); - bSizer162->Add( m_build, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - m_staticline3411 = new wxStaticLine( m_panel41, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - bSizer162->Add( m_staticline3411, 0, wxEXPAND, 5 ); - - m_staticText72 = new wxStaticText( m_panel41, wxID_ANY, _("Source code written in C++ using:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText72->Wrap( -1 ); - m_staticText72->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) ); - - bSizer162->Add( m_staticText72, 0, wxALL, 5 ); - - wxBoxSizer* bSizer171; - bSizer171 = new wxBoxSizer( wxHORIZONTAL ); - - m_hyperlink11 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("MS Visual C++"), wxT("http://msdn.microsoft.com/library/60k1461a.aspx"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink11->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - m_hyperlink11->SetToolTip( _("http://msdn.microsoft.com/library/60k1461a.aspx") ); - - bSizer171->Add( m_hyperlink11, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - - m_hyperlink9 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("MinGW"), wxT("http://www.mingw.org"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink9->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - m_hyperlink9->SetToolTip( _("http://www.mingw.org") ); - - bSizer171->Add( m_hyperlink9, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - - m_hyperlink10 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("Code::Blocks"), wxT("http://www.codeblocks.org"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink10->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - m_hyperlink10->SetToolTip( _("http://www.codeblocks.org") ); - - bSizer171->Add( m_hyperlink10, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - - m_hyperlink7 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("wxWidgets"), wxT("http://www.wxwidgets.org"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink7->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - m_hyperlink7->SetToolTip( _("http://www.wxwidgets.org") ); - - bSizer171->Add( m_hyperlink7, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - - m_hyperlink14 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("wxFormBuilder"), wxT("http://wxformbuilder.org"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink14->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - m_hyperlink14->SetToolTip( _("http://wxformbuilder.org") ); - - bSizer171->Add( m_hyperlink14, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - - bSizer162->Add( bSizer171, 0, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); - - wxBoxSizer* bSizer172; - bSizer172 = new wxBoxSizer( wxHORIZONTAL ); - - m_hyperlink15 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("zen::Xml"), wxT("http://zenxml.sourceforge.net"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink15->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - m_hyperlink15->SetToolTip( _("http://zenxml.sourceforge.net") ); - - bSizer172->Add( m_hyperlink15, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - - m_hyperlink13 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("Boost"), wxT("http://www.boost.org"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink13->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - m_hyperlink13->SetToolTip( _("http://www.boost.org") ); - - bSizer172->Add( m_hyperlink13, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - - m_hyperlink16 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("Artistic Style"), wxT("http://astyle.sourceforge.net"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink16->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - m_hyperlink16->SetToolTip( _("http://astyle.sourceforge.net") ); - - bSizer172->Add( m_hyperlink16, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - - m_hyperlink12 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("Google Test"), wxT("http://code.google.com/p/googletest"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink12->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - m_hyperlink12->SetToolTip( _("http://code.google.com/p/googletest") ); - - bSizer172->Add( m_hyperlink12, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - - m_hyperlink18 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("Unicode NSIS"), wxT("http://www.scratchpaper.com"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink18->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - m_hyperlink18->SetToolTip( _("http://www.scratchpaper.com") ); - - bSizer172->Add( m_hyperlink18, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - - bSizer162->Add( bSizer172, 0, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); - - m_panel40 = new wxPanel( m_panel41, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - m_panel40->SetBackgroundColour( wxColour( 153, 170, 187 ) ); - - wxBoxSizer* bSizer183; - bSizer183 = new wxBoxSizer( wxVERTICAL ); - - m_panel39 = new wxPanel( m_panel40, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - m_panel39->SetBackgroundColour( wxColour( 221, 221, 255 ) ); - - wxBoxSizer* bSizer184; - bSizer184 = new wxBoxSizer( wxHORIZONTAL ); - - wxBoxSizer* bSizer178; - bSizer178 = new wxBoxSizer( wxVERTICAL ); - - m_staticText83 = new wxStaticText( m_panel39, wxID_ANY, _("If you like FreeFileSync"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText83->Wrap( -1 ); - m_staticText83->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 93, 92, false, wxEmptyString ) ); - m_staticText83->SetForegroundColour( wxColour( 0, 0, 0 ) ); - - bSizer178->Add( m_staticText83, 0, wxALL, 5 ); - - m_buttonDonate = new wxButton( m_panel39, wxID_ANY, _("Donate with PayPal"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonDonate->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); - m_buttonDonate->SetToolTip( _("https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=zenju@gmx.de&no_shipping=1&lc=US¤cy_code=EUR") ); - - bSizer178->Add( m_buttonDonate, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_RIGHT, 5 ); - - - bSizer184->Add( bSizer178, 1, wxALIGN_CENTER_VERTICAL, 5 ); - - m_animCtrlWink = new wxAnimationCtrl( m_panel39, wxID_ANY, wxNullAnimation, wxDefaultPosition, wxSize( -1,-1 ), wxAC_DEFAULT_STYLE ); - bSizer184->Add( m_animCtrlWink, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - - m_panel39->SetSizer( bSizer184 ); - m_panel39->Layout(); - bSizer184->Fit( m_panel39 ); - bSizer183->Add( m_panel39, 0, wxEXPAND|wxALL, 5 ); - - - m_panel40->SetSizer( bSizer183 ); - m_panel40->Layout(); - bSizer183->Fit( m_panel40 ); - bSizer162->Add( m_panel40, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); - - m_scrolledWindowTranslators = new wxScrolledWindow( m_panel41, wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), wxHSCROLL|wxVSCROLL ); - m_scrolledWindowTranslators->SetScrollRate( 10, 10 ); - m_scrolledWindowTranslators->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - m_scrolledWindowTranslators->SetMinSize( wxSize( -1,180 ) ); - - bSizerTranslators = new wxBoxSizer( wxVERTICAL ); - - m_staticText54 = new wxStaticText( m_scrolledWindowTranslators, wxID_ANY, _("Many thanks for localization:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText54->Wrap( -1 ); - m_staticText54->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) ); - - bSizerTranslators->Add( m_staticText54, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP|wxBOTTOM, 5 ); - - - bSizerTranslators->Add( 0, 5, 0, 0, 5 ); - - fgSizerTranslators = new wxFlexGridSizer( 50, 3, 2, 20 ); - 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 ); - bSizer162->Add( m_scrolledWindowTranslators, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); - - m_staticline43 = new wxStaticLine( m_panel41, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - bSizer162->Add( m_staticline43, 0, wxEXPAND, 5 ); - - m_staticText94 = new wxStaticText( m_panel41, wxID_ANY, _("Feedback and suggestions are welcome"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText94->Wrap( -1 ); - bSizer162->Add( m_staticText94, 0, wxALL, 5 ); - - wxBoxSizer* bSizer166; - bSizer166 = new wxBoxSizer( wxHORIZONTAL ); - - wxBoxSizer* bSizer170; - bSizer170 = new wxBoxSizer( wxHORIZONTAL ); - - - bSizer170->Add( 0, 0, 1, wxEXPAND, 5 ); - - m_hyperlink1 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("Homepage"), wxT("http://freefilesync.sourceforge.net/"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink1->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, true, wxEmptyString ) ); - m_hyperlink1->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - m_hyperlink1->SetToolTip( _("http://freefilesync.sourceforge.net/") ); - - bSizer170->Add( m_hyperlink1, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - m_bitmap9 = new wxStaticBitmap( m_panel41, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer170->Add( m_bitmap9, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - - bSizer170->Add( 0, 0, 1, wxEXPAND, 5 ); - - - bSizer166->Add( bSizer170, 1, wxALIGN_CENTER_VERTICAL, 5 ); - - wxBoxSizer* bSizer1711; - bSizer1711 = new wxBoxSizer( wxHORIZONTAL ); - - - bSizer1711->Add( 0, 0, 1, wxEXPAND, 5 ); - - m_hyperlink2 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("Email"), wxT("mailto:zenju@gmx.de"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink2->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, true, wxEmptyString ) ); - m_hyperlink2->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - m_hyperlink2->SetToolTip( _("zenju@gmx.de") ); - - bSizer1711->Add( m_hyperlink2, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - m_bitmap10 = new wxStaticBitmap( m_panel41, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer1711->Add( m_bitmap10, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - - bSizer1711->Add( 0, 0, 1, wxEXPAND, 5 ); - - - bSizer166->Add( bSizer1711, 1, wxALIGN_CENTER_VERTICAL, 5 ); - - - bSizer162->Add( bSizer166, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); - - m_staticline34 = new wxStaticLine( m_panel41, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - bSizer162->Add( m_staticline34, 0, wxEXPAND, 5 ); - - m_staticText93 = new wxStaticText( m_panel41, wxID_ANY, _("Published under the GNU General Public License"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText93->Wrap( -1 ); - bSizer162->Add( m_staticText93, 0, wxALL, 5 ); - - wxBoxSizer* bSizer1671; - bSizer1671 = new wxBoxSizer( wxHORIZONTAL ); - - - bSizer1671->Add( 0, 0, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_bitmap13 = new wxStaticBitmap( m_panel41, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer1671->Add( m_bitmap13, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - - m_hyperlink5 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("http://www.gnu.org/licenses/gpl.html"), wxT("http://www.gnu.org/licenses/gpl.html"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_hyperlink5->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - - bSizer1671->Add( m_hyperlink5, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); - - - bSizer1671->Add( 0, 0, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - - bSizer162->Add( bSizer1671, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); - - - m_panel41->SetSizer( bSizer162 ); - m_panel41->Layout(); - bSizer162->Fit( m_panel41 ); - bSizer31->Add( m_panel41, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); - - m_staticline36 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - bSizer31->Add( m_staticline36, 0, wxEXPAND, 5 ); - - bSizerStdButtons = new wxBoxSizer( wxHORIZONTAL ); - - m_buttonClose = new wxButton( this, wxID_OK, _("Close"), wxDefaultPosition, wxSize( -1,30 ), 0 ); - m_buttonClose->SetDefault(); - bSizerStdButtons->Add( m_buttonClose, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 ); - - - bSizer31->Add( bSizerStdButtons, 0, wxALIGN_RIGHT, 5 ); - - - this->SetSizer( bSizer31 ); - this->Layout(); - bSizer31->Fit( this ); - - this->Centre( wxBOTH ); - - // Connect Events - this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( AboutDlgGenerated::OnClose ) ); - m_buttonDonate->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AboutDlgGenerated::OnDonate ), NULL, this ); - m_buttonClose->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AboutDlgGenerated::OnOK ), NULL, this ); -} - -AboutDlgGenerated::~AboutDlgGenerated() -{ - // Disconnect Events - this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( AboutDlgGenerated::OnClose ) ); - m_buttonDonate->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AboutDlgGenerated::OnDonate ), NULL, this ); - m_buttonClose->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AboutDlgGenerated::OnOK ), NULL, this ); - -} - MessageDlgGenerated::MessageDlgGenerated( 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( 300,160 ), wxDefaultSize ); @@ -2883,7 +2625,6 @@ MessageDlgGenerated::MessageDlgGenerated( wxWindow* parent, wxWindowID id, const bSizer26->Add( m_bitmapMsgType, 0, wxRIGHT|wxLEFT, 10 ); m_textCtrlMessage = new wxTextCtrl( m_panel33, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 420,150 ), wxTE_MULTILINE|wxTE_READONLY|wxNO_BORDER ); - m_textCtrlMessage->SetMaxLength( 0 ); bSizer26->Add( m_textCtrlMessage, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP, 5 ); @@ -2981,7 +2722,6 @@ DeleteDlgGenerated::DeleteDlgGenerated( wxWindow* parent, wxWindowID id, const w bSizer160->Add( 0, 10, 0, 0, 5 ); m_textCtrlFileList = new wxTextCtrl( m_panel31, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 520,200 ), wxTE_DONTWRAP|wxTE_MULTILINE|wxTE_READONLY|wxSTATIC_BORDER ); - m_textCtrlFileList->SetMaxLength( 0 ); bSizer160->Add( m_textCtrlFileList, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); @@ -3004,7 +2744,7 @@ DeleteDlgGenerated::DeleteDlgGenerated( wxWindow* parent, wxWindowID id, const w wxBoxSizer* bSizer99; bSizer99 = new wxBoxSizer( wxVERTICAL ); - m_checkBoxUseRecycler = new wxCheckBox( this, wxID_ANY, _("Recycle Bin"), wxDefaultPosition, wxDefaultSize, 0 ); + m_checkBoxUseRecycler = new wxCheckBox( this, wxID_ANY, _("Recycle bin"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer99->Add( m_checkBoxUseRecycler, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5 ); m_checkBoxDeleteBothSides = new wxCheckBox( this, wxID_ANY, _("Delete on both sides"), wxDefaultPosition, wxDefaultSize, 0 ); @@ -3074,7 +2814,7 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w bSizer72->Add( m_staticTextHeader, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - 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 = new wxStaticText( this, wxID_ANY, _("Files will only be synchronized if they pass all filter rules.\nNote: File paths must be relative to base directories."), wxDefaultPosition, wxSize( -1,-1 ), 0 ); m_staticText44->Wrap( 500 ); bSizer72->Add( m_staticText44, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); @@ -3112,7 +2852,6 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w bSizer1661->Add( m_bitmapInclude, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxTOP|wxBOTTOM|wxRIGHT, 5 ); m_textCtrlInclude = new wxTextCtrl( m_panel38, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), wxTE_MULTILINE ); - m_textCtrlInclude->SetMaxLength( 0 ); bSizer1661->Add( m_textCtrlInclude, 1, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); @@ -3132,7 +2871,6 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w bSizer1651->Add( m_bitmapExclude, 0, wxALIGN_CENTER_HORIZONTAL|wxTOP|wxBOTTOM|wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 ); m_textCtrlExclude = new wxTextCtrl( m_panel38, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), wxTE_MULTILINE ); - m_textCtrlExclude->SetMaxLength( 0 ); bSizer1651->Add( m_textCtrlExclude, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 ); @@ -3338,7 +3076,7 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind m_checkBoxTransCopy = new wxCheckBox( m_panel39, wxID_ANY, _("Fail-safe file copy"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer160->Add( m_checkBoxTransCopy, 0, wxALL|wxEXPAND, 5 ); - m_staticText82 = new wxStaticText( m_panel39, wxID_ANY, _("Write to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of fatal error."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText82 = new wxStaticText( m_panel39, wxID_ANY, _("Copy to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of a fatal error."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText82->Wrap( 460 ); m_staticText82->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) ); @@ -3347,7 +3085,7 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind m_checkBoxCopyLocked = new wxCheckBox( m_panel39, wxID_ANY, _("Copy locked files"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer160->Add( m_checkBoxCopyLocked, 0, wxALL|wxEXPAND, 5 ); - m_staticTextCopyLocked = new wxStaticText( m_panel39, wxID_ANY, _("Copy shared or locked files using Volume Shadow Copy Service (Requires Administrator rights)"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextCopyLocked = new wxStaticText( m_panel39, wxID_ANY, _("Copy shared or locked files using the Volume Shadow Copy Service (requires administrator rights)"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextCopyLocked->Wrap( 460 ); m_staticTextCopyLocked->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) ); @@ -3356,7 +3094,7 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind m_checkBoxCopyPermissions = new wxCheckBox( m_panel39, wxID_ANY, _("Copy file access permissions"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer160->Add( m_checkBoxCopyPermissions, 0, wxALL|wxEXPAND, 5 ); - m_staticText8211 = new wxStaticText( m_panel39, wxID_ANY, _("Transfer file and folder permissions (Requires Administrator rights)"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText8211 = new wxStaticText( m_panel39, wxID_ANY, _("Transfer file and folder permissions (requires administrator rights)"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText8211->Wrap( 460 ); m_staticText8211->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) ); @@ -3368,7 +3106,7 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind m_staticline191 = new wxStaticLine( m_panel39, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); bSizer166->Add( m_staticline191, 0, wxEXPAND|wxTOP, 5 ); - m_buttonResetDialogs = new zen::BitmapButton( m_panel39, wxID_ANY, _("Restore hidden dialogs"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonResetDialogs = new zen::BitmapTextButton( m_panel39, wxID_ANY, _("Restore hidden dialogs"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); bSizer166->Add( m_buttonResetDialogs, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); m_staticline192 = new wxStaticLine( m_panel39, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); @@ -3424,7 +3162,7 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind bSizer173->Add( m_gridCustomCommand, 1, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); - bSizer166->Add( bSizer173, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer166->Add( bSizer173, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxBOTTOM, 5 ); m_panel39->SetSizer( bSizer166 ); @@ -3509,78 +3247,6 @@ PopupDialogGenerated::~PopupDialogGenerated() { } -SearchDialogGenerated::SearchDialogGenerated( 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* bSizer161; - bSizer161 = new wxBoxSizer( wxHORIZONTAL ); - - wxBoxSizer* bSizer166; - bSizer166 = new wxBoxSizer( wxVERTICAL ); - - wxBoxSizer* bSizer162; - bSizer162 = new wxBoxSizer( wxHORIZONTAL ); - - m_staticText101 = new wxStaticText( this, wxID_ANY, _("Find what:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText101->Wrap( -1 ); - bSizer162->Add( m_staticText101, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlSearchTxt = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 220,-1 ), 0 ); - m_textCtrlSearchTxt->SetMaxLength( 0 ); - bSizer162->Add( m_textCtrlSearchTxt, 1, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); - - - bSizer166->Add( bSizer162, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - - bSizer166->Add( 0, 5, 0, 0, 5 ); - - m_checkBoxMatchCase = new wxCheckBox( this, wxID_ANY, _("Match case"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer166->Add( m_checkBoxMatchCase, 0, wxEXPAND|wxALL, 5 ); - - - bSizer161->Add( bSizer166, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - wxBoxSizer* bSizer97; - bSizer97 = new wxBoxSizer( wxVERTICAL ); - - m_buttonFindNext = new wxButton( this, wxID_OK, _("&Find next"), wxDefaultPosition, wxSize( -1,30 ), 0 ); - m_buttonFindNext->SetDefault(); - m_buttonFindNext->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) ); - - bSizer97->Add( m_buttonFindNext, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); - - m_button29 = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,30 ), 0 ); - bSizer97->Add( m_button29, 0, wxEXPAND|wxALL, 5 ); - - - bSizer161->Add( bSizer97, 0, 0, 5 ); - - - this->SetSizer( bSizer161 ); - this->Layout(); - bSizer161->Fit( this ); - - this->Centre( wxBOTH ); - - // Connect Events - this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( SearchDialogGenerated::OnClose ) ); - m_textCtrlSearchTxt->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( SearchDialogGenerated::OnText ), NULL, this ); - m_buttonFindNext->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SearchDialogGenerated::OnFindNext ), NULL, this ); - m_button29->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SearchDialogGenerated::OnCancel ), NULL, this ); -} - -SearchDialogGenerated::~SearchDialogGenerated() -{ - // Disconnect Events - this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( SearchDialogGenerated::OnClose ) ); - m_textCtrlSearchTxt->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( SearchDialogGenerated::OnText ), NULL, this ); - m_buttonFindNext->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SearchDialogGenerated::OnFindNext ), NULL, this ); - m_button29->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SearchDialogGenerated::OnCancel ), NULL, this ); - -} - SelectTimespanDlgGenerated::SelectTimespanDlgGenerated( 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 ); @@ -3595,10 +3261,10 @@ SelectTimespanDlgGenerated::SelectTimespanDlgGenerated( wxWindow* parent, wxWind wxBoxSizer* bSizer98; bSizer98 = new wxBoxSizer( wxHORIZONTAL ); - m_calendarFrom = new wxCalendarCtrl( m_panel35, wxID_ANY, wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxCAL_SHOW_HOLIDAYS ); + m_calendarFrom = new wxCalendarCtrl( m_panel35, wxID_ANY, wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxCAL_SHOW_HOLIDAYS|wxNO_BORDER ); bSizer98->Add( m_calendarFrom, 0, wxALL, 5 ); - m_calendarTo = new wxCalendarCtrl( m_panel35, wxID_ANY, wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxCAL_SHOW_HOLIDAYS ); + m_calendarTo = new wxCalendarCtrl( m_panel35, wxID_ANY, wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxCAL_SHOW_HOLIDAYS|wxNO_BORDER ); bSizer98->Add( m_calendarTo, 0, wxALL, 5 ); @@ -3649,3 +3315,311 @@ SelectTimespanDlgGenerated::~SelectTimespanDlgGenerated() m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SelectTimespanDlgGenerated::OnCancel ), NULL, this ); } + +AboutDlgGenerated::AboutDlgGenerated( 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->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) ); + + wxBoxSizer* bSizer31; + bSizer31 = new wxBoxSizer( wxVERTICAL ); + + m_panel41 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_panel41->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + + wxBoxSizer* bSizer162; + bSizer162 = new wxBoxSizer( wxVERTICAL ); + + m_bitmapLogo = new wxStaticBitmap( m_panel41, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer162->Add( m_bitmapLogo, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + m_staticline341 = new wxStaticLine( m_panel41, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bSizer162->Add( m_staticline341, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer174; + bSizer174 = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizer181; + bSizer181 = new wxBoxSizer( wxVERTICAL ); + + m_build = new wxStaticText( m_panel41, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); + m_build->Wrap( -1 ); + bSizer181->Add( m_build, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + m_staticline3411 = new wxStaticLine( m_panel41, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bSizer181->Add( m_staticline3411, 0, wxEXPAND, 5 ); + + m_staticText96 = new wxStaticText( m_panel41, wxID_ANY, _("Source code written in C++ using:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText96->Wrap( -1 ); + bSizer181->Add( m_staticText96, 0, wxALL, 5 ); + + wxBoxSizer* bSizer171; + bSizer171 = new wxBoxSizer( wxHORIZONTAL ); + + m_hyperlink11 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("MS Visual C++"), wxT("http://msdn.microsoft.com/library/60k1461a.aspx"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_hyperlink11->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + m_hyperlink11->SetToolTip( _("http://msdn.microsoft.com/library/60k1461a.aspx") ); + + bSizer171->Add( m_hyperlink11, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_hyperlink9 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("MinGW"), wxT("http://www.mingw.org"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_hyperlink9->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + m_hyperlink9->SetToolTip( _("http://www.mingw.org") ); + + bSizer171->Add( m_hyperlink9, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_hyperlink10 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("Code::Blocks"), wxT("http://www.codeblocks.org"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_hyperlink10->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + m_hyperlink10->SetToolTip( _("http://www.codeblocks.org") ); + + bSizer171->Add( m_hyperlink10, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_hyperlink7 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("wxWidgets"), wxT("http://www.wxwidgets.org"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_hyperlink7->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + m_hyperlink7->SetToolTip( _("http://www.wxwidgets.org") ); + + bSizer171->Add( m_hyperlink7, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_hyperlink14 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("wxFormBuilder"), wxT("http://wxformbuilder.org"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_hyperlink14->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + m_hyperlink14->SetToolTip( _("http://wxformbuilder.org") ); + + bSizer171->Add( m_hyperlink14, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer181->Add( bSizer171, 0, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + wxBoxSizer* bSizer172; + bSizer172 = new wxBoxSizer( wxHORIZONTAL ); + + m_hyperlink15 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("zen::Xml"), wxT("http://zenxml.sourceforge.net"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_hyperlink15->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + m_hyperlink15->SetToolTip( _("http://zenxml.sourceforge.net") ); + + bSizer172->Add( m_hyperlink15, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_hyperlink13 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("Boost"), wxT("http://www.boost.org"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_hyperlink13->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + m_hyperlink13->SetToolTip( _("http://www.boost.org") ); + + bSizer172->Add( m_hyperlink13, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_hyperlink16 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("Artistic Style"), wxT("http://astyle.sourceforge.net"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_hyperlink16->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + m_hyperlink16->SetToolTip( _("http://astyle.sourceforge.net") ); + + bSizer172->Add( m_hyperlink16, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_hyperlink12 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("Google Test"), wxT("http://code.google.com/p/googletest"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_hyperlink12->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + m_hyperlink12->SetToolTip( _("http://code.google.com/p/googletest") ); + + bSizer172->Add( m_hyperlink12, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_hyperlink18 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("Unicode NSIS"), wxT("http://www.scratchpaper.com"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_hyperlink18->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + m_hyperlink18->SetToolTip( _("http://www.scratchpaper.com") ); + + bSizer172->Add( m_hyperlink18, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer181->Add( bSizer172, 0, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + m_panelDonate = new wxPanel( m_panel41, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_panelDonate->SetBackgroundColour( wxColour( 153, 170, 187 ) ); + + wxBoxSizer* bSizer183; + bSizer183 = new wxBoxSizer( wxVERTICAL ); + + m_panel39 = new wxPanel( m_panelDonate, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_panel39->SetBackgroundColour( wxColour( 221, 221, 255 ) ); + + wxBoxSizer* bSizer184; + bSizer184 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer184->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_animCtrlWink = new wxAnimationCtrl( m_panel39, wxID_ANY, wxNullAnimation, wxDefaultPosition, wxSize( 48,48 ), wxAC_DEFAULT_STYLE ); + bSizer184->Add( m_animCtrlWink, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + wxBoxSizer* bSizer178; + bSizer178 = new wxBoxSizer( wxVERTICAL ); + + m_staticText83 = new wxStaticText( m_panel39, wxID_ANY, _("If you like FreeFileSync"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText83->Wrap( -1 ); + m_staticText83->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 93, 92, false, wxEmptyString ) ); + m_staticText83->SetForegroundColour( wxColour( 0, 0, 0 ) ); + + bSizer178->Add( m_staticText83, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_buttonDonate = new wxButton( m_panel39, wxID_ANY, _("Donate with PayPal"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonDonate->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); + m_buttonDonate->SetToolTip( _("https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=zenju@gmx.de&no_shipping=1&lc=US¤cy_code=EUR") ); + + bSizer178->Add( m_buttonDonate, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_HORIZONTAL, 5 ); + + + bSizer184->Add( bSizer178, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer184->Add( 0, 0, 1, wxEXPAND, 5 ); + + + m_panel39->SetSizer( bSizer184 ); + m_panel39->Layout(); + bSizer184->Fit( m_panel39 ); + bSizer183->Add( m_panel39, 0, wxEXPAND|wxALL, 5 ); + + + m_panelDonate->SetSizer( bSizer183 ); + m_panelDonate->Layout(); + bSizer183->Fit( m_panelDonate ); + bSizer181->Add( m_panelDonate, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + m_staticText94 = new wxStaticText( m_panel41, wxID_ANY, _("Feedback and suggestions are welcome"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText94->Wrap( -1 ); + bSizer181->Add( m_staticText94, 0, wxALL, 5 ); + + wxBoxSizer* bSizer166; + bSizer166 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer166->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_bitmap9 = new wxStaticBitmap( m_panel41, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_bitmap9->SetToolTip( _("Homepage") ); + + bSizer166->Add( m_bitmap9, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_hyperlink1 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("freefilesync.sf.net"), wxT("http://freefilesync.sf.net/"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_hyperlink1->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, true, wxEmptyString ) ); + m_hyperlink1->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + + bSizer166->Add( m_hyperlink1, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer166->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_bitmap10 = new wxStaticBitmap( m_panel41, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_bitmap10->SetToolTip( _("Email") ); + + bSizer166->Add( m_bitmap10, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_hyperlink2 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("zenju@gmx.de"), wxT("mailto:zenju@gmx.de"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_hyperlink2->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, true, wxEmptyString ) ); + m_hyperlink2->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + + bSizer166->Add( m_hyperlink2, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer166->Add( 0, 0, 1, wxEXPAND, 5 ); + + + bSizer181->Add( bSizer166, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + m_staticline34 = new wxStaticLine( m_panel41, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bSizer181->Add( m_staticline34, 0, wxEXPAND, 5 ); + + m_staticText93 = new wxStaticText( m_panel41, wxID_ANY, _("Published under the GNU General Public License"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText93->Wrap( -1 ); + bSizer181->Add( m_staticText93, 0, wxALL, 5 ); + + wxBoxSizer* bSizer1671; + bSizer1671 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer1671->Add( 0, 0, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_bitmap13 = new wxStaticBitmap( m_panel41, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer1671->Add( m_bitmap13, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_hyperlink5 = new wxHyperlinkCtrl( m_panel41, wxID_ANY, _("http://www.gnu.org/licenses/gpl.html"), wxT("http://www.gnu.org/licenses/gpl.html"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_hyperlink5->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + + bSizer1671->Add( m_hyperlink5, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer1671->Add( 0, 0, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer181->Add( bSizer1671, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + + bSizer174->Add( bSizer181, 0, 0, 5 ); + + m_staticline37 = new wxStaticLine( m_panel41, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ); + bSizer174->Add( m_staticline37, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer177; + bSizer177 = new wxBoxSizer( wxVERTICAL ); + + m_staticText54 = new wxStaticText( m_panel41, wxID_ANY, _("Many thanks for localization:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText54->Wrap( 200 ); + m_staticText54->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) ); + + bSizer177->Add( m_staticText54, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); + + + bSizer177->Add( 0, 5, 0, 0, 5 ); + + m_scrolledWindowTranslators = new wxScrolledWindow( m_panel41, wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), wxVSCROLL ); + m_scrolledWindowTranslators->SetScrollRate( 10, 10 ); + m_scrolledWindowTranslators->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + m_scrolledWindowTranslators->SetMinSize( wxSize( 220,-1 ) ); + + fgSizerTranslators = new wxFlexGridSizer( 0, 2, 2, 10 ); + fgSizerTranslators->SetFlexibleDirection( wxBOTH ); + fgSizerTranslators->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + + m_scrolledWindowTranslators->SetSizer( fgSizerTranslators ); + m_scrolledWindowTranslators->Layout(); + fgSizerTranslators->Fit( m_scrolledWindowTranslators ); + bSizer177->Add( m_scrolledWindowTranslators, 1, wxALIGN_CENTER_HORIZONTAL|wxLEFT|wxEXPAND, 5 ); + + + bSizer174->Add( bSizer177, 0, wxEXPAND, 5 ); + + + bSizer162->Add( bSizer174, 0, 0, 5 ); + + + m_panel41->SetSizer( bSizer162 ); + m_panel41->Layout(); + bSizer162->Fit( m_panel41 ); + bSizer31->Add( m_panel41, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + + m_staticline36 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bSizer31->Add( m_staticline36, 0, wxEXPAND, 5 ); + + bSizerStdButtons = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonClose = new wxButton( this, wxID_OK, _("Close"), wxDefaultPosition, wxSize( -1,30 ), 0 ); + m_buttonClose->SetDefault(); + bSizerStdButtons->Add( m_buttonClose, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer31->Add( bSizerStdButtons, 0, wxALIGN_RIGHT, 5 ); + + + this->SetSizer( bSizer31 ); + this->Layout(); + bSizer31->Fit( this ); + + this->Centre( wxBOTH ); + + // Connect Events + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( AboutDlgGenerated::OnClose ) ); + m_buttonDonate->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AboutDlgGenerated::OnDonate ), NULL, this ); + m_buttonClose->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AboutDlgGenerated::OnOK ), NULL, this ); +} + +AboutDlgGenerated::~AboutDlgGenerated() +{ + // Disconnect Events + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( AboutDlgGenerated::OnClose ) ); + m_buttonDonate->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AboutDlgGenerated::OnDonate ), NULL, this ); + m_buttonClose->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AboutDlgGenerated::OnOK ), NULL, this ); + +} diff --git a/ui/gui_generated.h b/ui/gui_generated.h index f06ebf93..a590e2c2 100644 --- a/ui/gui_generated.h +++ b/ui/gui_generated.h @@ -14,8 +14,7 @@ class ExecFinishedBox; class FolderHistoryBox; class ToggleButton; -class wxStaticText; -namespace zen{ class BitmapButton; } +namespace zen{ class BitmapTextButton; } namespace zen{ class Graph2D; } namespace zen{ class Grid; } namespace zen{ class TripleSplitter; } @@ -29,19 +28,19 @@ namespace zen{ class TripleSplitter; } #include <wx/font.h> #include <wx/colour.h> #include <wx/settings.h> -#include <wx/stattext.h> #include <wx/button.h> -#include <wx/sizer.h> #include <wx/bmpbuttn.h> +#include <wx/sizer.h> #include <wx/panel.h> +#include <wx/stattext.h> #include <wx/combobox.h> #include <wx/scrolwin.h> #include <wx/statbmp.h> #include <wx/statline.h> -#include <wx/listbox.h> +#include <wx/textctrl.h> #include <wx/checkbox.h> +#include <wx/listbox.h> #include <wx/frame.h> -#include <wx/textctrl.h> #include <wx/gauge.h> #include <wx/animate.h> #include <wx/notebook.h> @@ -49,9 +48,9 @@ namespace zen{ class TripleSplitter; } #include <wx/tglbtn.h> #include <wx/choice.h> #include <wx/spinctrl.h> -#include <wx/hyperlink.h> #include <wx/grid.h> #include <wx/calctrl.h> +#include <wx/hyperlink.h> #include "../zen/i18n.h" @@ -87,13 +86,11 @@ class MainDialogGenerated : public wxFrame wxBoxSizer* bSizerPanelHolder; wxPanel* m_panelTopButtons; wxBoxSizer* bSizerTopButtons; - wxStaticText* m_staticTextCmpVariant; - zen::BitmapButton* m_buttonCompare; - zen::BitmapButton* m_buttonCancel; + zen::BitmapTextButton* m_buttonCompare; + zen::BitmapTextButton* m_buttonCancel; wxBitmapButton* m_bpButtonCmpConfig; - wxStaticText* m_staticTextSyncVariant; wxBitmapButton* m_bpButtonSyncConfig; - zen::BitmapButton* m_buttonSync; + zen::BitmapTextButton* m_buttonSync; wxPanel* m_panelDirectoryPairs; wxStaticText* m_staticTextResolvedPathL; wxBitmapButton* m_bpButtonAddPair; @@ -132,6 +129,11 @@ class MainDialogGenerated : public wxFrame wxStaticText* m_staticTextStatusRightFiles; wxStaticText* m_staticTextStatusRightBytes; wxStaticText* m_staticTextFullStatus; + wxPanel* m_panelSearch; + wxBitmapButton* m_bpButtonHideSearch; + wxStaticText* m_staticText101; + wxTextCtrl* m_textCtrlSearchTxt; + wxCheckBox* m_checkBoxMatchCase; wxPanel* m_panelConfig; wxBoxSizer* bSizerConfig; wxBitmapButton* m_bpButtonOpen; @@ -198,6 +200,8 @@ class MainDialogGenerated : public wxFrame virtual void OnAddFolderPair( wxCommandEvent& event ) { event.Skip(); } virtual void OnRemoveTopFolderPair( wxCommandEvent& event ) { event.Skip(); } virtual void OnSwapSides( wxCommandEvent& event ) { event.Skip(); } + virtual void OnHideSearchPanel( wxCommandEvent& event ) { event.Skip(); } + virtual void OnSearchGridEnter( wxCommandEvent& event ) { event.Skip(); } virtual void OnCfgHistoryKeyEvent( wxKeyEvent& event ) { event.Skip(); } virtual void OnLoadFromHistory( wxCommandEvent& event ) { event.Skip(); } virtual void OnLoadFromHistoryDoubleClick( wxCommandEvent& event ) { event.Skip(); } @@ -470,6 +474,7 @@ class SyncCfgDlgGenerated : public wxDialog wxStaticText* m_staticTextUpdate; wxToggleButton* m_toggleBtnCustom; wxStaticText* m_staticTextCustom; + wxCheckBox* m_checkBoxDetectMove; wxBoxSizer* bSizerExtraConfig; wxStaticLine* m_staticline321; wxBoxSizer* bSizer179; @@ -534,6 +539,7 @@ class SyncCfgDlgGenerated : public wxDialog virtual void OnSyncUpdate( wxCommandEvent& event ) { event.Skip(); } virtual void OnSyncCustomDouble( wxMouseEvent& event ) { event.Skip(); } virtual void OnSyncCustom( wxCommandEvent& event ) { event.Skip(); } + virtual void OnToggleDetectMovedFiles( wxCommandEvent& event ) { event.Skip(); } virtual void OnErrorIgnore( wxCommandEvent& event ) { event.Skip(); } virtual void OnErrorPopup( wxCommandEvent& event ) { event.Skip(); } virtual void OnDeletionPermanent( wxCommandEvent& event ) { event.Skip(); } @@ -568,14 +574,14 @@ class BatchDlgGenerated : public wxDialog protected: wxStaticBitmap* m_bitmapBatchJob; wxStaticText* m_staticTextHeader; - wxStaticText* m_staticText44; + wxStaticText* m_staticTextDescr; wxBitmapButton* m_bpButtonHelp; wxStaticLine* m_staticline18; wxPanel* m_panel35; wxStaticText* m_staticText82; wxToggleButton* m_toggleBtnErrorIgnore; wxToggleButton* m_toggleBtnErrorPopup; - wxToggleButton* m_toggleBtnErrorExit; + wxToggleButton* m_toggleBtnErrorAbort; wxStaticLine* m_staticline26; wxStaticText* m_staticText81; ExecFinishedBox* m_comboBoxExecFinished; @@ -596,7 +602,7 @@ class BatchDlgGenerated : public wxDialog virtual void OnHelp( wxCommandEvent& event ) { event.Skip(); } virtual void OnErrorIgnore( wxCommandEvent& event ) { event.Skip(); } virtual void OnErrorPopup( wxCommandEvent& event ) { event.Skip(); } - virtual void OnErrorExit( wxCommandEvent& event ) { event.Skip(); } + virtual void OnErrorAbort( wxCommandEvent& event ) { event.Skip(); } virtual void OnToggleGenerateLogfile( wxCommandEvent& event ) { event.Skip(); } virtual void OnToggleLogfilesLimit( wxCommandEvent& event ) { event.Skip(); } virtual void OnSaveBatchJob( wxCommandEvent& event ) { event.Skip(); } @@ -612,66 +618,6 @@ class BatchDlgGenerated : public wxDialog }; /////////////////////////////////////////////////////////////////////////////// -/// Class AboutDlgGenerated -/////////////////////////////////////////////////////////////////////////////// -class AboutDlgGenerated : public wxDialog -{ - private: - - protected: - wxPanel* m_panel41; - wxStaticBitmap* m_bitmapLogo; - wxStaticLine* m_staticline341; - wxStaticText* m_build; - wxStaticLine* m_staticline3411; - wxStaticText* m_staticText72; - wxHyperlinkCtrl* m_hyperlink11; - wxHyperlinkCtrl* m_hyperlink9; - wxHyperlinkCtrl* m_hyperlink10; - wxHyperlinkCtrl* m_hyperlink7; - wxHyperlinkCtrl* m_hyperlink14; - wxHyperlinkCtrl* m_hyperlink15; - wxHyperlinkCtrl* m_hyperlink13; - wxHyperlinkCtrl* m_hyperlink16; - wxHyperlinkCtrl* m_hyperlink12; - wxHyperlinkCtrl* m_hyperlink18; - wxPanel* m_panel40; - wxPanel* m_panel39; - wxStaticText* m_staticText83; - wxButton* m_buttonDonate; - wxAnimationCtrl* m_animCtrlWink; - wxScrolledWindow* m_scrolledWindowTranslators; - wxBoxSizer* bSizerTranslators; - wxStaticText* m_staticText54; - wxFlexGridSizer* fgSizerTranslators; - wxStaticLine* m_staticline43; - wxStaticText* m_staticText94; - wxHyperlinkCtrl* m_hyperlink1; - wxStaticBitmap* m_bitmap9; - wxHyperlinkCtrl* m_hyperlink2; - wxStaticBitmap* m_bitmap10; - wxStaticLine* m_staticline34; - wxStaticText* m_staticText93; - wxStaticBitmap* m_bitmap13; - wxHyperlinkCtrl* m_hyperlink5; - wxStaticLine* m_staticline36; - wxBoxSizer* bSizerStdButtons; - wxButton* m_buttonClose; - - // Virtual event handlers, overide them in your derived class - virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } - virtual void OnDonate( wxCommandEvent& event ) { event.Skip(); } - virtual void OnOK( wxCommandEvent& event ) { event.Skip(); } - - - public: - - AboutDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); - ~AboutDlgGenerated(); - -}; - -/////////////////////////////////////////////////////////////////////////////// /// Class MessageDlgGenerated /////////////////////////////////////////////////////////////////////////////// class MessageDlgGenerated : public wxDialog @@ -815,7 +761,7 @@ class GlobalSettingsDlgGenerated : public wxDialog wxCheckBox* m_checkBoxCopyPermissions; wxStaticText* m_staticText8211; wxStaticLine* m_staticline191; - zen::BitmapButton* m_buttonResetDialogs; + zen::BitmapTextButton* m_buttonResetDialogs; wxStaticLine* m_staticline192; wxStaticText* m_staticText85; wxBitmapButton* m_bpButtonAddRow; @@ -863,61 +809,92 @@ class PopupDialogGenerated : public wxDialog }; /////////////////////////////////////////////////////////////////////////////// -/// Class SearchDialogGenerated +/// Class SelectTimespanDlgGenerated /////////////////////////////////////////////////////////////////////////////// -class SearchDialogGenerated : public wxDialog +class SelectTimespanDlgGenerated : public wxDialog { private: protected: - wxStaticText* m_staticText101; - wxTextCtrl* m_textCtrlSearchTxt; - wxCheckBox* m_checkBoxMatchCase; - wxButton* m_buttonFindNext; - wxButton* m_button29; + wxPanel* m_panel35; + wxCalendarCtrl* m_calendarFrom; + wxCalendarCtrl* m_calendarTo; + wxStaticLine* m_staticline21; + wxBoxSizer* bSizerStdButtons; + wxButton* m_buttonOkay; + wxButton* m_buttonCancel; // Virtual event handlers, overide them in your derived class virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } - virtual void OnText( wxCommandEvent& event ) { event.Skip(); } - virtual void OnFindNext( wxCommandEvent& event ) { event.Skip(); } + virtual void OnChangeSelectionFrom( wxCalendarEvent& event ) { event.Skip(); } + virtual void OnChangeSelectionTo( wxCalendarEvent& event ) { event.Skip(); } + virtual void OnOkay( wxCommandEvent& event ) { event.Skip(); } virtual void OnCancel( wxCommandEvent& event ) { event.Skip(); } public: - SearchDialogGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Find"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); - ~SearchDialogGenerated(); + SelectTimespanDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Select time span"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + ~SelectTimespanDlgGenerated(); }; /////////////////////////////////////////////////////////////////////////////// -/// Class SelectTimespanDlgGenerated +/// Class AboutDlgGenerated /////////////////////////////////////////////////////////////////////////////// -class SelectTimespanDlgGenerated : public wxDialog +class AboutDlgGenerated : public wxDialog { private: protected: - wxPanel* m_panel35; - wxCalendarCtrl* m_calendarFrom; - wxCalendarCtrl* m_calendarTo; - wxStaticLine* m_staticline21; + wxPanel* m_panel41; + wxStaticBitmap* m_bitmapLogo; + wxStaticLine* m_staticline341; + wxStaticText* m_build; + wxStaticLine* m_staticline3411; + wxStaticText* m_staticText96; + wxHyperlinkCtrl* m_hyperlink11; + wxHyperlinkCtrl* m_hyperlink9; + wxHyperlinkCtrl* m_hyperlink10; + wxHyperlinkCtrl* m_hyperlink7; + wxHyperlinkCtrl* m_hyperlink14; + wxHyperlinkCtrl* m_hyperlink15; + wxHyperlinkCtrl* m_hyperlink13; + wxHyperlinkCtrl* m_hyperlink16; + wxHyperlinkCtrl* m_hyperlink12; + wxHyperlinkCtrl* m_hyperlink18; + wxPanel* m_panelDonate; + wxPanel* m_panel39; + wxAnimationCtrl* m_animCtrlWink; + wxStaticText* m_staticText83; + wxButton* m_buttonDonate; + wxStaticText* m_staticText94; + wxStaticBitmap* m_bitmap9; + wxHyperlinkCtrl* m_hyperlink1; + wxStaticBitmap* m_bitmap10; + wxHyperlinkCtrl* m_hyperlink2; + wxStaticLine* m_staticline34; + wxStaticText* m_staticText93; + wxStaticBitmap* m_bitmap13; + wxHyperlinkCtrl* m_hyperlink5; + wxStaticLine* m_staticline37; + wxStaticText* m_staticText54; + wxScrolledWindow* m_scrolledWindowTranslators; + wxFlexGridSizer* fgSizerTranslators; + wxStaticLine* m_staticline36; wxBoxSizer* bSizerStdButtons; - wxButton* m_buttonOkay; - wxButton* m_buttonCancel; + wxButton* m_buttonClose; // Virtual event handlers, overide them in your derived class virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } - virtual void OnChangeSelectionFrom( wxCalendarEvent& event ) { event.Skip(); } - virtual void OnChangeSelectionTo( wxCalendarEvent& event ) { event.Skip(); } - virtual void OnOkay( wxCommandEvent& event ) { event.Skip(); } - virtual void OnCancel( wxCommandEvent& event ) { event.Skip(); } + virtual void OnDonate( wxCommandEvent& event ) { event.Skip(); } + virtual void OnOK( wxCommandEvent& event ) { event.Skip(); } public: - SelectTimespanDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Select time span"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); - ~SelectTimespanDlgGenerated(); + AboutDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); + ~AboutDlgGenerated(); }; diff --git a/ui/gui_status_handler.cpp b/ui/gui_status_handler.cpp index 0131af3f..0816f2f1 100644 --- a/ui/gui_status_handler.cpp +++ b/ui/gui_status_handler.cpp @@ -7,7 +7,7 @@ #include "gui_status_handler.h" #include <wx/wupdlock.h> #include <wx+/shell_execute.h> -#include <wx+/button.h> +#include <wx+/bitmap_button.h> #include <wx/app.h> #include "msg_popup.h" #include "main_dlg.h" @@ -238,12 +238,12 @@ SyncStatusHandler::~SyncStatusHandler() if (!abortIsRequested()) //if aborted (manually), we don't execute the command { const std::wstring finalCommand = progressDlg->getExecWhenFinishedCommand(); //final value (after possible user modification) - if (isCloseProgressDlgCommand(finalCommand)) - showFinalResults = false; //take precedence over current visibility status - else if (!finalCommand.empty()) + if (!finalCommand.empty()) { - auto cmdexp = expandMacros(utfCvrtTo<Zstring>(finalCommand)); - shellExecute(cmdexp); + if (isCloseProgressDlgCommand(finalCommand)) + showFinalResults = false; //take precedence over current visibility status + else + shellExecute(expandMacros(utfCvrtTo<Zstring>(finalCommand))); } } diff --git a/ui/main_dlg.cpp b/ui/main_dlg.cpp index eaae0545..c84606f4 100644 --- a/ui/main_dlg.cpp +++ b/ui/main_dlg.cpp @@ -18,7 +18,7 @@ #include <wx/display.h> #include <wx+/context_menu.h> #include <wx+/string_conv.h> -#include <wx+/button.h> +#include <wx+/bitmap_button.h> #include <wx+/shell_execute.h> #include <wx+/app_main.h> #include <wx+/toggle_button.h> @@ -46,6 +46,10 @@ #include "../lib/lock_holder.h" #include "../lib/localization.h" +#ifdef ZEN_MAC +#include <ApplicationServices/ApplicationServices.h> +#endif + using namespace zen; using namespace std::rel_ops; @@ -56,11 +60,6 @@ struct wxClientHistoryData : public wxClientData //we need a wxClientData derive { wxClientHistoryData(const Zstring& cfgFile, int lastUseIndex) : cfgFile_(cfgFile), lastUseIndex_(lastUseIndex) {} - //~wxClientHistoryData() - //{ - // std::cerr << cfgFile_.c_str() << "\n"; - //} - Zstring cfgFile_; int lastUseIndex_; //support sorting history by last usage, the higher the index the more recent the usage }; @@ -276,7 +275,7 @@ private: namespace { -//workaround for wxWidgets: small hack to update menu items: actually this is a wxWidgets bug (affects Windows- and Linux-build) +//workaround for wxWidgets bug failing to update menu item bitmaps (affects Windows- and Linux-build) void setMenuItemImage(wxMenuItem*& menuItem, const wxBitmap& bmp) { assert(menuItem->GetKind() == wxITEM_NORMAL); @@ -291,14 +290,21 @@ void setMenuItemImage(wxMenuItem*& menuItem, const wxBitmap& bmp) if (pos != wxNOT_FOUND) { /* - menu->Remove(item); ->this simple sequence crashes on Kubuntu x64, wxWidgets 2.9.2 - menu->Insert(index, item); + menu->Remove(menuItem); ->this simple sequence crashes on Kubuntu x64, wxWidgets 2.9.2 + menu->Insert(pos, menuItem); */ const bool enabled = menuItem->IsEnabled(); wxMenuItem* newItem = new wxMenuItem(menu, menuItem->GetId(), menuItem->GetItemLabel()); - newItem->SetBitmap(bmp); - menu->Destroy(menuItem); //actual workaround + newItem->SetBitmap(bmp); +#ifdef __WXMSW__ //not availabe on wxGTK or wxOSX + //for some inconceivable reason wxWidgets is not consistent with itself and renders disabled icons + //just greyscale instead of brightened like bitmap buttons; much better: + newItem->SetDisabledBitmap(bmp.ConvertToDisabled()); +#endif + bool isDestroyed = menu->Destroy(menuItem); //actual workaround + assert(isDestroyed); + (void)isDestroyed; menuItem = menu->Insert(pos, newItem); //don't forget to update input item pointer! if (!enabled) @@ -408,6 +414,13 @@ void MainDialog::create(const xmlAccess::XmlGuiConfig& guiCfg, MainDialog* frame = new MainDialog(guiCfg, referenceFiles, globSett, startComparison); frame->Show(); +#ifdef ZEN_MAC + ProcessSerialNumber psn = { 0, kCurrentProcess }; + ::TransformProcessType(&psn, kProcessTransformToForegroundApplication); //show dock icon, even if we're not an application bundle + //if the executable is not yet in a bundle or if it is called through a launcher, we need to set focus manually: + ::SetFrontProcess(&psn); +#endif + } @@ -417,7 +430,8 @@ MainDialog::MainDialog(const xmlAccess::XmlGuiConfig& guiCfg, bool startComparison) : MainDialogGenerated(nullptr), folderHistoryLeft (std::make_shared<FolderHistory>()), //make sure it is always bound - folderHistoryRight(std::make_shared<FolderHistory>()) // + folderHistoryRight(std::make_shared<FolderHistory>()), // + focusWindowAfterSearch(nullptr) { m_directoryLeft ->init(folderHistoryLeft); m_directoryRight->init(folderHistoryRight); @@ -431,7 +445,6 @@ MainDialog::MainDialog(const xmlAccess::XmlGuiConfig& guiCfg, setRelativeFontSize(*m_buttonCompare, 1.5); setRelativeFontSize(*m_buttonSync, 1.5); setRelativeFontSize(*m_buttonCancel, 1.5); - m_buttonCancel->refreshButtonLabel(); //required after font change! //---------------- support for dockable gui style -------------------------------- bSizerPanelHolder->Detach(m_panelTopButtons); @@ -455,6 +468,9 @@ MainDialog::MainDialog(const xmlAccess::XmlGuiConfig& guiCfg, auiMgr.AddPane(m_panelDirectoryPairs, wxAuiPaneInfo().Name(L"Panel2").Layer(2).Top().Caption(_("Folder pairs")).CaptionVisible(false).PaneBorder(false).Gripper()); + auiMgr.AddPane(m_panelSearch, + wxAuiPaneInfo().Name(L"PanelFind").Layer(2).Bottom().Caption(_("Find")).CaptionVisible(false).PaneBorder(false).Gripper().MinSize(200, m_bpButtonHideSearch->GetSize().GetHeight()).Hide()); + auiMgr.AddPane(m_gridNavi, wxAuiPaneInfo().Name(L"Panel10").Layer(3).Left().Position(1).Caption(_("Overview")).MinSize(300, m_gridNavi->GetSize().GetHeight())); //MinSize(): just default size, see comment below @@ -524,12 +540,17 @@ MainDialog::MainDialog(const xmlAccess::XmlGuiConfig& guiCfg, m_gridMainR->Connect(EVENT_GRID_MOUSE_LEFT_DOUBLE, GridClickEventHandler(MainDialog::onGridDoubleClickR), nullptr, this ); m_gridNavi->Connect(EVENT_GRID_SELECT_RANGE, GridRangeSelectEventHandler(MainDialog::onNaviSelection), nullptr, this); + //---------------------------------------------------------------------------------- + + m_panelSearch->Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(MainDialog::OnSearchPanelKeyPressed), nullptr, this); //set tool tips with (non-translated!) short cut hint m_bpButtonOpen ->SetToolTip(_("Open...") + L" (Ctrl+O)"); m_bpButtonSave ->SetToolTip(_("Save") + L" (Ctrl+S)"); - m_buttonCompare->SetToolTip(_("Compare both sides") + L" (F5)"); - m_buttonSync ->SetToolTip(_("Start synchronization") + L" (F6)"); + m_buttonCompare ->SetToolTip(_("Compare both sides") + L" (F5)"); + m_bpButtonCmpConfig ->SetToolTip(_("Comparison settings") + L" (F6)"); + m_bpButtonSyncConfig->SetToolTip(_("Synchronization settings") + L" (F7)"); + m_buttonSync ->SetToolTip(_("Start synchronization") + L" (F8)"); gridDataView = std::make_shared<GridView>(); treeDataView = std::make_shared<TreeView>(); @@ -560,12 +581,16 @@ MainDialog::MainDialog(const xmlAccess::XmlGuiConfig& guiCfg, setConfig(guiCfg, referenceFiles); //set icons for this dialog - m_buttonCompare ->setBitmapFront(getResourceImage(L"compare"), 5); m_bpButtonSyncConfig->SetBitmapLabel(getResourceImage(L"cfg_sync")); m_bpButtonCmpConfig ->SetBitmapLabel(getResourceImage(L"cfg_compare")); m_bpButtonOpen ->SetBitmapLabel(getResourceImage(L"load")); m_bpButtonBatchJob ->SetBitmapLabel(getResourceImage(L"batch")); m_bpButtonAddPair ->SetBitmapLabel(getResourceImage(L"item_add")); + m_bpButtonHideSearch->SetBitmapLabel(getResourceImage(L"close_panel")); + + //we can't use a wxButton for cancel: it's rendered smaller on OS X than a wxBitmapButton! + setBitmapTextLabel(*m_buttonCancel, wxImage(), m_buttonCancel->GetLabel()); + { IconBuffer tmp(IconBuffer::SIZE_SMALL); const wxBitmap& bmpFile = tmp.genericFileIcon(); @@ -577,8 +602,6 @@ MainDialog::MainDialog(const xmlAccess::XmlGuiConfig& guiCfg, m_bitmapSmallFileRight ->SetBitmap(bmpFile); } - m_panelTopButtons->Layout(); //wxButtonWithImage size might have changed - const int dummySize = 5; wxImage dummyImg(dummySize, dummySize); if (!dummyImg.HasAlpha()) @@ -826,6 +849,7 @@ void MainDialog::setGlobalCfgOnInit(const xmlAccess::XmlGlobalSettings& globalSe cfgFileNames.push_back(lastRunConfigName()); //make sure <Last session> is always part of history list (if existing) addFileToCfgHistory(cfgFileNames); + removeObsoleteCfgHistoryItems(cfgFileNames); //remove non-existent items (we need this only on startup) //-------------------------------------------------------------------------------- @@ -837,6 +861,8 @@ void MainDialog::setGlobalCfgOnInit(const xmlAccess::XmlGlobalSettings& globalSe gridview::setupIcons(*m_gridMainL, *m_gridMainC, *m_gridMainR, globalSettings.gui.showIcons, convert(globalSettings.gui.iconSize)); //------------------------------------------------------------------------------------------------ + m_checkBoxMatchCase->SetValue(globalCfg.gui.textSearchRespectCase); + //wxAuiManager erroneously loads panel captions, we don't want that typedef std::vector<std::pair<wxString, wxString> > CaptionNameMapping; CaptionNameMapping captionNameMap; @@ -853,6 +879,8 @@ void MainDialog::setGlobalCfgOnInit(const xmlAccess::XmlGlobalSettings& globalSe //if MainDialog::onQueryEndSession() is called while comparison is active, this panel is saved and restored as "visible" auiMgr.GetPane(compareStatus->getAsWindow()).Hide(); + auiMgr.GetPane(m_panelSearch).Hide(); //no need to show it on startup + m_menuItemCheckVersionAuto->Check(globalCfg.gui.lastUpdateCheck != -1); auiMgr.Update(); @@ -886,6 +914,8 @@ xmlAccess::XmlGlobalSettings MainDialog::getGlobalCfgBeforeExit() for (unsigned int i = 0; i < m_listBoxHistory->GetCount(); ++i) if (auto clientString = dynamic_cast<const wxClientHistoryData*>(m_listBoxHistory->GetClientObject(i))) historyDetail.insert(std::make_pair(clientString->lastUseIndex_, clientString->cfgFile_)); + else + assert(false); //sort by last use; put most recent items *first* (looks better in xml than the reverse) std::vector<Zstring> history; @@ -902,6 +932,8 @@ xmlAccess::XmlGlobalSettings MainDialog::getGlobalCfgBeforeExit() globalSettings.gui.folderHistoryLeft = folderHistoryLeft ->getList(); globalSettings.gui.folderHistoryRight = folderHistoryRight->getList(); + globalSettings.gui.textSearchRespectCase = m_checkBoxMatchCase->GetValue(); + globalSettings.gui.guiPerspectiveLast = auiMgr.SavePerspective(); //we need to portably retrieve non-iconized, non-maximized size and position (non-portable: GetWindowPlacement()) @@ -1196,7 +1228,7 @@ void MainDialog::deleteSelectedFiles(const std::vector<FileSystemObject*>& selec deleteOnBothSides, globalCfg.gui.useRecyclerForManualDeletion) == ReturnSmallDlg::BUTTON_OKAY) { - wxBusyCursor dummy; //show hourglass cursor + //wxBusyCursor dummy; -> redundant: progress already shown in status bar! try { //handle errors when deleting files/folders @@ -1348,8 +1380,8 @@ void MainDialog::setStatusBarFileStatistics(size_t filesOnLeftView, size_t foldersOnLeftView, size_t filesOnRightView, size_t foldersOnRightView, - UInt64 filesizeLeftView, - UInt64 filesizeRightView) + zen::UInt64 filesizeLeftView, + zen::UInt64 filesizeRightView) { wxWindowUpdateLocker dummy(m_panelStatusBar); //avoid display distortion @@ -1357,14 +1389,13 @@ void MainDialog::setStatusBarFileStatistics(size_t filesOnLeftView, bSizerFileStatus->Show(true); m_staticTextFullStatus->Hide(); - //fill statistics //update status information bSizerStatusLeftDirectories->Show(foldersOnLeftView > 0); bSizerStatusLeftFiles ->Show(filesOnLeftView > 0); setText(*m_staticTextStatusLeftDirs, replaceCpy(_P("1 directory", "%x directories", foldersOnLeftView), L"%x", toGuiString(foldersOnLeftView), false)); setText(*m_staticTextStatusLeftFiles, replaceCpy(_P("1 file", "%x files", filesOnLeftView), L"%x", toGuiString(filesOnLeftView), false)); - setText(*m_staticTextStatusLeftBytes, filesizeToShortString(to<Int64>(filesizeLeftView))); + setText(*m_staticTextStatusLeftBytes, L"(" + filesizeToShortString(to<Int64>(filesizeLeftView)) + L")"); wxString statusMiddleNew; if (gridDataView->rowsTotal() > 0) @@ -1379,7 +1410,7 @@ void MainDialog::setStatusBarFileStatistics(size_t filesOnLeftView, setText(*m_staticTextStatusRightDirs, replaceCpy(_P("1 directory", "%x directories", foldersOnRightView), L"%x", toGuiString(foldersOnRightView), false)); setText(*m_staticTextStatusRightFiles, replaceCpy(_P("1 file", "%x files", filesOnRightView), L"%x", toGuiString(filesOnRightView), false)); - setText(*m_staticTextStatusRightBytes, filesizeToShortString(to<Int64>(filesizeRightView))); + setText(*m_staticTextStatusRightBytes, L"(" + filesizeToShortString(to<Int64>(filesizeRightView)) + L")"); //fill middle text (considering flashStatusInformation()) if (oldStatusMsgs.empty()) @@ -1463,7 +1494,7 @@ void MainDialog::disableAllElements(bool enableAbort) m_bpButtonSyncConfig ->Disable(); m_buttonSync ->Disable(); m_panelDirectoryPairs->Disable(); - m_panelCenter ->Disable(); + m_splitterMain ->Disable(); //includes m_panelCenter, but not m_panelStatusBar! m_panelViewFilter ->Disable(); m_panelFilter ->Disable(); m_panelConfig ->Disable(); @@ -1499,7 +1530,7 @@ void MainDialog::enableAllElements() m_bpButtonSyncConfig ->Enable(); m_buttonSync ->Enable(); m_panelDirectoryPairs->Enable(); - m_panelCenter ->Enable(); + m_splitterMain ->Enable(); m_panelViewFilter ->Enable(); m_panelFilter ->Enable(); m_panelConfig ->Enable(); @@ -1512,8 +1543,8 @@ void MainDialog::enableAllElements() m_buttonCompare->Enable(); m_buttonCompare->Show(); - m_panelTopButtons->Layout(); m_panelTopButtons->Enable(); + m_panelTopButtons->Layout(); //at least wxWidgets on OS X fails to do this after enabling: Refresh(); @@ -1752,7 +1783,7 @@ void MainDialog::onGridButtonEvent(wxKeyEvent& event, Grid& grid, bool leftSide) } -bool isPartOf(const wxWindow* child, const wxWindow* top) +bool isComponentOf(const wxWindow* child, const wxWindow* top) { for (const wxWindow* wnd = child; wnd != nullptr; wnd = wnd->GetParent()) if (wnd == top) @@ -1788,22 +1819,46 @@ void MainDialog::OnGlobalKeyEvent(wxKeyEvent& event) //process key events withou switch (keyCode) { case 'F': //CTRL + F - zen::startFind(this, *m_gridMainL, *m_gridMainR, globalCfg.gui.textSearchRespectCase); + showFindPanel(); return; //-> swallow event! } switch (keyCode) { - case WXK_F3: //F3 - case WXK_NUMPAD_F3: // - zen::findNext(this, *m_gridMainL, *m_gridMainR, globalCfg.gui.textSearchRespectCase); + case WXK_F3: + case WXK_NUMPAD_F3: + startFindNext(); return; //-> swallow event! - case WXK_F8: //F8 + case WXK_F6: + { + wxCommandEvent dummy2(wxEVT_COMMAND_BUTTON_CLICKED); //simulate button click + if (wxEvtHandler* evtHandler = m_bpButtonCmpConfig->GetEventHandler()) + evtHandler->ProcessEvent(dummy2); //synchronous call + } + return; //-> swallow event! + + case WXK_F7: + { + wxCommandEvent dummy2(wxEVT_COMMAND_BUTTON_CLICKED); //simulate button click + if (wxEvtHandler* evtHandler = m_bpButtonSyncConfig->GetEventHandler()) + evtHandler->ProcessEvent(dummy2); //synchronous call + } + return; //-> swallow event! + + case WXK_F9: setViewTypeSyncAction(!m_bpButtonViewTypeSyncAction->isActive()); return; //-> swallow event! - //redirect certain (unhandled) keys directly to grid! + case WXK_F10: + { + wxCommandEvent dummy2(wxEVT_COMMAND_BUTTON_CLICKED); //simulate button click + if (wxEvtHandler* evtHandler = m_bpButtonFilter->GetEventHandler()) + evtHandler->ProcessEvent(dummy2); //synchronous call + } + return; //-> swallow event! + + //redirect certain (unhandled) keys directly to grid! case WXK_UP: case WXK_DOWN: case WXK_LEFT: @@ -1823,14 +1878,15 @@ void MainDialog::OnGlobalKeyEvent(wxKeyEvent& event) //process key events withou case WXK_NUMPAD_END: { const wxWindow* focus = wxWindow::FindFocus(); - if (!isPartOf(focus, m_gridMainL ) && // - !isPartOf(focus, m_gridMainC ) && //don't propagate keyboard commands if grid is already in focus - !isPartOf(focus, m_gridMainR ) && // - !isPartOf(focus, m_gridNavi ) && - !isPartOf(focus, m_listBoxHistory) && //don't propagate if selecting config - !isPartOf(focus, m_directoryLeft) && //don't propagate if changing directory field - !isPartOf(focus, m_directoryRight) && - !isPartOf(focus, m_scrolledWindowFolderPairs)) + if (!isComponentOf(focus, m_gridMainL ) && // + !isComponentOf(focus, m_gridMainC ) && //don't propagate keyboard commands if grid is already in focus + !isComponentOf(focus, m_gridMainR ) && // + !isComponentOf(focus, m_gridNavi ) && + !isComponentOf(focus, m_listBoxHistory) && //don't propagate if selecting config + !isComponentOf(focus, m_directoryLeft ) && //don't propagate if changing directory field + !isComponentOf(focus, m_directoryRight) && + !isComponentOf(focus, m_panelSearch ) && + !isComponentOf(focus, m_scrolledWindowFolderPairs)) if (wxEvtHandler* evtHandler = m_gridMainL->getMainWin().GetEventHandler()) { m_gridMainL->SetFocus(); @@ -1875,12 +1931,11 @@ void MainDialog::onNaviSelection(GridRangeSelectEvent& event) { leadRow = std::max<ptrdiff_t>(0, leadRow - 1); //scroll one more row - m_gridMainL->scrollTo(leadRow); - m_gridMainC->scrollTo(leadRow); - m_gridMainR->scrollTo(leadRow); + m_gridMainL->scrollTo(leadRow); //scroll all of them (includes the "scroll master") + m_gridMainC->scrollTo(leadRow); // + m_gridMainR->scrollTo(leadRow); // m_gridNavi->getMainWin().Update(); //draw cursor immediately rather than on next idle event (required for slow CPUs, netbook) - } //get selection on navigation tree and set corresponding markers on main grid @@ -1938,6 +1993,27 @@ void MainDialog::onNaviGridContext(GridClickEvent& event) //Gtk requires "no spaces" for shortcut identifiers! menu.addSeparator(); } + + //---------------------------------------------------------------------------------------------------- + //FILE FILTER + auto addFilterMenu = [&](const std::wstring& label, const wxString& iconName, bool include) + { + if (selection.size() == 1) + { + //by relative path + menu.addItem(label + L" " + (FILE_NAME_SEPARATOR + selection[0]->getObjRelativeName()), + [this, &selection, include] { filterItems(selection, include); }, &getResourceImage(iconName)); + } + else if (selection.size() > 1) + { + //by relative path + menu.addItem(label + L" <" + _("multiple selection") + L">", + [this, &selection, include] { filterItems(selection, include); }, &getResourceImage(iconName)); + } + }; + addFilterMenu(_("Include via filter:"), L"filter_include_small", true); + addFilterMenu(_("Exclude via filter:"), L"filter_exclude_small", false); + //---------------------------------------------------------------------------------------------------- if (!selection.empty()) { @@ -1950,23 +2026,9 @@ void MainDialog::onNaviGridContext(GridClickEvent& event) menu.addItem(_("Exclude temporarily") + L"\tSpace", [] {}, nullptr, false); //---------------------------------------------------------------------------------------------------- - //EXCLUDE FILTER - if (selection.size() == 1) - { - //by relative path - menu.addItem(_("Exclude via filter:") + L" " + (FILE_NAME_SEPARATOR + selection[0]->getObjRelativeName()), - [this, &selection] { excludeItems(selection); }, &getResourceImage(L"filterSmall")); - } - else if (selection.size() > 1) - { - //by relative path - menu.addItem(_("Exclude via filter:") + L" <" + _("multiple selection") + L">", - [this, &selection] { excludeItems(selection); }, &getResourceImage(L"filterSmall")); - } - - //---------------------------------------------------------------------------------------------------- //CONTEXT_DELETE_FILES menu.addSeparator(); + menu.addItem(_("Delete") + L"\tDelete", [&] { deleteSelectedFiles(selection, selection); }, nullptr, !selection.empty()); menu.popup(*this); @@ -2030,52 +2092,57 @@ void MainDialog::onMainGridContextRim(bool leftSide) //Gtk requires "no spaces" for shortcut identifiers! menu.addSeparator(); } - //---------------------------------------------------------------------------------------------------- - if (!selection.empty()) - { - if (selection[0]->isActive()) - menu.addItem(_("Exclude temporarily") + L"\tSpace", [this, &selection] { setFilterManually(selection, false); }, &getResourceImage(L"checkboxFalse")); - else - menu.addItem(_("Include temporarily") + L"\tSpace", [this, &selection] { setFilterManually(selection, true); }, &getResourceImage(L"checkboxTrue")); - } - else - menu.addItem(_("Exclude temporarily") + L"\tSpace", [] {}, nullptr, false); //---------------------------------------------------------------------------------------------------- - //EXCLUDE FILTER - if (selection.size() == 1) + //FILE FILTER + auto addFilterMenu = [&](const wxString& label, const wxString& iconName, bool include) { - ContextMenu submenu; - - //by extension - if (dynamic_cast<const DirPair*>(selection[0]) == nullptr) //non empty && no directory + if (selection.size() == 1) { - const Zstring filename = afterLast(selection[0]->getObjRelativeName(), FILE_NAME_SEPARATOR); - if (contains(filename, Zchar('.'))) //be careful: AfterLast would return the whole string if '.' were not found! - { - const Zstring extension = afterLast(filename, Zchar('.')); + ContextMenu submenu; - submenu.addItem(L"*." + utfCvrtTo<wxString>(extension), - [this, extension] { excludeExtension(extension); }); + //by extension + if (dynamic_cast<const DirPair*>(selection[0]) == nullptr) //non empty && no directory + { + const Zstring filename = afterLast(selection[0]->getObjRelativeName(), FILE_NAME_SEPARATOR); + if (contains(filename, Zchar('.'))) //be careful: AfterLast would return the whole string if '.' were not found! + { + const Zstring extension = afterLast(filename, Zchar('.')); + submenu.addItem(L"*." + utfCvrtTo<wxString>(extension), + [this, extension, include] { filterExtension(extension, include); }); + } } - } - //by short name - submenu.addItem(utfCvrtTo<wxString>(Zstring(Zstr("*")) + FILE_NAME_SEPARATOR + selection[0]->getObjShortName()), - [this, &selection] { excludeShortname(*selection[0]); }); + //by short name + submenu.addItem(utfCvrtTo<wxString>(Zstring(Zstr("*")) + FILE_NAME_SEPARATOR + selection[0]->getObjShortName()), + [this, &selection, include] { filterShortname(*selection[0], include); }); - //by relative path - submenu.addItem(utfCvrtTo<wxString>(FILE_NAME_SEPARATOR + selection[0]->getObjRelativeName()), - [this, &selection] { excludeItems(selection); }); + //by relative path + submenu.addItem(utfCvrtTo<wxString>(FILE_NAME_SEPARATOR + selection[0]->getObjRelativeName()), + [this, &selection, include] { filterItems(selection, include); }); - menu.addSubmenu(_("Exclude via filter:"), submenu, &getResourceImage(L"filterSmall")); - } - else if (selection.size() > 1) + menu.addSubmenu(label, submenu, &getResourceImage(iconName)); + } + else if (selection.size() > 1) + { + //by relative path + menu.addItem(label + L" <" + _("multiple selection") + L">", + [this, &selection, include] { filterItems(selection, include); }, &getResourceImage(iconName)); + } + }; + addFilterMenu(_("Include via filter:"), L"filter_include_small", true); + addFilterMenu(_("Exclude via filter:"), L"filter_exclude_small", false); + + //---------------------------------------------------------------------------------------------------- + if (!selection.empty()) { - //by relative path - menu.addItem(_("Exclude via filter:") + L" <" + _("multiple selection") + L">", - [this, &selection] { excludeItems(selection); }, &getResourceImage(L"filterSmall")); + if (selection[0]->isActive()) + menu.addItem(_("Exclude temporarily") + L"\tSpace", [this, &selection] { setFilterManually(selection, false); }, &getResourceImage(L"checkboxFalse")); + else + menu.addItem(_("Include temporarily") + L"\tSpace", [this, &selection] { setFilterManually(selection, true); }, &getResourceImage(L"checkboxTrue")); } + else + menu.addItem(_("Exclude temporarily") + L"\tSpace", [] {}, nullptr, false); //---------------------------------------------------------------------------------------------------- //CONTEXT_EXTERNAL_APP @@ -2117,76 +2184,83 @@ void MainDialog::onMainGridContextRim(bool leftSide) } -void MainDialog::excludeExtension(const Zstring& extension) + +void MainDialog::filterPhrase(const Zstring& phrase, bool include, bool addNewLine) { - const Zstring newExclude = Zstr("*.") + extension; + Zstring& filterString = [&]() -> Zstring& + { + if (include) + { + Zstring& includeFilter = currentCfg.mainCfg.globalFilter.includeFilter; + if (NameFilter::isNull(includeFilter, FilterConfig().excludeFilter)) //fancy way of checking for "*" include + includeFilter.clear(); + return includeFilter; + } + else + return currentCfg.mainCfg.globalFilter.excludeFilter; + }(); - //add to filter config - Zstring& excludeFilter = currentCfg.mainCfg.globalFilter.excludeFilter; - if (!excludeFilter.empty() && !endsWith(excludeFilter, Zstr(";")) && !endsWith(excludeFilter, Zstr("\n"))) - excludeFilter += Zstr("\n"); - excludeFilter += newExclude + Zstr(";"); //';' is appended to 'mark' that next exclude extension entry won't write to new line + if (addNewLine) + { + if (!filterString.empty() && !endsWith(filterString, Zstr("\n"))) + filterString += Zstr("\n"); + filterString += phrase; + } + else + { + if (!filterString.empty() && !endsWith(filterString, Zstr("\n")) && !endsWith(filterString, Zstr(";"))) + filterString += Zstr("\n"); + filterString += phrase + Zstr(";"); //';' is appended to 'mark' that next exclude extension entry won't write to new line + } updateGlobalFilterButton(); + if (include) + applyFilterConfig(); //user's temporary exclusions lost! + else //do not fully apply filter, just exclude new items: preserve user's temporary exclusions + { + std::for_each(begin(folderCmp), end(folderCmp), [&](BaseDirPair& baseDirObj) { addHardFiltering(baseDirObj, phrase); }); + updateGui(); + } +} - //do not fully apply filter, just exclude new items - std::for_each(begin(folderCmp), end(folderCmp), [&](BaseDirPair& baseDirObj) { addHardFiltering(baseDirObj, newExclude); }); - updateGui(); + +void MainDialog::filterExtension(const Zstring& extension, bool include) +{ + filterPhrase(Zstr("*.") + extension, include, false); } -void MainDialog::excludeShortname(const FileSystemObject& fsObj) +void MainDialog::filterShortname(const FileSystemObject& fsObj, bool include) { - Zstring newExclude = Zstring(Zstr("*")) + FILE_NAME_SEPARATOR + fsObj.getObjShortName(); + Zstring phrase = Zstring(Zstr("*")) + FILE_NAME_SEPARATOR + fsObj.getObjShortName(); const bool isDir = dynamic_cast<const DirPair*>(&fsObj) != nullptr; if (isDir) - newExclude += FILE_NAME_SEPARATOR; + phrase += FILE_NAME_SEPARATOR; - //add to filter config - Zstring& excludeFilter = currentCfg.mainCfg.globalFilter.excludeFilter; - if (!excludeFilter.empty() && !endsWith(excludeFilter, Zstr("\n"))) - excludeFilter += Zstr("\n"); - excludeFilter += newExclude; - - updateGlobalFilterButton(); - - //do not fully apply filter, just exclude new items - std::for_each(begin(folderCmp), end(folderCmp), [&](BaseDirPair& baseDirObj) { addHardFiltering(baseDirObj, newExclude); }); - updateGui(); + filterPhrase(phrase, include, true); } -void MainDialog::excludeItems(const std::vector<FileSystemObject*>& selection) +void MainDialog::filterItems(const std::vector<FileSystemObject*>& selection, bool include) { - if (!selection.empty()) //check needed to determine if filtering is needed + if (!selection.empty()) { - Zstring newExclude; + Zstring phrase; for (auto it = selection.begin(); it != selection.end(); ++it) { FileSystemObject* fsObj = *it; if (it != selection.begin()) - newExclude += Zstr("\n"); + phrase += Zstr("\n"); //#pragma warning(suppress: 6011) -> fsObj bound in this context! - newExclude += FILE_NAME_SEPARATOR + fsObj->getObjRelativeName(); + phrase += FILE_NAME_SEPARATOR + fsObj->getObjRelativeName(); const bool isDir = dynamic_cast<const DirPair*>(fsObj) != nullptr; if (isDir) - newExclude += FILE_NAME_SEPARATOR; + phrase += FILE_NAME_SEPARATOR; } - - //add to filter config - Zstring& excludeFilter = currentCfg.mainCfg.globalFilter.excludeFilter; - if (!excludeFilter.empty() && !endsWith(excludeFilter, Zstr("\n"))) - excludeFilter += Zstr("\n"); - excludeFilter += newExclude; - - updateGlobalFilterButton(); - - //do not fully apply filter, just exclude new items - std::for_each(begin(folderCmp), end(folderCmp), [&](BaseDirPair& baseDirObj) { addHardFiltering(baseDirObj, newExclude); }); - updateGui(); + filterPhrase(phrase, include, true); } } @@ -2196,10 +2270,10 @@ void MainDialog::onGridLabelContextC(GridClickEvent& event) ContextMenu menu; const bool actionView = m_bpButtonViewTypeSyncAction->isActive(); - menu.addRadio(_("Category") + (actionView ? L"\tF8" : L""), [&] { setViewTypeSyncAction(false); }, !actionView); - menu.addRadio(_("Action") + (!actionView ? L"\tF8" : L""), [&] { setViewTypeSyncAction(true ); }, actionView); + menu.addRadio(_("Category") + (actionView ? L"\tF9" : L""), [&] { setViewTypeSyncAction(false); }, !actionView); + menu.addRadio(_("Action") + (!actionView ? L"\tF9" : L""), [&] { setViewTypeSyncAction(true ); }, actionView); - //menu.addItem(_("Category") + L"\tF8", [&] { setViewTypeSyncAction(false); }, m_bpButtonViewTypeSyncAction->isActive() ? nullptr : &getResourceImage(L"compare_small")); + //menu.addItem(_("Category") + L"\tF9", [&] { setViewTypeSyncAction(false); }, m_bpButtonViewTypeSyncAction->isActive() ? nullptr : &getResourceImage(L"compare_small")); //menu.addItem(_("Action"), [&] { setViewTypeSyncAction(true ); }, m_bpButtonViewTypeSyncAction->isActive() ? &getResourceImage(L"sync_small") : nullptr); menu.popup(*this); } @@ -2219,30 +2293,23 @@ void MainDialog::onGridLabelContext(Grid& grid, ColumnTypeRim type, const std::v { ContextMenu menu; - auto toggleColumn = [&](const Grid::ColumnAttribute& ca) + auto toggleColumn = [&](ColumnType ct) { auto colAttr = grid.getColumnConfig(); - for (auto it = colAttr.begin(); it != colAttr.end(); ++it) - if (it->type_ == ca.type_) + for (Grid::ColumnAttribute& ca : colAttr) + if (ca.type_ == ct) { - it->visible_ = !ca.visible_; + ca.visible_ = !ca.visible_; grid.setColumnConfig(colAttr); return; } }; - if (auto prov = grid.getDataProvider()) - { - const auto& colAttr = grid.getColumnConfig(); - for (auto it = colAttr.begin(); it != colAttr.end(); ++it) - { - const Grid::ColumnAttribute& ca = *it; - - menu.addCheckBox(prov->getColumnLabel(ca.type_), [ca, toggleColumn] { toggleColumn(ca); }, + if (const GridData* prov = grid.getDataProvider()) + for (const Grid::ColumnAttribute& ca : grid.getColumnConfig()) + menu.addCheckBox(prov->getColumnLabel(ca.type_), [ca, toggleColumn] { toggleColumn(ca.type_); }, ca.visible_, ca.type_ != static_cast<ColumnType>(COL_TYPE_FILENAME)); //do not allow user to hide file name column! - } - } //---------------------------------------------------------------------------------------------- menu.addSeparator(); @@ -2309,7 +2376,9 @@ void MainDialog::OnContextSetLayout(wxMouseEvent& event) const wxAuiPaneInfoArray& paneArray = auiMgr.GetAllPanes(); for (size_t i = 0; i < paneArray.size(); ++i) - if (!paneArray[i].IsShown() && !paneArray[i].name.empty() && paneArray[i].window != compareStatus->getAsWindow()) + if (!paneArray[i].IsShown() && !paneArray[i].name.empty() && + paneArray[i].window != compareStatus->getAsWindow() && + paneArray[i].window != m_panelSearch) captionNameMap.push_back(std::make_pair(paneArray[i].caption, paneArray[i].name)); if (!captionNameMap.empty()) @@ -2364,10 +2433,10 @@ void MainDialog::OnSyncSettingsContext(wxMouseEvent& event) const auto currentVar = getConfig().mainCfg.syncCfg.directionCfg.var; - menu.addRadio(L"<- " + _("Two way") + L" ->" , [&] { setVariant(DirectionConfig::AUTOMATIC); }, currentVar == DirectionConfig::AUTOMATIC); - menu.addRadio( _("Mirror") + L" ->>", [&] { setVariant(DirectionConfig::MIRROR); }, currentVar == DirectionConfig::MIRROR); - menu.addRadio( _("Update") + L" ->" , [&] { setVariant(DirectionConfig::UPDATE); }, currentVar == DirectionConfig::UPDATE); - menu.addRadio( _("Custom") , [&] { setVariant(DirectionConfig::CUSTOM); }, currentVar == DirectionConfig::CUSTOM); + menu.addRadio(L"<- " + _("Two way") + L" ->" , [&] { setVariant(DirectionConfig::TWOWAY); }, currentVar == DirectionConfig::TWOWAY); + menu.addRadio( _("Mirror") + L" ->>", [&] { setVariant(DirectionConfig::MIRROR); }, currentVar == DirectionConfig::MIRROR); + menu.addRadio( _("Update") + L" ->" , [&] { setVariant(DirectionConfig::UPDATE); }, currentVar == DirectionConfig::UPDATE); + menu.addRadio( _("Custom") , [&] { setVariant(DirectionConfig::CUSTOM); }, currentVar == DirectionConfig::CUSTOM); menu.popup(*this); } @@ -2426,8 +2495,12 @@ void MainDialog::addFileToCfgHistory(const std::vector<Zstring>& filenames) const int itemCount = static_cast<int>(m_listBoxHistory->GetCount()); for (int i = 0; i < itemCount; ++i) if (auto histData = dynamic_cast<const wxClientHistoryData*>(m_listBoxHistory->GetClientObject(i))) + { if (EqualFilename()(filename, histData->cfgFile_)) return i; + } + else + assert(false); return -1; }(); @@ -2452,12 +2525,7 @@ void MainDialog::addFileToCfgHistory(const std::vector<Zstring>& filenames) //this prevents problems with m_listBoxHistory losing keyboard selection focus if identical selection is redundantly reapplied for (int pos = 0; pos < static_cast<int>(selections.size()); ++pos) if (m_listBoxHistory->IsSelected(pos) != selections[pos]) - { - if (selections[pos]) - m_listBoxHistory->SetSelection(pos); - else - m_listBoxHistory->Deselect(pos); - } + m_listBoxHistory->SetSelection(pos, selections[pos]); } @@ -2542,9 +2610,6 @@ void MainDialog::updateUnsavedCfgStatus() title += toWx(activeCfgFilename); else if (activeConfigFiles.size() > 1) { -#ifdef _MSC_VER -#pragma warning(disable:4428) // VC wrongly issues warning C4428: universal-character-name encountered in source -#endif const wchar_t* EM_DASH = L" \u2014 "; title += xmlAccess::extractJobName(activeConfigFiles[0]); std::for_each(activeConfigFiles.begin() + 1, activeConfigFiles.end(), [&](const Zstring& filename) { title += EM_DASH + xmlAccess::extractJobName(filename); }); @@ -2722,7 +2787,7 @@ bool MainDialog::saveOldConfig() //return false on user abort QuestConfig().setCaption(toWx(activeCfgFilename)). setLabelYes(_("&Save")). setLabelNo(_("Do&n't save")). - showCheckBox(dontAskAgain, _("Never save changes"), ReturnQuestionDlg::BUTTON_YES))) + showCheckBox(dontAskAgain, _("Never save &changes"), ReturnQuestionDlg::BUTTON_YES))) { case ReturnQuestionDlg::BUTTON_YES: @@ -2808,6 +2873,8 @@ void MainDialog::OnLoadFromHistory(wxCommandEvent& event) { if (auto histData = dynamic_cast<const wxClientHistoryData*>(m_listBoxHistory->GetClientObject(pos))) filenames.push_back(histData->cfgFile_); + else + assert(false); }); if (!filenames.empty()) @@ -2831,6 +2898,8 @@ void MainDialog::OnLoadFromHistoryDoubleClick(wxCommandEvent& event) { if (auto histData = dynamic_cast<const wxClientHistoryData*>(m_listBoxHistory->GetClientObject(pos))) filenames.push_back(histData->cfgFile_); + else + assert(false); }); if (!filenames.empty()) @@ -3026,15 +3095,7 @@ void MainDialog::setConfig(const xmlAccess::XmlGuiConfig& newGuiCfg, const std:: setViewTypeSyncAction(currentCfg.highlightSyncAction); - //########################################################### - //update compare variant name - m_staticTextCmpVariant->SetLabel(currentCfg.mainCfg.getCompVariantName()); - - //update sync variant name - m_staticTextSyncVariant->SetLabel(currentCfg.mainCfg.getSyncVariantName()); - m_panelTopButtons->Layout(); //adapt layout for variant text - - clearGrid(); //+ update GUI + clearGrid(); //+ update GUI! setLastUsedConfig(referenceFiles, newGuiCfg); } @@ -3185,7 +3246,7 @@ inline wxBitmap buttonReleased(const std::string& name) { wxImage output = getResourceImage(utfCvrtTo<wxString>(name)).ConvertToImage().ConvertToGreyscale(1.0/3, 1.0/3, 1.0/3); //treat all channels equally! - zen::move(output, 0, -1); //move image right one pixel + //zen::moveImage(output, 1, 0); //move image right one pixel brighten(output, 80); return mirrorIfRtl(output); @@ -3282,12 +3343,12 @@ void MainDialog::updateGlobalFilterButton() if (!isNullFilter(currentCfg.mainCfg.globalFilter)) { setImage(*m_bpButtonFilter, getResourceImage(L"filter")); - m_bpButtonFilter->SetToolTip(_("Filter is active")); + m_bpButtonFilter->SetToolTip(_("Filter is active") + L" (F10)"); } else { setImage(*m_bpButtonFilter, greyScale(getResourceImage(L"filter"))); - m_bpButtonFilter->SetToolTip(_("No filter selected")); + m_bpButtonFilter->SetToolTip(_("No filter selected")+ L" (F10)"); } } @@ -3296,7 +3357,7 @@ void MainDialog::OnCompare(wxCommandEvent& event) { //PERF_START; - wxBusyCursor dummy; //show hourglass cursor + //wxBusyCursor dummy; -> redundant: progress already shown in progress dialog! wxWindow* oldFocus = wxWindow::FindFocus(); ZEN_ON_SCOPE_EXIT(if (oldFocus) oldFocus->SetFocus();); //e.g. keep focus on main grid after pressing F5 @@ -3368,31 +3429,46 @@ void MainDialog::OnCompare(wxCommandEvent& event) } +void MainDialog::updateTopButtonImages() +{ + auto updateButton = [&](wxBitmapButton& btn, const wxBitmap& bmp, const wxString& variantName, bool makeGrey) + { + wxImage labelImage = createImageFromText(btn.GetLabel(), btn.GetFont(), makeGrey ? wxColor(128, 128, 128) : wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT)); + wxImage variantImage = createImageFromText(variantName, wxFont(wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxBOLD), wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT)); + + wxImage descrImage = stackImages(labelImage, variantImage, ImageStackLayout::VERTICAL, ImageStackAlignment::CENTER); + const wxImage& iconImage = makeGrey ? greyScale(bmp.ConvertToImage()) : bmp.ConvertToImage(); + + wxImage dynImage = btn.GetLayoutDirection() != wxLayout_RightToLeft ? + stackImages(iconImage, descrImage, ImageStackLayout::HORIZONTAL, ImageStackAlignment::CENTER, 5) : + stackImages(descrImage, iconImage, ImageStackLayout::HORIZONTAL, ImageStackAlignment::CENTER, 5); + + //SetMinSize() instead of SetSize() is needed here for wxWindows layout determination to work corretly + wxSize minSize = dynImage.GetSize() + wxSize(10, 10); //add border space + minSize.x = std::max(minSize.x, 180); + btn.SetMinSize(minSize); + + btn.SetBitmapLabel(wxBitmap(dynImage)); + //SetLabel() calls confuse wxBitmapButton in the disabled state and it won't show the image! workaround: + btn.SetBitmapDisabled(wxBitmap(dynImage.ConvertToDisabled())); + }; + + updateButton(*m_buttonCompare, getResourceImage(L"compare"), getConfig().mainCfg.getCompVariantName(), false); + updateButton(*m_buttonSync, getResourceImage(L"sync"), getConfig().mainCfg.getSyncVariantName(), folderCmp.empty()); + + m_panelTopButtons->Layout(); +} + + void MainDialog::updateGui() { updateGridViewData(); //update gridDataView and write status information - //update sync preview statistics updateStatistics(); updateUnsavedCfgStatus(); - //update sync and comparison variant names - m_staticTextSyncVariant->SetLabel(getConfig().mainCfg.getSyncVariantName()); - m_staticTextCmpVariant ->SetLabel(getConfig().mainCfg.getCompVariantName()); - m_panelTopButtons->Layout(); - - //update sync button enabled/disabled status - if (!folderCmp.empty()) - { - m_buttonSync->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT)); - m_buttonSync->setBitmapFront(getResourceImage(L"sync"), 5); - } - else - { - m_buttonSync->SetForegroundColour(wxColor(128, 128, 128)); //Some colors seem to have problems with 16-bit desktop color, well this one hasn't! - m_buttonSync->setBitmapFront(greyScale(getResourceImage(L"sync")), 5); - } + updateTopButtonImages(); auiMgr.Update(); //fix small display distortion, if view filter panel is empty } @@ -3541,7 +3617,7 @@ void MainDialog::OnStartSync(wxCommandEvent& event) guiCfg.mainCfg.onCompletion, globalCfg.gui.onCompletionHistory); - wxBusyCursor dummy; //show hourglass cursor -> lifetime must end *before* showing results dialog in ~SyncStatusHandler()! + //wxBusyCursor dummy; -> redundant: progress already shown in progress dialog! //GUI mode: place directory locks on directories isolated(!) during both comparison and synchronization std::unique_ptr<LockHolder> dirLocks; @@ -3848,7 +3924,6 @@ void MainDialog::updateGridViewData() void MainDialog::applyFilterConfig() { applyFiltering(folderCmp, getConfig().mainCfg); - updateGui(); //updateGuiDelayedIf(currentCfg.hideExcludedItems); //show update GUI before removing rows } @@ -3873,6 +3948,103 @@ void MainDialog::applySyncConfig() } +void MainDialog::showFindPanel() //CTRL + F or F3 with empty search phrase +{ + auiMgr.GetPane(m_panelSearch).Show(); + auiMgr.Update(); + + m_textCtrlSearchTxt->SelectAll(); + + wxWindow* focus = wxWindow::FindFocus(); //restore when closing panel! + if (!isComponentOf(focus, m_panelSearch)) + focusWindowAfterSearch = focus == &m_gridMainR->getMainWin() ? focus : &m_gridMainL->getMainWin(); + //don't save pointer to arbitrary window: it might not exist anymore when hideFindPanel() uses it!!! (e.g. some folder pair panel) + m_textCtrlSearchTxt->SetFocus(); +} + + +void MainDialog::hideFindPanel() +{ + auiMgr.GetPane(m_panelSearch).Hide(); + auiMgr.Update(); + + if (focusWindowAfterSearch) + { + focusWindowAfterSearch->SetFocus(); + focusWindowAfterSearch = nullptr; + } +} + + +void MainDialog::startFindNext() //F3 or ENTER in m_textCtrlSearchTxt +{ + const wxString& searchString = m_textCtrlSearchTxt->GetValue(); + + if (searchString.empty()) + showFindPanel(); + else + { + Grid* grid1 = m_gridMainL; + Grid* grid2 = m_gridMainR; + + wxWindow* focus = wxWindow::FindFocus(); + if ((isComponentOf(focus, m_panelSearch) ? focusWindowAfterSearch : focus) == &m_gridMainR->getMainWin()) + std::swap(grid1, grid2); //select side to start search at grid cursor position + + wxBeginBusyCursor(wxHOURGLASS_CURSOR); + const std::pair<const Grid*, ptrdiff_t> result = findGridMatch(*grid1, *grid2, searchString, + m_checkBoxMatchCase->GetValue()); //parameter owned by GUI, *not* globalCfg structure! => we should better implement a getGlocalCfg()! + wxEndBusyCursor(); + + if (Grid* grid = const_cast<Grid*>(result.first)) //grid wasn't const when passing to findAndSelectNext(), so this is safe + { + assert(result.second >= 0); + + gridview::setScrollMaster(*grid); + grid->setGridCursor(result.second); + + focusWindowAfterSearch = &grid->getMainWin(); + + if (!isComponentOf(wxWindow::FindFocus(), m_panelSearch)) + grid->getMainWin().SetFocus(); + } + else + { + showFindPanel(); + wxMessageBox(replaceCpy(_("Cannot find %x"), L"%x", L"\"" + searchString + L"\"", false), _("Find"), wxOK, this); + } + } +} + + +void MainDialog::OnSearchGridEnter(wxCommandEvent& event) +{ + startFindNext(); +} + + +void MainDialog::OnHideSearchPanel(wxCommandEvent& event) +{ + hideFindPanel(); +} + + +void MainDialog::OnSearchPanelKeyPressed(wxKeyEvent& event) +{ + switch (event.GetKeyCode()) + { + case WXK_RETURN: + case WXK_NUMPAD_ENTER: //catches ENTER keys while focus is on *any* part of m_panelSearch! Seems to obsolete OnHideSearchPanel()! + startFindNext(); + return; + case WXK_ESCAPE: + hideFindPanel(); + return; + } + event.Skip(); +} + + void MainDialog::OnAddFolderPair(wxCommandEvent& event) { wxWindowUpdateLocker dummy(this); //avoid display distortion @@ -4107,6 +4279,8 @@ void MainDialog::OnMenuExportFileList(wxCommandEvent& event) if (filePicker.ShowModal() != wxID_OK) return; + wxBusyCursor dummy; + const Zstring filename = utfCvrtTo<Zstring>(filePicker.GetPath()); //http://en.wikipedia.org/wiki/Comma-separated_values @@ -4315,7 +4489,7 @@ void MainDialog::setViewTypeSyncAction(bool value) //if (m_bpButtonViewTypeSyncAction->isActive() == value) return; support polling -> what about initialization? m_bpButtonViewTypeSyncAction->setActive(value); - m_bpButtonViewTypeSyncAction->SetToolTip((value ? _("Action") : _("Category")) + L" (F8)"); + m_bpButtonViewTypeSyncAction->SetToolTip((value ? _("Action") : _("Category")) + L" (F9)"); //toggle display of sync preview in middle grid gridview::highlightSyncAction(*m_gridMainC, value); diff --git a/ui/main_dlg.h b/ui/main_dlg.h index b655d95e..72762515 100644 --- a/ui/main_dlg.h +++ b/ui/main_dlg.h @@ -106,6 +106,7 @@ private: void updateGridViewData(); // void updateStatistics(); // more fine-grained updaters void updateUnsavedCfgStatus(); // + void updateTopButtonImages(); // //context menu functions std::vector<zen::FileSystemObject*> getGridSelection(bool fromLeft = true, bool fromRight = true) const; @@ -144,10 +145,10 @@ private: void OnContextSetLayout(wxMouseEvent& event); void OnGlobalKeyEvent (wxKeyEvent& event); - virtual void OnCompSettingsContext(wxMouseEvent& event); - virtual void OnSyncSettingsContext(wxMouseEvent& event); - virtual void OnGlobalFilterContext(wxMouseEvent& event); - virtual void OnViewButtonRightClick(wxMouseEvent& event); + virtual void OnCompSettingsContext(wxMouseEvent& event) override; + virtual void OnSyncSettingsContext(wxMouseEvent& event) override; + virtual void OnGlobalFilterContext(wxMouseEvent& event) override; + virtual void OnViewButtonRightClick(wxMouseEvent& event) override; void applyCompareConfig(bool switchMiddleGrid = false); @@ -183,56 +184,65 @@ private: void onGridLabelContextR(zen::GridClickEvent& event); void onGridLabelContext(zen::Grid& grid, zen::ColumnTypeRim type, const std::vector<zen::ColumnAttributeRim>& defaultColumnAttributes); - void OnToggleViewType (wxCommandEvent& event); - void OnToggleViewButton(wxCommandEvent& event); + virtual void OnToggleViewType (wxCommandEvent& event) override; + virtual void OnToggleViewButton(wxCommandEvent& event) override; - void OnConfigNew (wxCommandEvent& event); - void OnConfigSave (wxCommandEvent& event); - void OnConfigSaveAs (wxCommandEvent& event); - void OnSaveAsBatchJob (wxCommandEvent& event); - void OnConfigLoad (wxCommandEvent& event); - void OnLoadFromHistory(wxCommandEvent& event); - void OnLoadFromHistoryDoubleClick(wxCommandEvent& event); + virtual void OnConfigNew (wxCommandEvent& event) override; + virtual void OnConfigSave (wxCommandEvent& event) override; + virtual void OnConfigSaveAs (wxCommandEvent& event) override; + virtual void OnSaveAsBatchJob (wxCommandEvent& event) override; + virtual void OnConfigLoad (wxCommandEvent& event) override; + virtual void OnLoadFromHistory(wxCommandEvent& event) override; + virtual void OnLoadFromHistoryDoubleClick(wxCommandEvent& event); void deleteSelectedCfgHistoryItems(); - void OnCfgHistoryKeyEvent(wxKeyEvent& event); - void OnCfgHistoryRightClick(wxMouseEvent& event); - void OnRegularUpdateCheck(wxIdleEvent& event); - void OnLayoutWindowAsync (wxIdleEvent& event); + virtual void OnCfgHistoryRightClick(wxMouseEvent& event) override; + void OnCfgHistoryKeyEvent (wxKeyEvent& event) override; + void OnRegularUpdateCheck (wxIdleEvent& event); + void OnLayoutWindowAsync (wxIdleEvent& event); void OnResizeLeftFolderWidth(wxEvent& event); void OnResizeConfigPanel (wxEvent& event); void OnResizeViewPanel (wxEvent& event); void OnResizeStatisticsPanel(wxEvent& event); - void OnShowExcluded (wxCommandEvent& event); - void OnConfigureFilter (wxCommandEvent& event); - void OnSwapSides (wxCommandEvent& event); - void OnCompare (wxCommandEvent& event); - void OnSyncSettings (wxCommandEvent& event); - void OnCmpSettings (wxCommandEvent& event); - void OnStartSync (wxCommandEvent& event); - void OnClose (wxCloseEvent& event); - - void excludeExtension(const Zstring& extension); - void excludeShortname(const zen::FileSystemObject& fsObj); - void excludeItems(const std::vector<zen::FileSystemObject*>& selection); - - void OnAddFolderPair (wxCommandEvent& event); + virtual void OnShowExcluded (wxCommandEvent& event) override; + virtual void OnConfigureFilter (wxCommandEvent& event) override; + virtual void OnSwapSides (wxCommandEvent& event) override; + virtual void OnCompare (wxCommandEvent& event) override; + virtual void OnSyncSettings (wxCommandEvent& event) override; + virtual void OnCmpSettings (wxCommandEvent& event) override; + virtual void OnStartSync (wxCommandEvent& event) override; + virtual void OnClose (wxCloseEvent& event) override; + + void filterExtension(const Zstring& extension, bool include); + void filterShortname(const zen::FileSystemObject& fsObj, bool include); + void filterItems(const std::vector<zen::FileSystemObject*>& selection, bool include); + void filterPhrase(const Zstring& phrase, bool include, bool addNewLine); + + virtual void OnAddFolderPair (wxCommandEvent& event) override; void OnRemoveFolderPair (wxCommandEvent& event); - void OnRemoveTopFolderPair(wxCommandEvent& event); + virtual void OnRemoveTopFolderPair(wxCommandEvent& event) override; void applyFilterConfig(); void applySyncConfig(); + void showFindPanel(); //CTRL + F + void hideFindPanel(); + void startFindNext(); //F3 + + virtual void OnSearchGridEnter(wxCommandEvent& event) override; + virtual void OnHideSearchPanel(wxCommandEvent& event) override; + void OnSearchPanelKeyPressed(wxKeyEvent& event); + //menu events - virtual void OnMenuGlobalSettings(wxCommandEvent& event); - virtual void OnMenuExportFileList(wxCommandEvent& event); - virtual void OnMenuCheckVersion (wxCommandEvent& event); - virtual void OnMenuCheckVersionAutomatically(wxCommandEvent& event); - virtual void OnMenuAbout (wxCommandEvent& event); - virtual void OnShowHelp (wxCommandEvent& event); - virtual void OnMenuQuit (wxCommandEvent& event) { Close(); } + virtual void OnMenuGlobalSettings(wxCommandEvent& event) override; + virtual void OnMenuExportFileList(wxCommandEvent& event) override; + virtual void OnMenuCheckVersion (wxCommandEvent& event) override; + virtual void OnMenuCheckVersionAutomatically(wxCommandEvent& event) override; + virtual void OnMenuAbout (wxCommandEvent& event) override; + virtual void OnShowHelp (wxCommandEvent& event) override; + virtual void OnMenuQuit (wxCommandEvent& event) override { Close(); } void OnMenuLanguageSwitch(wxCommandEvent& event); @@ -296,6 +306,8 @@ private: wxTimer timerForAsyncTasks; //don't use wxWidgets idle handling => repeated idle requests/consumption hogs 100% cpu! std::unique_ptr<zen::FilterConfig> filterCfgOnClipboard; //copy/paste of filter config + + wxWindow* focusWindowAfterSearch; //used to restore focus after search panel is closed }; #endif // MAINDIALOG_H diff --git a/ui/msg_popup.cpp b/ui/msg_popup.cpp index 0d08768c..7fa1550f 100644 --- a/ui/msg_popup.cpp +++ b/ui/msg_popup.cpp @@ -60,7 +60,7 @@ ErrorDlg::ErrorDlg(wxWindow* parent, int activeButtons, const wxString& messageT SetTitle(!caption.empty() ? caption : _("Error")); m_bitmapMsgType->SetBitmap(getResourceImage(L"msg_error")); m_textCtrlMessage->SetValue(messageText); - checkBoxIgnoreErrors.SetLabel(_("Ignore further errors")); + checkBoxIgnoreErrors.SetLabel(_("&Ignore subsequent errors")); buttonIgnore.SetLabel(_("&Ignore")); buttonRetry .SetLabel(_("&Retry")); //buttonIgnore.SetId(wxID_IGNORE); -> setting id after button creation breaks "mouse snap to" functionality @@ -174,7 +174,7 @@ WarningDlg::WarningDlg(wxWindow* parent, int activeButtons, const wxString& mes SetTitle(_("Warning")); m_bitmapMsgType->SetBitmap(getResourceImage(L"msg_warning")); m_textCtrlMessage->SetValue(messageText); - checkBoxDontShowAgain.SetLabel(_("Don't show this warning again")); + checkBoxDontShowAgain.SetLabel(_("&Don't show this warning again")); buttonIgnore.SetLabel(_("&Ignore")); buttonSwitch.SetLabel(_("&Switch")); //buttonIgnore.SetId(wxID_IGNORE); -> see comment in ErrorDlg diff --git a/ui/progress_indicator.cpp b/ui/progress_indicator.cpp index fd1c305d..45fea4d5 100644 --- a/ui/progress_indicator.cpp +++ b/ui/progress_indicator.cpp @@ -12,6 +12,7 @@ #include <wx/sound.h> #include <wx/clipbrd.h> #include <wx/msgdlg.h> +#include <wx/dcclient.h> #include <wx/dataobj.h> //wxTextDataObject #include <zen/basic_math.h> #include <zen/format_unit.h> @@ -34,14 +35,13 @@ #include "tray_icon.h" #include "taskbar.h" #include "exec_finished_box.h" - -#include <wx/msgdlg.h> +//#include <wx/msgdlg.h> +#ifdef ZEN_MAC +#include <ApplicationServices/ApplicationServices.h> +#endif using namespace zen; -warn_static("remove after test") -#include <zen/perf.h> - namespace { @@ -301,7 +301,7 @@ wxBitmap buttonReleased(const std::string& name) //getResourceImage(utfCvrtTo<wxString>(name)).ConvertToImage().ConvertToGreyscale(1.0/3, 1.0/3, 1.0/3); //treat all channels equally! //brighten(output, 30); - zen::move(output, 0, -1); //move image right one pixel + //zen::moveImage(output, 1, 0); //move image right one pixel return output; } @@ -347,11 +347,7 @@ public: size_t rowNumber = 0; bool lastCharNewline = true; - std::for_each(it->message.begin(), it->message.end(), - [&](wchar_t c) - { - typedef Line Line; //workaround MSVC compiler bug! - + for (const wchar_t c : it->message) if (c == L'\n') { if (!lastCharNewline) //do not reference empty lines! @@ -361,7 +357,7 @@ public: } else lastCharNewline = false; - }); + if (!lastCharNewline) viewRef.push_back(Line(&*it, rowNumber)); } @@ -481,7 +477,7 @@ public: switch (static_cast<ColumnTypeMsg>(colType)) { case COL_TYPE_MSG_TIME: - drawCellText(dc, rectTmp, getValue(row, colType), grid.IsEnabled(), wxALIGN_CENTER); + drawCellText(dc, rectTmp, getValue(row, colType), true, wxALIGN_CENTER); break; case COL_TYPE_MSG_CATEGORY: @@ -505,13 +501,13 @@ public: { rectTmp.x += COLUMN_BORDER_LEFT; rectTmp.width -= COLUMN_BORDER_LEFT; - drawCellText(dc, rectTmp, getValue(row, colType), grid.IsEnabled()); + drawCellText(dc, rectTmp, getValue(row, colType), true); } break; } } - virtual size_t getBestSize(wxDC& dc, size_t row, ColumnType colType) + virtual int getBestSize(wxDC& dc, size_t row, ColumnType colType) { // -> synchronize renderCell() <-> getBestSize() @@ -654,7 +650,6 @@ private: m_gridMessages->Refresh(); //update MVC "view" } - void onGridButtonEvent(wxKeyEvent& event) { int keyCode = event.GetKeyCode(); @@ -736,18 +731,24 @@ namespace class CurveDataStatistics : public SparseCurveData { public: - CurveDataStatistics() : SparseCurveData(true), timeNow(0) {} + CurveDataStatistics() : SparseCurveData(true), /*true: add steps*/ timeNow(0) {} void clear() { samples.clear(); timeNow = 0; } void addRecord(long timeNowMs, double value) { - warn_static("review") - timeNow = timeNowMs; + //samples.clear(); + //samples.insert(std::make_pair(-1000, 0)); + //samples.insert(std::make_pair(0, 0)); + //samples.insert(std::make_pair(1, 1)); + //samples.insert(std::make_pair(1000, 0)); + //return; + + timeNow = timeNowMs; if (!samples.empty() && samples.rbegin()->second == value) return; //don't insert duplicate values - samples.insert(samples.end(), std::make_pair(timeNowMs, value)); //use fact that time is monotonously ascending + samples.insert(samples.end(), std::make_pair(timeNowMs, value)); //time is "expected" to be monotonously ascending //documentation differs about whether "hint" should be before or after the to be inserted element! //however "std::map<>::end()" is interpreted correctly by GCC and VS2010 @@ -756,29 +757,29 @@ public: } private: - virtual std::pair<double, double> getRangeX() const final + virtual std::pair<double, double> getRangeX() const final { - if (samples.empty()) return std::make_pair(0.0, 0.0); + if (samples.empty()) return std::make_pair(0.0, 0.0); - double upperEndMs = std::max(timeNow, samples.rbegin()->first); + double upperEndMs = std::max(timeNow, samples.rbegin()->first); - //request some additional width by 5% elapsed time to make graph recalibrate before hitting the right border - //caveat: graph for batch mode binary comparison does NOT start at elapsed time 0!! PHASE_COMPARING_CONTENT and PHASE_SYNCHRONIZING! - //=> consider width of current sample set! - upperEndMs += 0.05 *(upperEndMs - samples.begin()->first); + //report some additional width by 5% elapsed time to make graph recalibrate before hitting the right border + //caveat: graph for batch mode binary comparison does NOT start at elapsed time 0!! PHASE_COMPARING_CONTENT and PHASE_SYNCHRONIZING! + //=> consider width of current sample set! + upperEndMs += 0.05 *(upperEndMs - samples.begin()->first); return std::make_pair(samples.begin()->first / 1000.0, //need not start with 0, e.g. "binary comparison, graph reset, followed by sync" - upperEndMs / 1000.0); + upperEndMs / 1000.0); } virtual Opt<CurvePoint> getLessEq(double x) const final //x: seconds since begin { - const long timex = std::floor(x * 1000); - //------ add artifical last sample value ------- - if (!samples.empty() && samples.rbegin()->first < timeNow) - if (timeNow <= timex) - return CurvePoint(timeNow / 1000.0, samples.rbegin()->second); - //-------------------------------------------------- + const long timex = std::floor(x * 1000); + //------ add artifical last sample value ------- + if (!samples.empty() && samples.rbegin()->first < timeNow) + if (timeNow <= timex) + return CurvePoint(timeNow / 1000.0, samples.rbegin()->second); + //-------------------------------------------------- //find first key > x, then go one step back: => samples must be a std::map, NOT std::multimap!!! auto it = samples.upper_bound(timex); @@ -791,14 +792,14 @@ private: virtual Opt<CurvePoint> getGreaterEq(double x) const final { - const long timex = std::ceil(x * 1000); - //------ add artifical last sample value ------- - if (!samples.empty() && samples.rbegin()->first < timeNow) - if (samples.rbegin()->first < timex && timex <= timeNow) - return CurvePoint(timeNow / 1000.0, samples.rbegin()->second); - //-------------------------------------------------- - - auto it = samples.lower_bound(timex); + const long timex = std::ceil(x * 1000); + //------ add artifical last sample value ------- + if (!samples.empty() && samples.rbegin()->first < timeNow) + if (samples.rbegin()->first < timex && timex <= timeNow) + return CurvePoint(timeNow / 1000.0, samples.rbegin()->second); + //-------------------------------------------------- + + auto it = samples.lower_bound(timex); if (it == samples.end()) return NoValue(); return CurvePoint(it->first / 1000.0, it->second); @@ -807,7 +808,7 @@ private: static const size_t MAX_BUFFER_SIZE = 2500000; //sizeof(single node) worst case ~ 3 * 8 byte ptr + 16 byte key/value = 40 byte std::map<long, double> samples; //time, unit: [ms] !don't use std::multimap, see getLessEq() - long timeNow; //help create an artificial record at the end of samples to visualize current time! + long timeNow; //help create an artificial record at the end of samples to visualize current time! }; @@ -823,41 +824,19 @@ private: virtual void getPoints(double minX, double maxX, int pixelWidth, std::vector<CurvePoint>& points) const final { - - warn_static("remove after test") -#if 0 - if (yTotal_ > 100) - { -points.push_back(CurvePoint(0.38552801074951426,0.3861846045528107)); -points.push_back(CurvePoint(-0.5565680734345084,1.793989720937398)); -points.push_back(CurvePoint(2.85210684934041,3.339141677944872)); -points.push_back(CurvePoint(0.45404408959926135,0.7810567713436095)); -points.push_back(CurvePoint(2.303978218542433,-0.6610850551966995)); -points.push_back(CurvePoint(-2.5606633797896112,-0.4035597290287872)); -points.push_back(CurvePoint(-0.5394390537220716,0.40335295963067147)); - - - //points.push_back(CurvePoint(0.2885508231771302,-1.9264175407823294)); - //points.push_back(CurvePoint(-1.9332518577512143,0.6244007597162101)); - //points.push_back(CurvePoint(3.116299689813205,1.6973640131005165)); - //points.push_back(CurvePoint(0.0,0.0)); - //points.push_back(CurvePoint(-5.993091301993007,0.5231778112837284)); - return; - } -#endif - - - - - + //points.push_back(CurvePoint(-1, 0)); + //points.push_back(CurvePoint(0, 0)); + //points.push_back(CurvePoint(0.0001, 1)); + //points.push_back(CurvePoint(1, 0)); + //return; if (x <= maxX) { points.push_back(CurvePoint(x, 0)); points.push_back(CurvePoint(x, yCurrent_)); - points.push_back(CurvePoint(maxX, yCurrent_)); + points.push_back(CurvePoint(maxX, yCurrent_)); points.push_back(CurvePoint(x, yCurrent_)); - points.push_back(CurvePoint(x, yTotal_)); + points.push_back(CurvePoint(x, yTotal_)); } } @@ -891,15 +870,18 @@ private: }; +const double stretchDefaultBlockSize = 1.4; //enlarge block default size + + struct LabelFormatterBytes : public LabelFormatter { virtual double getOptimalBlockSize(double bytesProposed) const { + bytesProposed *= stretchDefaultBlockSize; //enlarge block default size + if (bytesProposed <= 1) //never smaller than 1 byte return 1; - bytesProposed *= 1.4; //enlarge block default size - //round to next number which is a convenient to read block size const double k = std::floor(std::log(bytesProposed) / std::log(2.0)); const double e = std::pow(2.0, k); @@ -919,6 +901,8 @@ struct LabelFormatterItemCount : public LabelFormatter { virtual double getOptimalBlockSize(double itemsProposed) const { + itemsProposed *= stretchDefaultBlockSize; //enlarge block default size + const double steps[] = { 1, 2, 5, 10 }; if (itemsProposed <= 10) return numeric::nearMatch(itemsProposed, std::begin(steps), std::end(steps)); //similar to nextNiceNumber(), but without the 2.5 step! @@ -998,35 +982,7 @@ public: virtual void initNewPhase(); virtual void notifyProgressChange(); - virtual void updateGui() { - - - warn_static("remove after test") -#if 0 - static bool init = false; - static wxStopWatch sw; - if (!init) - { - init = true; - sw.Start(); - } - if (sw.Time() > 1000 * 10) - { - PERF_START - for (int i = 0; i < 10000; ++i) - //for (int i = 0; i < 1000000; ++i) - updateGuiInt(true); - sw.Start(); - sw.Pause(); - } -#endif - - - - - - - updateGuiInt(true); } + virtual void updateGui() { updateGuiInt(true); } virtual std::wstring getExecWhenFinishedCommand() const { return pnl.m_comboBoxExecFinished->getValue(); } @@ -1197,6 +1153,8 @@ SyncProgressDialogImpl<TopLevelDialog>::SyncProgressDialogImpl(long style, //wxF setLabelY(Graph2D::Y_LABEL_RIGHT, yLabelWidth, std::make_shared<LabelFormatterItemCount>()). setSelectionMode(Graph2D::SELECT_NONE)); + //pnl.m_panelGraphBytes->setAttributes(Graph2D::MainAttributes().setMinX(-1).setMaxX(1).setMinY(-1).setMaxY(1)); + pnl.m_panelGraphBytes->setCurve(curveDataBytes, Graph2D::CurveAttributes().setLineWidth(2). fillCurveArea(wxColor(205, 255, 202)). //faint green setColor (wxColor( 20, 200, 0))); //medium green @@ -1217,30 +1175,18 @@ SyncProgressDialogImpl<TopLevelDialog>::SyncProgressDialogImpl(long style, //wxF updateDialogStatus(); //null-status will be shown while waiting for dir locks - - warn_static("remove after test") -#if 0 - pnl.m_panelGraphBytes->setAttributes(Graph2D::MainAttributes().setMinX(-1).setMaxX(1).setMinY(-1).setMaxY(1)); - pnl.m_panelGraphBytes->setCurve(curveDataBytesCurrent, Graph2D::CurveAttributes().setLineWidth(6).setColor(wxColor(12, 128, 0)) - .fillCurveArea(wxColor(198, 206, 255)) //faint blue - ); // -#endif - - - - - - - - - - this->Fit(); pnl.Layout(); if (showProgress) { this->Show(); +#ifdef ZEN_MAC + ProcessSerialNumber psn = { 0, kCurrentProcess }; + ::TransformProcessType(&psn, kProcessTransformToForegroundApplication); //show dock icon (consider non-silent batch mode) + ::SetFrontProcess(&psn); //why isn't this covered by wxWindows::Raise()?? +#endif + pnl.m_buttonCancel->SetFocus(); //don't steal focus when starting in sys-tray! //clear gui flicker, remove dummy texts: window must be visible to make this work! @@ -1260,6 +1206,11 @@ SyncProgressDialogImpl<TopLevelDialog>::~SyncProgressDialogImpl() //make sure main dialog is shown again if still "minimized to systray"! see SyncProgressDialog::closeWindowDirectly() parentFrame_->Show(); +#ifdef ZEN_MAC + ProcessSerialNumber psn = { 0, kCurrentProcess }; + ::TransformProcessType(&psn, kProcessTransformToForegroundApplication); //show dock icon (consider GUI mode with "close progress dialog") + ::SetFrontProcess(&psn); //why isn't this covered by wxWindows::Raise()?? +#endif //if (parentFrame_->IsIconized()) //caveat: if window is maximized calling Iconize(false) will erroneously un-maximize! // parentFrame_->Iconize(false); } @@ -1301,10 +1252,10 @@ void SyncProgressDialogImpl<TopLevelDialog>::initNewPhase() updateDialogStatus(); //evaluates "syncStat_->currentPhase()" //reset graphs (e.g. after binary comparison) - curveDataBytesTotal ->setValue(0, 0); - curveDataBytesCurrent->setValue(0, 0, 0); - curveDataItemsTotal ->setValue(0, 0); - curveDataItemsCurrent->setValue(0, 0, 0); + curveDataBytesTotal ->setValue(0, 0); + curveDataBytesCurrent->setValue(0, 0, 0); + curveDataItemsTotal ->setValue(0, 0); + curveDataItemsCurrent->setValue(0, 0, 0); curveDataBytes->clear(); curveDataItems->clear(); @@ -1494,10 +1445,10 @@ void SyncProgressDialogImpl<TopLevelDialog>::updateGuiInt(bool allowYield) curveDataItemsTotal ->setValue(timeNow, itemsTotal); curveDataItemsCurrent->setValue(timeNow, itemsCurrent, itemsTotal); //even though notifyProgressChange() already set the latest data, let's add another sample to have all curves consider "timeNow" - //no problem with adding too many records: CurveDataStatistics will remove duplicate entries! - curveDataBytes->addRecord(timeNow, to<double>(dataCurrent)); - curveDataItems->addRecord(timeNow, itemsCurrent); - + //no problem with adding too many records: CurveDataStatistics will remove duplicate entries! + curveDataBytes->addRecord(timeNow, to<double>(dataCurrent)); + curveDataItems->addRecord(timeNow, itemsCurrent); + //remaining objects and data setText(*pnl.m_staticTextRemainingObj, toGuiString(itemsTotal - itemsCurrent), &layoutChanged); setText(*pnl.m_staticTextDataRemaining, L"(" + filesizeToShortString(dataTotal - dataCurrent) + L")", &layoutChanged); @@ -1745,7 +1696,11 @@ void SyncProgressDialogImpl<TopLevelDialog>::processHasFinished(SyncResult resul //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 +#if (defined __WXGTK__ || defined __WXOSX__) + //In wxWidgets 2.9.3 upwards, the wxWindow::Reparent() below fails on GTK and OS X if window is frozen! http://forums.codeblocks.org/index.php?topic=13388.45 +#else + wxWindowUpdateLocker dummy(this); //badly needed on Windows +#endif paused_ = false; //you never know? @@ -1824,7 +1779,7 @@ void SyncProgressDialogImpl<TopLevelDialog>::processHasFinished(SyncResult resul //hide current operation status pnl.bSizerStatusText->Show(false); - //show and prepare final statistics + //show and prepare final statistics pnl.m_notebookResult->Show(); #if defined ZEN_WIN || defined ZEN_LINUX @@ -1835,15 +1790,15 @@ void SyncProgressDialogImpl<TopLevelDialog>::processHasFinished(SyncResult resul pnl.m_panelTimeRemaining->Hide(); //1. re-arrange graph into results listbook - pnl.bSizerRoot->Detach(pnl.m_panelProgress); + const bool wasDetached = pnl.bSizerRoot->Detach(pnl.m_panelProgress); + assert(wasDetached); + (void)wasDetached; pnl.m_panelProgress->Reparent(pnl.m_notebookResult); -#ifdef ZEN_LINUX //does not seem to be required on Win or OS X - wxTheApp->Yield(); //wxGTK 2.9.3 fails miserably at "reparent" whithout this -#endif - pnl.m_notebookResult->AddPage(pnl.m_panelProgress, _("Statistics"), true); //AddPage() takes ownership! + pnl.m_notebookResult->AddPage(pnl.m_panelProgress, _("Statistics"), true); //2. log file const size_t posLog = 1; + assert(pnl.m_notebookResult->GetPageCount() == 1); LogPanel* logPanel = new LogPanel(pnl.m_notebookResult, log); //owned by m_notebookResult pnl.m_notebookResult->AddPage(logPanel, _("Log"), false); //bSizerHoldStretch->Insert(0, logPanel, 1, wxEXPAND); @@ -1981,6 +1936,11 @@ void SyncProgressDialogImpl<TopLevelDialog>::minimizeToTray() this->Hide(); if (parentFrame_) parentFrame_->Hide(); +#ifdef ZEN_MAC + //hide dock icon: else user is able to forcefully show the hidden main dialog by clicking on the icon!! + ProcessSerialNumber psn = { 0, kCurrentProcess }; + ::TransformProcessType(&psn, kProcessTransformToUIElementApplication); +#endif } } @@ -2008,6 +1968,12 @@ void SyncProgressDialogImpl<TopLevelDialog>::resumeFromSystray() updateDialogStatus(); //restore Windows 7 task bar status (e.g. required in pause mode) updateGuiInt(false); //restore Windows 7 task bar progress (e.g. required in pause mode) + +#ifdef ZEN_MAC + ProcessSerialNumber psn = { 0, kCurrentProcess }; + ::TransformProcessType(&psn, kProcessTransformToForegroundApplication); //show dock icon again + ::SetFrontProcess(&psn); //why isn't this covered by wxWindows::Raise()?? +#endif } } diff --git a/ui/search.cpp b/ui/search.cpp index 4c9c5366..c834b934 100644 --- a/ui/search.cpp +++ b/ui/search.cpp @@ -5,82 +5,19 @@ // ************************************************************************** #include "search.h" -#include "gui_generated.h" -#include <wx/msgdlg.h> -#include <wx/utils.h> -#include <utility> #include <zen/string_tools.h> -#include <wx+/mouse_move_dlg.h> -using namespace zen; - - -class SearchDlg : public SearchDialogGenerated -{ -public: - SearchDlg(wxWindow* parent, wxString& searchText, bool& respectCase); - - enum ReturnCodes - { - BUTTON_CANCEL, - BUTTON_OKAY - }; - -private: - void OnClose (wxCloseEvent& event) { EndModal(BUTTON_CANCEL); } - void OnCancel(wxCommandEvent& event) { EndModal(BUTTON_CANCEL); } - void OnFindNext(wxCommandEvent& event); - void OnText(wxCommandEvent& event); - - wxString& searchText_; - bool& respectCase_; -}; - - -SearchDlg::SearchDlg(wxWindow* parent, wxString& searchText, bool& respectCase) : - SearchDialogGenerated(parent), - searchText_(searchText), - respectCase_(respectCase) -{ -#ifdef ZEN_WIN - new zen::MouseMoveWindow(*this); //allow moving main dialog by clicking (nearly) anywhere...; ownership passed to "this" -#endif - - m_checkBoxMatchCase->SetValue(respectCase_); - m_textCtrlSearchTxt->SetValue(searchText_); - - m_textCtrlSearchTxt->SetFocus(); -} - - -void SearchDlg::OnFindNext(wxCommandEvent& event) -{ - respectCase_ = m_checkBoxMatchCase->GetValue(); - searchText_ = m_textCtrlSearchTxt->GetValue(); - EndModal(BUTTON_OKAY); -} +using namespace zen; -void SearchDlg::OnText(wxCommandEvent& event) +namespace { - if (m_textCtrlSearchTxt->GetValue().Trim().IsEmpty()) - m_buttonFindNext->Disable(); - else - m_buttonFindNext->Enable(); - - event.Skip(); -} -//########################################################################################### - -template <bool respectCase> -class FindInText; - template <bool respectCase> -class FindInText +class ContainsMatch { public: - FindInText(const wxString& textToFind) : textToFind_(textToFind) {} - bool found(const wxString& phrase) const { return contains(phrase, textToFind_); } + ContainsMatch(const wxString& textToFind) : textToFind_(textToFind) {} + bool operator()(const wxString& phrase) const { return contains(phrase, textToFind_); } private: wxString textToFind_; @@ -88,11 +25,11 @@ private: template <> -class FindInText<false> +class ContainsMatch<false> { public: - FindInText(const wxString& textToFind) : textToFind_(textToFind) { textToFind_.MakeUpper(); } - bool found(wxString&& phrase) const + ContainsMatch(const wxString& textToFind) : textToFind_(textToFind) { textToFind_.MakeUpper(); } + bool operator()(wxString&& phrase) const { //wxWidgets::MakeUpper() is inefficient! But performance is not THAT important for this high-level search functionality phrase.MakeUpper(); @@ -111,102 +48,53 @@ ptrdiff_t findRow(const Grid& grid, //return -1 if no matching row found size_t rowFirst, //specify area to search: size_t rowLast) // [rowFirst, rowLast) { - auto prov = grid.getDataProvider(); - std::vector<Grid::ColumnAttribute> colAttr = grid.getColumnConfig(); - vector_remove_if(colAttr, [](const Grid::ColumnAttribute& ca) { return !ca.visible_; }); - if (!colAttr.empty() && prov) + if (auto prov = grid.getDataProvider()) { - const FindInText<respectCase> searchTxt(searchString); + std::vector<Grid::ColumnAttribute> colAttr = grid.getColumnConfig(); + vector_remove_if(colAttr, [](const Grid::ColumnAttribute& ca) { return !ca.visible_; }); + if (!colAttr.empty()) + { + const ContainsMatch<respectCase> containsMatch(searchString); - 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; + for (size_t row = rowFirst; row < rowLast; ++row) + for (auto iterCol = colAttr.begin(); iterCol != colAttr.end(); ++iterCol) + if (containsMatch(prov->getValue(row, iterCol->type_))) + return row; + } } return -1; } - - -//syntactic sugar... -ptrdiff_t findRow(Grid& grid, - bool respectCase, - const wxString& searchString, - size_t rowFirst, //specify area to search: - size_t rowLast) // [rowFirst, rowLast) -{ - return respectCase ? - findRow<true>( grid, searchString, rowFirst, rowLast) : - findRow<false>(grid, searchString, rowFirst, rowLast); } -wxString lastSearchString; //this variable really is conceptionally global... - - -void executeSearch(bool forceShowDialog, - bool& respectCase, - wxWindow* parent, - Grid* gridL, Grid* gridR) +std::pair<const Grid*, ptrdiff_t> zen::findGridMatch(const Grid& grid1, const Grid& grid2, const wxString& searchString, bool respectCase) { - bool searchDialogWasShown = false; - - if (forceShowDialog || lastSearchString.IsEmpty()) - { - SearchDlg searchDlg(parent, lastSearchString, respectCase); //wxWidgets deletion handling -> deleted by parentWindow - if (static_cast<SearchDlg::ReturnCodes>(searchDlg.ShowModal()) != SearchDlg::BUTTON_OKAY) - return; - - searchDialogWasShown = true; - } - - if (wxWindow::FindFocus() == &gridR->getMainWin()) - std::swap(gridL, gridR); //select side to start with + const size_t rowCountL = grid1.getRowCount(); + const size_t rowCountR = grid2.getRowCount(); + auto cursorPos = grid1.getGridCursor(); //(row, component pos) - const size_t rowCountL = gridL->getRowCount(); - const size_t rowCountR = gridR->getRowCount(); - auto cursorPos = gridL->getGridCursor(); //(row, component pos) + std::pair<const Grid*, ptrdiff_t> result(nullptr, -1); size_t cursorRowL = cursorPos.first; if (cursorRowL >= rowCountL) cursorRowL = 0; { - wxBusyCursor showHourGlass; - - auto finishSearch = [&](Grid& grid, size_t rowFirst, size_t rowLast) -> bool + auto finishSearch = [&](const Grid& grid, size_t rowFirst, size_t rowLast) -> bool { - const ptrdiff_t targetRow = findRow(grid, respectCase, lastSearchString, rowFirst, rowLast); + const ptrdiff_t targetRow = respectCase ? + findRow<true>( grid, searchString, rowFirst, rowLast) : + findRow<false>(grid, searchString, rowFirst, rowLast); if (targetRow >= 0) { - //gridOther.clearSelection(); -> not needed other grids are automatically cleared after selection - grid.setGridCursor(targetRow); - grid.SetFocus(); + result = std::make_pair(&grid, targetRow); return true; } return false; }; - if (finishSearch(*gridL, cursorRowL + 1, rowCountL) || - finishSearch(*gridR, 0, rowCountR) || - finishSearch(*gridL, 0, cursorRowL + 1)) - return; + if (!finishSearch(grid1, cursorRowL + 1, rowCountL)) + if (!finishSearch(grid2, 0, rowCountR)) + finishSearch(grid1, 0, cursorRowL + 1); } - - wxMessageBox(replaceCpy(_("Cannot find %x"), L"%x", L"\"" + lastSearchString + L"\"", false), _("Find"), wxOK, parent); - - //show search dialog again - if (searchDialogWasShown) - executeSearch(true, respectCase, parent, gridL, gridR); -} -//########################################################################################### - - -void zen::startFind(wxWindow* parent, Grid& gridL, Grid& gridR, bool& respectCase) //Strg + F -{ - executeSearch(true, respectCase, parent, &gridL, &gridR); -} - - -void zen::findNext(wxWindow* parent, Grid& gridL, Grid& gridR, bool& respectCase) //F3 -{ - executeSearch(false, respectCase, parent, &gridL, &gridR); -} + return result; +}
\ No newline at end of file diff --git a/ui/search.h b/ui/search.h index dd92d5b6..1adf3d01 100644 --- a/ui/search.h +++ b/ui/search.h @@ -4,15 +4,15 @@ // * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved * // ************************************************************************** -#ifndef SEARCH_H_INCLUDED -#define SEARCH_H_INCLUDED +#ifndef SEARCH_H_423905762345342526587 +#define SEARCH_H_423905762345342526587 #include <wx+/grid.h> namespace zen { -void startFind(wxWindow* parent, Grid& gridL, Grid& gridR, bool& respectCase); //Strg + F -void findNext( wxWindow* parent, Grid& gridL, Grid& gridR, bool& respectCase); //F3 +std::pair<const Grid*, ptrdiff_t> findGridMatch(const Grid& grid1, const Grid& grid2, const wxString& searchString, bool respectCase); +//returns (grid/row) where the value was found, (nullptr, -1) if not found } -#endif // SEARCH_H_INCLUDED +#endif //SEARCH_H_423905762345342526587 diff --git a/ui/small_dlgs.cpp b/ui/small_dlgs.cpp index b7b7828b..19ad5417 100644 --- a/ui/small_dlgs.cpp +++ b/ui/small_dlgs.cpp @@ -11,7 +11,7 @@ #include <zen/tick_count.h> #include <zen/stl_tools.h> #include <wx+/choice_enum.h> -#include <wx+/button.h> +#include <wx+/bitmap_button.h> #include <wx+/rtl.h> #include <wx+/no_flicker.h> #include <wx+/mouse_move_dlg.h> @@ -66,18 +66,15 @@ AboutDlg::AboutDlg(wxWindow* parent) : AboutDlgGenerated(parent) wxStaticBitmap* staticBitmapFlag = new wxStaticBitmap(m_scrolledWindowTranslators, wxID_ANY, getResourceImage(it->languageFlag), wxDefaultPosition, wxSize(-1, 11), 0 ); fgSizerTranslators->Add(staticBitmapFlag, 0, wxALIGN_CENTER); - //language name - wxStaticText* staticTextLanguage = new wxStaticText(m_scrolledWindowTranslators, wxID_ANY, it->languageName, wxDefaultPosition, wxDefaultSize, 0 ); - staticTextLanguage->Wrap(-1); - fgSizerTranslators->Add(staticTextLanguage, 0, wxALIGN_CENTER_VERTICAL); - //translator name wxStaticText* staticTextTranslator = new wxStaticText(m_scrolledWindowTranslators, wxID_ANY, it->translatorName, wxDefaultPosition, wxDefaultSize, 0 ); staticTextTranslator->Wrap(-1); fgSizerTranslators->Add(staticTextTranslator, 0, wxALIGN_CENTER_VERTICAL); - } - bSizerTranslators->Fit(m_scrolledWindowTranslators); + staticBitmapFlag ->SetToolTip(it->languageName); + staticTextTranslator->SetToolTip(it->languageName); + } + fgSizerTranslators->Fit(m_scrolledWindowTranslators); #ifdef ZEN_WIN new zen::MouseMoveWindow(*this); //-> put *after* creating credits @@ -112,7 +109,6 @@ AboutDlg::AboutDlg(wxWindow* parent) : AboutDlgGenerated(parent) tmp.Resize(wxSize(GetClientSize().GetWidth(), tmp.GetHeight()), wxPoint(0, 0), 255, 255, 255); //enlarge to fit full width bmpLogo = wxBitmap(tmp); } - { wxMemoryDC dc(bmpLogo); dc.SetTextForeground(wxColor(2, 2, 2)); //for some unknown reason SetBitmap below seems to replace wxBLACK with white on accessibility high contrast schemes!! @@ -177,14 +173,16 @@ FilterDlg::FilterDlg(wxWindow* parent, setRelativeFontSize(*m_staticTextHeader, 1.25); +#ifndef __WXGTK__ //wxWidgets holds portability promise by not supporting for multi-line controls...not m_textCtrlInclude->SetMaxLength(0); //allow large filter entries! m_textCtrlExclude->SetMaxLength(0); // +#endif 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_NONE, L"(" + _("Inactive") + L")"). //meta options should be enclosed in parentheses add(UTIME_TODAY, _("Today")). // add(UTIME_THIS_WEEK, _("This week")). add(UTIME_THIS_MONTH, _("This month")). @@ -192,7 +190,7 @@ FilterDlg::FilterDlg(wxWindow* parent, add(UTIME_LAST_X_DAYS, _("Last x days")); enumSizeDescr. - add(USIZE_NONE, _("Inactive")). + add(USIZE_NONE, L"(" + _("Inactive") + L")"). //meta options should be enclosed in parentheses add(USIZE_BYTE, _("Byte")). add(USIZE_KB, _("KB")). add(USIZE_MB, _("MB")); @@ -369,7 +367,9 @@ DeleteDialog::DeleteDialog(wxWindow* parent, m_checkBoxDeleteBothSides->SetValue(true); } +#ifndef __WXGTK__ //wxWidgets holds portability promise by not supporting for multi-line controls...not m_textCtrlFileList->SetMaxLength(0); //allow large entries! +#endif updateGui(); @@ -390,8 +390,8 @@ void DeleteDialog::updateGui() wxString header; if (m_checkBoxUseRecycler->GetValue()) { - header = _P("Do you really want to move the following item to the Recycle Bin?", - "Do you really want to move the following %x items to the Recycle Bin?", delInfo.second); + header = _P("Do you really want to move the following item to the recycle bin?", + "Do you really want to move the following %x items to the recycle bin?", delInfo.second); m_bitmapDeleteType->SetBitmap(getResourceImage(L"recycler")); } else @@ -587,7 +587,7 @@ CompareCfgDialog::CompareCfgDialog(wxWindow* parent, m_bpButtonHelp->SetBitmapLabel(getResourceImage(L"help")); enumDescrHandleSyml. - add(SYMLINK_IGNORE, _("Exclude")). + add(SYMLINK_EXCLUDE, _("Exclude")). add(SYMLINK_USE_DIRECTLY, _("Direct")). add(SYMLINK_FOLLOW_LINK, _("Follow")); @@ -679,7 +679,7 @@ private: virtual void OnRemoveRow(wxCommandEvent& event); void onResize(wxSizeEvent& event); - void set(const xmlAccess::ExternalApps& extApp); + void setExtApp(const xmlAccess::ExternalApps& extApp); xmlAccess::ExternalApps getExtApp(); xmlAccess::XmlGlobalSettings& settings; @@ -698,9 +698,9 @@ GlobalSettingsDlg::GlobalSettingsDlg(wxWindow* parent, xmlAccess::XmlGlobalSetti setRelativeFontSize(*m_staticTextHeader, 1.25); m_bitmapSettings ->SetBitmap (getResourceImage(L"settings")); - m_buttonResetDialogs->setBitmapFront(getResourceImage(L"reset_dialogs"), 5); m_bpButtonAddRow ->SetBitmapLabel(getResourceImage(L"item_add")); m_bpButtonRemoveRow ->SetBitmapLabel(getResourceImage(L"item_remove")); + setBitmapTextLabel(*m_buttonResetDialogs, getResourceImage(L"reset_dialogs").ConvertToImage(), m_buttonResetDialogs->GetLabel()); m_checkBoxCopyLocked ->SetValue(globalSettings.copyLockedFiles); m_checkBoxTransCopy ->SetValue(globalSettings.transactionalFileCopy); @@ -713,7 +713,7 @@ GlobalSettingsDlg::GlobalSettingsDlg(wxWindow* parent, xmlAccess::XmlGlobalSetti m_staticTextCopyLocked->Hide(); #endif - set(globalSettings.gui.externelApplications); + setExtApp(globalSettings.gui.externelApplications); const wxString toolTip = wxString(_("Integrate external applications into context menu. The following macros are available:")) + L"\n\n" + L"%item_path% \t" + _("- full file or folder name") + L"\n" + @@ -782,11 +782,11 @@ void GlobalSettingsDlg::OnDefault(wxCommandEvent& event) m_checkBoxCopyLocked ->SetValue(defaultCfg.copyLockedFiles); m_checkBoxTransCopy ->SetValue(defaultCfg.transactionalFileCopy); m_checkBoxCopyPermissions->SetValue(defaultCfg.copyFilePermissions); - set(defaultCfg.gui.externelApplications); + setExtApp(defaultCfg.gui.externelApplications); } -void GlobalSettingsDlg::set(const xmlAccess::ExternalApps& extApp) +void GlobalSettingsDlg::setExtApp(const xmlAccess::ExternalApps& extApp) { auto extAppTmp = extApp; vector_remove_if(extAppTmp, [](decltype(extAppTmp[0])& entry) { return entry.first.empty() && entry.second.empty(); }); @@ -935,11 +935,15 @@ SelectTimespanDlg::SelectTimespanDlg(wxWindow* parent, Int64& timeFrom, Int64& t m_calendarFrom->SetDate(utcToLocalDateTime(to<time_t>(timeFrom_))); m_calendarTo ->SetDate(utcToLocalDateTime(to<time_t>(timeTo_))); +#if wxCHECK_VERSION(2, 9, 5) + //doesn't seem to be a problem here: +#else //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); +#endif Fit(); m_buttonOkay->SetFocus(); diff --git a/ui/sync_cfg.cpp b/ui/sync_cfg.cpp index 97518be1..d0d32c18 100644 --- a/ui/sync_cfg.cpp +++ b/ui/sync_cfg.cpp @@ -35,10 +35,12 @@ public: ExecWhenFinishedCfg* execWhenFinished); //optional input parameter private: - virtual void OnSyncTwoWay(wxCommandEvent& event) { directionCfg.var = DirectionConfig::AUTOMATIC; updateGui(); } - virtual void OnSyncMirror(wxCommandEvent& event) { directionCfg.var = DirectionConfig::MIRROR; updateGui(); } - virtual void OnSyncUpdate(wxCommandEvent& event) { directionCfg.var = DirectionConfig::UPDATE; updateGui(); } - virtual void OnSyncCustom(wxCommandEvent& event) { directionCfg.var = DirectionConfig::CUSTOM; updateGui(); } + virtual void OnSyncTwoWay(wxCommandEvent& event) { directionCfg.var = DirectionConfig::TWOWAY; updateGui(); } + virtual void OnSyncMirror(wxCommandEvent& event) { directionCfg.var = DirectionConfig::MIRROR; updateGui(); } + virtual void OnSyncUpdate(wxCommandEvent& event) { directionCfg.var = DirectionConfig::UPDATE; updateGui(); } + virtual void OnSyncCustom(wxCommandEvent& event) { directionCfg.var = DirectionConfig::CUSTOM; updateGui(); } + + virtual void OnToggleDetectMovedFiles(wxCommandEvent& event) { directionCfg.detectMovedFiles = !directionCfg.detectMovedFiles; updateGui(); } virtual void OnSyncTwoWayDouble(wxMouseEvent& event); virtual void OnSyncMirrorDouble(wxMouseEvent& event); @@ -101,7 +103,7 @@ void updateConfigIcons(const DirectionConfig& directionCfg, wxBitmapButton* buttonDifferent, wxBitmapButton* buttonConflict) { - if (directionCfg.var != DirectionConfig::AUTOMATIC) //automatic mode needs no sync-directions + if (directionCfg.var != DirectionConfig::TWOWAY) //automatic mode needs no sync-directions { const DirectionSet dirCfg = extractDirections(directionCfg); @@ -211,7 +213,7 @@ SyncCfgDialog::SyncCfgDialog(wxWindow* parent, ExecWhenFinishedCfg* execWhenFinished) : SyncCfgDlgGenerated(parent), handleDeletion(DELETE_TO_RECYCLER), // - onGuiError(ON_GUIERROR_POPUP), //dummy init + onGuiError(ON_GUIERROR_POPUP), //dummy init outSyncCfg(syncCfg), outOptOnGuiError(handleError), outOptExecWhenFinished(execWhenFinished), @@ -298,7 +300,7 @@ SyncCfgDialog::Config SyncCfgDialog::getConfig() const output.syncCfg.versioningDirectory = utfCvrtTo<Zstring>(versioningFolder.getName()); output.syncCfg.versioningStyle = getEnumVal(enumVersioningStyle, *m_choiceVersioningStyle), - ////get single parameter "version limit" from both checkbox and spin ctrl: + //get single parameter "version limit" from both checkbox and spin ctrl: // output.syncCfg.versionCountLimit = m_checkBoxVersionsLimit->GetValue() ? m_spinCtrlVersionsLimit->GetValue() : -1; output.onGuiError = onGuiError; @@ -329,9 +331,13 @@ void SyncCfgDialog::updateGui() m_bpButtonDifferent, m_bpButtonConflict); + //selecting "detect move files" does not always make sense: + m_checkBoxDetectMove->Enable(detectMovedFilesSelectable(directionCfg)); + m_checkBoxDetectMove->SetValue(detectMovedFilesEnabled(directionCfg)); //parameter NOT owned by checkbox! + //display only relevant sync options - m_bitmapDatabase ->Show(cfg.syncCfg.directionCfg.var == DirectionConfig::AUTOMATIC); - sbSizerSyncDirections->Show(cfg.syncCfg.directionCfg.var != DirectionConfig::AUTOMATIC); + m_bitmapDatabase ->Show(cfg.syncCfg.directionCfg.var == DirectionConfig::TWOWAY); + sbSizerSyncDirections->Show(cfg.syncCfg.directionCfg.var != DirectionConfig::TWOWAY); switch (compareVar_) //sbSizerSyncDirections->Show resets child sizers! { @@ -359,7 +365,7 @@ void SyncCfgDialog::updateGui() switch (cfg.syncCfg.directionCfg.var) { - case DirectionConfig::AUTOMATIC: + case DirectionConfig::TWOWAY: m_toggleBtnTwoWay->SetValue(true); m_staticTextAutomatic->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); break; @@ -512,7 +518,7 @@ void pressCustomDir(DirectionConfig& directionCfg, SyncDirection& syncdir) { switch (directionCfg.var) { - case DirectionConfig::AUTOMATIC: + case DirectionConfig::TWOWAY: assert(false); break; case DirectionConfig::MIRROR: @@ -525,20 +531,21 @@ void pressCustomDir(DirectionConfig& directionCfg, SyncDirection& syncdir) toggleSyncDirection(syncdir); //some config optimization: if custom settings happen to match "mirror" or "update", just switch variant - DirectionSet currentSet = extractDirections(directionCfg); - DirectionSet setMirror; - DirectionSet setUpdate; + const DirectionSet setMirror = [] { DirectionConfig mirrorCfg; mirrorCfg.var = DirectionConfig::MIRROR; - setMirror = extractDirections(mirrorCfg); - } + return extractDirections(mirrorCfg); + }(); + + const DirectionSet setUpdate = [] { DirectionConfig updateCfg; updateCfg.var = DirectionConfig::UPDATE; - setUpdate = extractDirections(updateCfg); - } + return extractDirections(updateCfg); + }(); + const DirectionSet currentSet = extractDirections(directionCfg); if (currentSet == setMirror) directionCfg.var = DirectionConfig::MIRROR; else if (currentSet == setUpdate) diff --git a/ui/tree_view.cpp b/ui/tree_view.cpp index 791fa6cc..cf4eb2e8 100644 --- a/ui/tree_view.cpp +++ b/ui/tree_view.cpp @@ -57,9 +57,7 @@ void TreeView::extractVisibleSubtree(HierarchyObject& hierObj, //in }; cont.firstFileId = nullptr; - std::for_each(hierObj.refSubFiles().begin(), hierObj.refSubFiles().end(), - [&](FilePair& fileObj) - { + for (FilePair& fileObj : hierObj.refSubFiles()) if (pred(fileObj)) { cont.bytesNet += getBytes(fileObj); @@ -68,11 +66,8 @@ void TreeView::extractVisibleSubtree(HierarchyObject& hierObj, //in if (!cont.firstFileId) cont.firstFileId = fileObj.getId(); } - }); - std::for_each(hierObj.refSubLinks().begin(), hierObj.refSubLinks().end(), - [&](SymlinkPair& linkObj) - { + for (SymlinkPair& linkObj : hierObj.refSubLinks()) if (pred(linkObj)) { ++cont.itemCountNet; @@ -80,14 +75,13 @@ void TreeView::extractVisibleSubtree(HierarchyObject& hierObj, //in if (!cont.firstFileId) cont.firstFileId = linkObj.getId(); } - }); + cont.bytesGross += cont.bytesNet; cont.itemCountGross += cont.itemCountNet; cont.subDirs.reserve(hierObj.refSubDirs().size()); //avoid expensive reallocations! - std::for_each(hierObj.refSubDirs().begin(), hierObj.refSubDirs().end(), - [&cont, pred](DirPair& subDirObj) + for (DirPair& subDirObj : hierObj.refSubDirs()) { const bool included = pred(subDirObj); @@ -107,7 +101,7 @@ void TreeView::extractVisibleSubtree(HierarchyObject& hierObj, //in subDirView.objId = subDirObj.getId(); compressNode(subDirView); } - }); + } } @@ -121,30 +115,30 @@ void calcPercentage(std::vector<std::pair<UInt64, int*>>& workList) 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; }); + for (std::pair<UInt64, int*>& pair : workList) + *pair.second = 0; return; } int remainingPercent = 100; - std::for_each(workList.begin(), workList.end(), - [&](std::pair<UInt64, int*>& pair) + for (std::pair<UInt64, int*>& pair : workList) { - *pair.second = to<double>(pair.first) * 100 / to<double>(total); //round down + *pair.second = to<int>(pair.first * 100U / total); //round down remainingPercent -= *pair.second; - }); + } + assert(remainingPercent >= 0); + assert(remainingPercent < static_cast<int>(workList.size())); - //find #remainingPercent items with largest absolute error + //distribute remaining percent so that overall error is minimized as much as possible: remainingPercent = std::min(remainingPercent, static_cast<int>(workList.size())); if (remainingPercent > 0) { 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; + return lhs.first * 100U % total > rhs.first * 100U % total; }); - //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; }); } } @@ -244,7 +238,7 @@ void TreeView::sortSingleLevel(std::vector<TreeLine>& items, ColumnTypeNavi colu } -void TreeView::getChildren(const Container& cont, size_t level, std::vector<TreeLine>& output) +void TreeView::getChildren(const Container& cont, unsigned int level, std::vector<TreeLine>& output) { output.clear(); output.reserve(cont.subDirs.size() + 1); //keep pointers in "workList" valid @@ -453,7 +447,7 @@ void TreeView::reduceNode(size_t row) { if (row < flatTree.size()) { - const size_t parentLevel = flatTree[row].level_; + const unsigned int parentLevel = flatTree[row].level_; bool done = false; flatTree.erase(std::remove_if(flatTree.begin() + row + 1, flatTree.end(), @@ -477,7 +471,7 @@ ptrdiff_t TreeView::getParent(size_t row) const { if (row < flatTree.size()) { - const size_t level = flatTree[row].level_; + const auto level = flatTree[row].level_; while (row-- > 0) if (flatTree[row].level_ < level) @@ -638,18 +632,13 @@ std::unique_ptr<TreeView::Node> TreeView::getLine(size_t row) const HierarchyObject& parent = firstFile->parent(); //lazy evaluation: recheck "lastViewFilterPred" again rather than buffer and bloat "lastViewFilterPred" - std::for_each(parent.refSubFiles().begin(), parent.refSubFiles().end(), - [&](FileSystemObject& fsObj) - { + for (FileSystemObject& fsObj : parent.refSubFiles()) if (lastViewFilterPred(fsObj)) filesAndLinks.push_back(&fsObj); - }); - std::for_each(parent.refSubLinks().begin(), parent.refSubLinks().end(), - [&](FileSystemObject& fsObj) - { + + for (FileSystemObject& fsObj : parent.refSubLinks()) if (lastViewFilterPred(fsObj)) filesAndLinks.push_back(&fsObj); - }); return make_unique<TreeView::FilesNode>(percent, parentDir->bytesNet, parentDir->itemCountNet, level, filesAndLinks); } @@ -664,10 +653,6 @@ std::unique_ptr<TreeView::Node> TreeView::getLine(size_t row) const namespace { -#ifdef _MSC_VER -#pragma warning(disable:4428) // VC wrongly issues warning C4428: universal-character-name encountered in source -#endif - wxString getShortDisplayNameForFolderPair(const Zstring& dirLeftPf, const Zstring& dirRightPf) //post-fixed with separator { assert(endsWith(dirLeftPf, FILE_NAME_SEPARATOR) || dirLeftPf .empty()); @@ -1015,7 +1000,7 @@ private: rectTmp.width -= widthNodeIcon + GAP_SIZE; if (rectTmp.width > 0) - drawCellText(dc, rectTmp, getValue(row, colType), grid.IsEnabled(), wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + drawCellText(dc, rectTmp, getValue(row, colType), isActive, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); } } } @@ -1038,11 +1023,11 @@ private: rectTmp.width -= 2 * GAP_SIZE; } - drawCellText(dc, rectTmp, getValue(row, colType), grid.IsEnabled(), alignment); + drawCellText(dc, rectTmp, getValue(row, colType), true, alignment); } } - virtual size_t getBestSize(wxDC& dc, size_t row, ColumnType colType) + virtual int getBestSize(wxDC& dc, size_t row, ColumnType colType) { // -> synchronize renderCell() <-> getBestSize() <-> onMouseLeft() diff --git a/ui/tree_view.h b/ui/tree_view.h index d7289d17..719212dd 100644 --- a/ui/tree_view.h +++ b/ui/tree_view.h @@ -57,12 +57,12 @@ public: //--------------------------------------------------------------------- struct Node { - Node(int percent, UInt64 bytes, int itemCount, size_t level, NodeStatus status) : + Node(int percent, UInt64 bytes, int itemCount, unsigned int level, NodeStatus status) : percent_(percent), level_(level), status_(status), bytes_(bytes), itemCount_(itemCount) {} virtual ~Node() {} const int percent_; //[0, 100] - const size_t level_; + const unsigned int level_; const NodeStatus status_; const UInt64 bytes_; const int itemCount_; @@ -70,13 +70,13 @@ public: struct FilesNode : public Node { - FilesNode(int percent, UInt64 bytes, int itemCount, size_t level, const std::vector<FileSystemObject*>& filesAndLinks) : Node(percent, bytes, itemCount, level, STATUS_EMPTY), filesAndLinks_(filesAndLinks) {} + FilesNode(int percent, UInt64 bytes, int itemCount, unsigned int level, const std::vector<FileSystemObject*>& filesAndLinks) : Node(percent, bytes, itemCount, level, STATUS_EMPTY), filesAndLinks_(filesAndLinks) {} std::vector<FileSystemObject*> filesAndLinks_; //files or symlinks; pointers are bound! }; struct DirNode : public Node { - DirNode(int percent, UInt64 bytes, int itemCount, size_t level, NodeStatus status, DirPair& dirObj) : Node(percent, bytes, itemCount, level, status), dirObj_(dirObj) {} + DirNode(int percent, UInt64 bytes, int itemCount, unsigned int level, NodeStatus status, DirPair& dirObj) : Node(percent, bytes, itemCount, level, status), dirObj_(dirObj) {} DirPair& dirObj_; }; @@ -137,9 +137,9 @@ private: struct TreeLine { - TreeLine(size_t level, int percent, const Container* node, enum NodeType type) : level_(level), percent_(percent), node_(node), type_(type) {} + TreeLine(unsigned int level, int percent, const Container* node, enum NodeType type) : level_(level), percent_(percent), node_(node), type_(type) {} - size_t level_; + unsigned int 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! @@ -148,7 +148,7 @@ private: 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); + void getChildren(const Container& cont, unsigned int level, std::vector<TreeLine>& output); template <class Predicate> void updateView(Predicate pred); void applySubView(std::vector<RootNodeImpl>&& newView); diff --git a/ui/triple_splitter.cpp b/ui/triple_splitter.cpp index 65c39337..fbdd22d7 100644 --- a/ui/triple_splitter.cpp +++ b/ui/triple_splitter.cpp @@ -13,7 +13,7 @@ using namespace zen; namespace { //------------ Grid Constants ------------------------------- -const int SASH_HIT_TOLERANCE = 5; //currently onla a placebo! +const int SASH_HIT_TOLERANCE = 5; //currently only a placebo! const int SASH_SIZE = 10; const double SASH_GRAVITY = 0.5; //value within [0, 1]; 1 := resize left only, 0 := resize right only const int CHILD_WINDOW_MIN_SIZE = 50; //min. size of managed windows @@ -36,11 +36,9 @@ TripleSplitter::TripleSplitter(wxWindow* parent, Connect(wxEVT_SIZE, wxSizeEventHandler (TripleSplitter::onSizeEvent ), nullptr, this); //http://wiki.wxwidgets.org/Flicker-Free_Drawing Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(TripleSplitter::onEraseBackGround), nullptr, this); -#if wxCHECK_VERSION(2, 9, 1) + SetBackgroundStyle(wxBG_STYLE_PAINT); -#else - SetBackgroundStyle(wxBG_STYLE_CUSTOM); -#endif + Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(TripleSplitter::onMouseLeftDown ), nullptr, this); Connect(wxEVT_LEFT_UP, wxMouseEventHandler(TripleSplitter::onMouseLeftUp ), nullptr, this); Connect(wxEVT_MOTION, wxMouseEventHandler(TripleSplitter::onMouseMovement ), nullptr, this); @@ -49,6 +47,7 @@ TripleSplitter::TripleSplitter(wxWindow* parent, Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(TripleSplitter::onMouseLeftDouble), nullptr, this); } + TripleSplitter::~TripleSplitter() {} //make sure correct destructor gets created for std::unique_ptr<SashMove> @@ -78,7 +77,7 @@ void TripleSplitter::updateWindowSizes() class TripleSplitter::SashMove { public: - SashMove(wxWindow& wnd, int mousePosX, int centerPosX) : wnd_(wnd), mousePosX_(mousePosX), centerPosX_(centerPosX) + SashMove(wxWindow& wnd, int mousePosX, int centerOffset) : wnd_(wnd), mousePosX_(mousePosX), centerOffset_(centerOffset) { wnd_.SetCursor(wxCURSOR_SIZEWE); wnd_.CaptureMouse(); @@ -89,13 +88,13 @@ public: if (wnd_.HasCapture()) wnd_.ReleaseMouse(); } - int getMousePosXStart () { return mousePosX_; } - int getCenterPosXStart() { return centerPosX_; } + int getMousePosXStart () const { return mousePosX_; } + int getCenterOffsetStart() const { return centerOffset_; } private: wxWindow& wnd_; const int mousePosX_; - const int centerPosX_; + const int centerOffset_; }; @@ -113,6 +112,7 @@ int TripleSplitter::getCenterPosXOptimal() const return (clientRect.width - centerWidth) * SASH_GRAVITY; //allowed to be negative for extreme client widths! } + int TripleSplitter::getCenterPosX() const { const wxRect clientRect = GetClientRect(); @@ -120,12 +120,12 @@ int TripleSplitter::getCenterPosX() const const int centerPosXOptimal = getCenterPosXOptimal(); //normalize "centerPosXOptimal + centerOffset" - if (clientRect.width < 2 * CHILD_WINDOW_MIN_SIZE + centerWidth) //continuous transition between conditional branches! + if (clientRect.width < 2 * CHILD_WINDOW_MIN_SIZE + centerWidth) //use fixed "centeroffset" when "clientRect.width == 2 * CHILD_WINDOW_MIN_SIZE + centerWidth" return centerPosXOptimal + CHILD_WINDOW_MIN_SIZE - static_cast<int>(2 * CHILD_WINDOW_MIN_SIZE * SASH_GRAVITY); //avoid rounding error - else - return std::max(CHILD_WINDOW_MIN_SIZE, //make sure centerPosXOptimal + offset is within bounds - std::min(centerPosXOptimal + centerOffset, clientRect.width - CHILD_WINDOW_MIN_SIZE - centerWidth)); + //make sure transition between conditional branches is continuous! + return std::max(CHILD_WINDOW_MIN_SIZE, //make sure centerPosXOptimal + offset is within bounds + std::min(centerPosXOptimal + centerOffset, clientRect.width - CHILD_WINDOW_MIN_SIZE - centerWidth)); } @@ -173,7 +173,7 @@ void TripleSplitter::onMouseLeftDown(wxMouseEvent& event) const int posX = event.GetPosition().x; if (hitOnSashLine(posX)) - activeMove.reset(new SashMove(*this, posX, getCenterPosX())); + activeMove.reset(new SashMove(*this, posX, centerOffset)); event.Skip(); } @@ -189,10 +189,11 @@ void TripleSplitter::onMouseMovement(wxMouseEvent& event) { if (activeMove) { - centerOffset = activeMove->getCenterPosXStart() - getCenterPosXOptimal() + event.GetPosition().x - activeMove->getMousePosXStart(); + centerOffset = activeMove->getCenterOffsetStart() + event.GetPosition().x - activeMove->getMousePosXStart(); - //CAVEAT: centerOffset is evaluated *before* normalization in getCenterPosX()! - //This can lead to the strange effect of window not immediately resizing when centerOffset is extremely off limits => normalize right here + //CAVEAT: function getCenterPosX() normalizes centerPosX *not* centerOffset! + //This can lead to the strange effect of window not immediately resizing when centerOffset is extremely off limits + //=> normalize centerOffset right here centerOffset = getCenterPosX() - getCenterPosXOptimal(); updateWindowSizes(); diff --git a/version/version.h b/version/version.h index 323fa8c4..6a201f47 100644 --- a/version/version.h +++ b/version/version.h @@ -3,7 +3,7 @@ namespace zen { - const wchar_t currentVersion[] = L"5.20"; //internal linkage! +const wchar_t currentVersion[] = L"5.21"; //internal linkage! } #endif diff --git a/wx+/bitmap_button.h b/wx+/bitmap_button.h new file mode 100644 index 00000000..5674f66b --- /dev/null +++ b/wx+/bitmap_button.h @@ -0,0 +1,81 @@ +// ************************************************************************** +// * 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 (zenju AT gmx DOT de) - All Rights Reserved * +// ************************************************************************** + +#ifndef BUTTON_HEADER_83415718945878341563415 +#define BUTTON_HEADER_83415718945878341563415 + +#include <wx/bmpbuttn.h> +#include "image_tools.h" + +namespace zen +{ +//zen::BitmapTextButton is identical to wxBitmapButton, but preserves the label via SetLabel(), which wxFormbuilder would ditch! +class BitmapTextButton : public wxBitmapButton +{ +public: + BitmapTextButton(wxWindow* parent, + wxWindowID id, + const wxString& label, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxValidator& validator = wxDefaultValidator, + const wxString& name = wxButtonNameStr) : + wxBitmapButton(parent, id, wxNullBitmap, pos, size, style | wxBU_AUTODRAW, validator, name) { SetLabel(label); } +}; + +void setBitmapTextLabel(wxBitmapButton& btn, const wxImage& img, const wxString& text, int gap = 5, int border = 5); + +//set bitmap label flicker free: +void setImage(wxBitmapButton& button, const wxBitmap& bmp); + + + + + + + + + + + +//################################### implementation ################################### +inline +void setBitmapTextLabel(wxBitmapButton& btn, const wxImage& img, const wxString& text, int gap, int border) +{ + assert(gap >= 0 && border >= 0); + gap = std::max(0, gap); + border = std::max(0, border); + + wxImage dynImage = createImageFromText(text, btn.GetFont(), btn.GetForegroundColour()); + if (img.IsOk()) + { + if (btn.GetLayoutDirection() != wxLayout_RightToLeft) + dynImage = stackImages(img, dynImage, ImageStackLayout::HORIZONTAL, ImageStackAlignment::CENTER, gap); + else + dynImage = stackImages(dynImage, img, ImageStackLayout::HORIZONTAL, ImageStackAlignment::CENTER, gap); + } + + //SetMinSize() instead of SetSize() is needed here for wxWindows layout determination to work corretly + wxSize minSize = btn.GetMinSize(); + btn.SetMinSize(wxSize(std::max(dynImage.GetWidth () + 2 * border, minSize.GetWidth()), + std::max(dynImage.GetHeight() + 2 * border, minSize.GetHeight()))); + + btn.SetBitmapLabel(wxBitmap(dynImage)); + //SetLabel() calls confuse wxBitmapButton in the disabled state and it won't show the image! workaround: + btn.SetBitmapDisabled(wxBitmap(dynImage.ConvertToDisabled())); +} + + +inline +void setImage(wxBitmapButton& button, const wxBitmap& bmp) +{ + if (!isEqual(button.GetBitmapLabel(), bmp)) + button.SetBitmapLabel(bmp); +} +} + +#endif //BUTTON_HEADER_83415718945878341563415 diff --git a/wx+/button.cpp b/wx+/button.cpp deleted file mode 100644 index 806c0969..00000000 --- a/wx+/button.cpp +++ /dev/null @@ -1,305 +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 (zenju AT gmx DOT de) - All Rights Reserved * -// ************************************************************************** - -#include "button.h" -#include <algorithm> -#include <limits> -#include <cmath> -#include <zen/string_tools.h> -#include <wx/dcmemory.h> -#include <wx/image.h> -#include "image_tools.h" - -using namespace zen; - - -void zen::setImage(wxBitmapButton& button, const wxBitmap& bmp) -{ - if (!isEqual(button.GetBitmapLabel(), bmp)) - button.SetBitmapLabel(bmp); -} - - -BitmapButton::BitmapButton(wxWindow* parent, - wxWindowID id, - const wxString& label, - const wxPoint& pos, - const wxSize& size, - long style, - const wxValidator& validator, - const wxString& name) : - wxBitmapButton(parent, id, wxNullBitmap, pos, size, style | wxBU_AUTODRAW, validator, name), - spaceAfter_(0), - spaceBefore_(0), - innerBorderSize(5) -{ - SetLabel(label); -} - - -void BitmapButton::setBitmapFront(const wxBitmap& bitmap, int spaceAfter) -{ - if (!isEqual(bitmap, bitmapFront) || spaceAfter_ != spaceAfter) //avoid flicker - { - bitmapFront = bitmap; - spaceAfter_ = spaceAfter; - refreshButtonLabel(); - } -} - - -void BitmapButton::SetLabel(const wxString& label) -{ - if (wxBitmapButton::GetLabel() != label) //avoid flicker - { - wxBitmapButton::SetLabel(label); - refreshButtonLabel(); - } -} - -void BitmapButton::setBitmapBack(const wxBitmap& bitmap, int spaceBefore) -{ - if (!isEqual(bitmap, bitmapBack) || spaceBefore_ != spaceBefore) //avoid flicker - { - bitmapBack = bitmap; - spaceBefore_ = spaceBefore; - refreshButtonLabel(); - } -} - - -namespace -{ -void makeWhiteTransparent(wxImage& image) //assume black text on white background -{ - if (unsigned char* alphaFirst = image.GetAlpha()) - { - unsigned char* alphaLast = alphaFirst + image.GetWidth() * image.GetHeight(); - - //dist(black, white) - const double distBlackWhite = 255 * std::sqrt(3.0); - - const unsigned char* bytePos = image.GetData(); - - for (unsigned char* j = alphaFirst; j != alphaLast; ++j) - { - unsigned char r = *bytePos++; // - unsigned char g = *bytePos++; //each pixel consists of three bytes - unsigned char b = *bytePos++; // - - //dist((r,g,b), white) - double distColWhite = std::sqrt((255.0 - r) * (255.0 - r) + - (255.0 - g) * (255.0 - g) + - (255.0 - b) * (255.0 - b)); - - //black(0,0,0) becomes fully opaque(255), while white(255,255,255) becomes transparent(0) - *j = distColWhite / distBlackWhite * wxIMAGE_ALPHA_OPAQUE; - } - } -} - - -wxSize getSizeNeeded(const wxString& text, wxFont& font) -{ - wxCoord width = 0; - wxCoord height = 0; - - //the context used for bitmaps... - wxMemoryDC().GetMultiLineTextExtent(replaceCpy(text, L"&", L"", false), //remove accelerator - &width, &height, nullptr, &font); - - return wxSize(width, height); -} -} - - -wxBitmap BitmapButton::createBitmapFromText(const wxString& text) -{ - //wxDC::DrawLabel() doesn't respect alpha channel at all => apply workaround to calculate alpha values manually: - - if (text.empty()) - return wxBitmap(); - - wxFont currentFont = wxBitmapButton::GetFont(); - wxColor textColor = wxBitmapButton::GetForegroundColour(); - - wxSize sizeNeeded = getSizeNeeded(text, currentFont); - wxBitmap newBitmap(sizeNeeded.GetWidth(), sizeNeeded.GetHeight()); - - { - wxMemoryDC dc(newBitmap); - - //set up white background - dc.SetBackground(*wxWHITE_BRUSH); - dc.Clear(); - - //find position of accelerator - const size_t accelPos = text.find(L"&"); - const int indexAccel = accelPos != wxString::npos ? static_cast<int>(accelPos) : -1; - - dc.SetTextForeground(*wxBLACK); //for use in makeWhiteTransparent - dc.SetTextBackground(*wxWHITE); // - dc.SetFont(currentFont); - - dc.DrawLabel(replaceCpy(text, L"&", L"", false), //remove accelerator - wxNullBitmap, wxRect(0, 0, newBitmap.GetWidth(), newBitmap.GetHeight()), wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, indexAccel); - } - - //add alpha channel to image - wxImage finalImage(newBitmap.ConvertToImage()); - finalImage.SetAlpha(); - - //set values for alpha channel - makeWhiteTransparent(finalImage); - - //now apply real text color - unsigned char* bytePos = finalImage.GetData(); - const int pixelCount = finalImage.GetWidth() * finalImage.GetHeight(); - for (int i = 0; i < pixelCount; ++ i) - { - *bytePos++ = textColor.Red(); - *bytePos++ = textColor.Green(); - *bytePos++ = textColor.Blue(); - } - - return wxBitmap(finalImage); -} - - -//copy one image into another, allowing arbitrary overlapping! (pos may contain negative numbers) -void writeToImage(const wxImage& source, const wxPoint& pos, wxImage& target) -{ - //determine startpositions in source and target image, as well as width and height to be copied - wxPoint posSrc, posTrg; - int width, height; - - //X-axis - if (pos.x < 0) - { - posSrc.x = -pos.x; - posTrg.x = 0; - width = std::min(pos.x + source.GetWidth(), target.GetWidth()); - } - else - { - posSrc.x = 0; - posTrg.x = pos.x; - width = std::min(target.GetWidth() - pos.x, source.GetWidth()); - } - - //Y-axis - if (pos.y < 0) - { - posSrc.y = -pos.y; - posTrg.y = 0; - height = std::min(pos.y + source.GetHeight(), target.GetHeight()); - } - else - { - posSrc.y = 0; - posTrg.y = pos.y; - height = std::min(target.GetHeight() - pos.y, source.GetHeight()); - } - - - if (width > 0 && height > 0) - { - { - //copy source to target respecting overlapping parts - const unsigned char* sourcePtr = source.GetData() + 3 * (posSrc.x + posSrc.y * source.GetWidth()); - const unsigned char* const sourcePtrEnd = source.GetData() + 3 * (posSrc.x + (posSrc.y + height) * source.GetWidth()); - unsigned char* targetPtr = target.GetData() + 3 * (posTrg.x + posTrg.y * target.GetWidth()); - - while (sourcePtr < sourcePtrEnd) - { - memcpy(targetPtr, sourcePtr, 3 * width); - sourcePtr += 3 * source.GetWidth(); - targetPtr += 3 * target.GetWidth(); - } - } - - //handle different cases concerning alpha channel - if (source.HasAlpha()) - { - if (!target.HasAlpha()) - { - target.SetAlpha(); - memset(target.GetAlpha(), wxIMAGE_ALPHA_OPAQUE, target.GetWidth() * target.GetHeight()); - } - - //copy alpha channel - const unsigned char* sourcePtr = source.GetAlpha() + (posSrc.x + posSrc.y * source.GetWidth()); - const unsigned char* const sourcePtrEnd = source.GetAlpha() + (posSrc.x + (posSrc.y + height) * source.GetWidth()); - unsigned char* targetPtr = target.GetAlpha() + (posTrg.x + posTrg.y * target.GetWidth()); - - while (sourcePtr < sourcePtrEnd) - { - memcpy(targetPtr, sourcePtr, width); - sourcePtr += source.GetWidth(); - targetPtr += target.GetWidth(); - } - } - else if (target.HasAlpha()) - { - unsigned char* targetPtr = target.GetAlpha() + (posTrg.x + posTrg.y * target.GetWidth()); - const unsigned char* const targetPtrEnd = target.GetAlpha() + (posTrg.x + (posTrg.y + height) * target.GetWidth()); - - while (targetPtr < targetPtrEnd) - { - memset(targetPtr, wxIMAGE_ALPHA_OPAQUE, width); - targetPtr += target.GetWidth(); - } - } - } -} - - -void BitmapButton::refreshButtonLabel() -{ - wxBitmap bitmapText = createBitmapFromText(GetLabel()); - - auto getSize = [](const wxBitmap& bmp) { return bmp.IsOk() ? wxSize(bmp.GetWidth(), bmp.GetHeight()) : wxSize(0, 0); }; - - wxSize szFront = getSize(bitmapFront); // - wxSize szText = getSize(bitmapText); //make sure to NOT access null-bitmaps! - wxSize szBack = getSize(bitmapBack); // - - //calculate dimensions of new button - const int height = std::max(std::max(szFront.GetHeight(), szText.GetHeight()), szBack.GetHeight()); - const int width = szFront.GetWidth() + spaceAfter_ + szText.GetWidth() + spaceBefore_ + szBack.GetWidth(); - - //create a transparent image - wxImage transparentImage(width, height, false); - transparentImage.SetAlpha(); - unsigned char* alpha = transparentImage.GetAlpha(); - ::memset(alpha, wxIMAGE_ALPHA_TRANSPARENT, width * height); - - //wxDC::DrawLabel() unfortunately isn't working for transparent images on Linux, so we need to use custom image-concatenation - if (bitmapFront.IsOk()) - writeToImage(bitmapFront.ConvertToImage(), - wxPoint(0, (transparentImage.GetHeight() - bitmapFront.GetHeight()) / 2), - transparentImage); - - if (bitmapText.IsOk()) - writeToImage(bitmapText.ConvertToImage(), - wxPoint(szFront.GetWidth() + spaceAfter_, (transparentImage.GetHeight() - bitmapText.GetHeight()) / 2), - transparentImage); - - if (bitmapBack.IsOk()) - writeToImage(bitmapBack.ConvertToImage(), - wxPoint(szFront.GetWidth() + spaceAfter_ + szText.GetWidth() + spaceBefore_, (transparentImage.GetHeight() - bitmapBack.GetHeight()) / 2), - transparentImage); - - //adjust button size - wxSize minSize = GetMinSize(); - - //SetMinSize() instead of SetSize() is needed here for wxWindows layout determination to work corretly - wxBitmapButton::SetMinSize(wxSize(std::max(width + 2 * innerBorderSize, minSize.GetWidth()), - std::max(height + 2 * innerBorderSize, minSize.GetHeight()))); - - //finally set bitmap - wxBitmapButton::SetBitmapLabel(wxBitmap(transparentImage)); -} diff --git a/wx+/button.h b/wx+/button.h deleted file mode 100644 index 42174a44..00000000 --- a/wx+/button.h +++ /dev/null @@ -1,53 +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 (zenju AT gmx DOT de) - All Rights Reserved * -// ************************************************************************** - -#ifndef CUSTOMBUTTON_H_INCLUDED -#define CUSTOMBUTTON_H_INCLUDED - -#include <wx/bmpbuttn.h> - -namespace zen -{ -//zen::BitmapButton behaves like wxButton but optionally adds bitmap labels -class BitmapButton : public wxBitmapButton -{ -public: - BitmapButton(wxWindow* parent, - wxWindowID id, - const wxString& label, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = 0, - const wxValidator& validator = wxDefaultValidator, - const wxString& name = wxButtonNameStr); - - void setBitmapFront(const wxBitmap& bitmap, int spaceAfter = 0); //...and enlarge button if required! - void setBitmapBack (const wxBitmap& bitmap, int spaceBefore = 0); // - - void setInnerBorderSize(int sz) { innerBorderSize = sz; refreshButtonLabel(); } - - virtual void SetLabel(const wxString& label); - - void refreshButtonLabel(); //e.g. after font change - -private: - wxBitmap createBitmapFromText(const wxString& text); - - wxBitmap bitmapFront; - int spaceAfter_; - ///wxString textLabel; - int spaceBefore_; - wxBitmap bitmapBack; - - int innerBorderSize; -}; - -//set bitmap label flicker free! -void setImage(wxBitmapButton& button, const wxBitmap& bmp); -} - - -#endif // CUSTOMBUTTON_H_INCLUDED @@ -74,8 +74,8 @@ public: } private: - //associate "active" clipping area with each DC - static hash_map<wxDC*, wxRect>& refDcToAreaMap() { static hash_map<wxDC*, wxRect> clippingAreas; return clippingAreas; } + //associate "active" clipping area with each DC + static hash_map<wxDC*, wxRect>& refDcToAreaMap() { static hash_map<wxDC*, wxRect> clippingAreas; return clippingAreas; } std::unique_ptr<wxRect> oldRect; wxDC& dc_; diff --git a/wx+/graph.cpp b/wx+/graph.cpp index cbedfa53..29ec4f36 100644 --- a/wx+/graph.cpp +++ b/wx+/graph.cpp @@ -16,7 +16,7 @@ using namespace zen; -//todo: support zoom via mouse wheel +//todo: support zoom via mouse wheel? const wxEventType zen::wxEVT_GRAPH_SELECTION = wxNewEventType(); @@ -218,40 +218,38 @@ void drawCornerText(wxDC& dc, const wxRect& graphArea, const wxString& txt, Grap } -warn_static("review") - +//calculate intersection of polygon with half-plane template <class Function, class Function2> void cutPoints(std::vector<CurvePoint>& curvePoints, std::vector<char>& oobMarker, Function isInside, Function2 getIntersection) { assert(curvePoints.size() == oobMarker.size()); if (curvePoints.size() != oobMarker.size() || curvePoints.empty()) return; - auto isMarkedOob = [&](size_t index) { return oobMarker[index] != 0; }; + auto isMarkedOob = [&](size_t index) { return oobMarker[index] != 0; }; //test if point is start of a OOB line std::vector<CurvePoint> curvePointsTmp; - std::vector<char> oobMarkerTmp; - auto savePoint = [&](const CurvePoint& pt, bool markedOob) { curvePointsTmp.push_back(pt); oobMarkerTmp.push_back(markedOob); }; + std::vector<char> oobMarkerTmp; + curvePointsTmp.reserve(curvePoints.size()); //allocating memory for these containers is one + oobMarkerTmp .reserve(oobMarker .size()); //of the more expensive operations of Graph2D! - warn_static("perf: avoid these push_backs") + auto savePoint = [&](const CurvePoint& pt, bool markedOob) { curvePointsTmp.push_back(pt); oobMarkerTmp.push_back(markedOob); }; - bool lastPointInside = isInside(curvePoints[0]); - if (lastPointInside) + bool pointInside = isInside(curvePoints[0]); + if (pointInside) savePoint(curvePoints[0], isMarkedOob(0)); - for (auto it = curvePoints.begin() + 1; it != curvePoints.end(); ++it) + for (size_t index = 1; index < curvePoints.size(); ++index) { - const size_t index = it - curvePoints.begin(); - - const bool pointInside = isInside(*it); - if (pointInside != lastPointInside) + if (isInside(curvePoints[index]) != pointInside) { - lastPointInside = pointInside; - - const CurvePoint is = getIntersection(*(it - 1), *it); //getIntersection returns *it when delta is zero + pointInside = !pointInside; + const CurvePoint is = getIntersection(curvePoints[index - 1], + curvePoints[index]); //getIntersection returns *it when delta is zero savePoint(is, !pointInside || isMarkedOob(index - 1)); } if (pointInside) - savePoint(*it, isMarkedOob(index)); + savePoint(curvePoints[index], isMarkedOob(index)); } + curvePointsTmp.swap(curvePoints); oobMarkerTmp .swap(oobMarker); } @@ -264,7 +262,7 @@ struct GetIntersectionX { const double deltaX = to.x - from.x; const double deltaY = to.y - from.y; - return !numeric::isNull(deltaX) ? CurvePoint(x_, from.y + (x_ - from.x) / deltaX * deltaY) : to; + return numeric::isNull(deltaX) ? to : CurvePoint(x_, from.y + (x_ - from.x) / deltaX * deltaY); }; private: double x_; @@ -277,7 +275,7 @@ struct GetIntersectionY { const double deltaX = to.x - from.x; const double deltaY = to.y - from.y; - return !numeric::isNull(deltaY) ? CurvePoint(from.x + (y_ - from.y) / deltaY * deltaX, y_) : to; + return numeric::isNull(deltaY) ? to : CurvePoint(from.x + (y_ - from.y) / deltaY * deltaX, y_); }; private: double y_; @@ -285,6 +283,7 @@ private: void cutPointsOutsideX(std::vector<CurvePoint>& curvePoints, std::vector<char>& oobMarker, double minX, double maxX) { + assert(std::find(oobMarker.begin(), oobMarker.end(), true) == oobMarker.end()); cutPoints(curvePoints, oobMarker, [&](const CurvePoint& pt) { return pt.x >= minX; }, GetIntersectionX(minX)); cutPoints(curvePoints, oobMarker, [&](const CurvePoint& pt) { return pt.x <= maxX; }, GetIntersectionX(maxX)); } @@ -297,27 +296,28 @@ void cutPointsOutsideY(std::vector<CurvePoint>& curvePoints, std::vector<char>& } -warn_static("review") void ContinuousCurveData::getPoints(double minX, double maxX, int pixelWidth, std::vector<CurvePoint>& points) const { if (pixelWidth <= 1) return; const ConvertCoord cvrtX(minX, maxX, pixelWidth - 1); //map [minX, maxX] to [0, pixelWidth - 1] - std::pair<double, double> rangeX = getRangeX(); - //catch large double values: if double is larger than what int can represent => undefined behavior! - const double xOutOfBoundsLow = cvrtX.screenToReal(-1); - const double xOutOfBoundsHigh = cvrtX.screenToReal(pixelWidth); - numeric::confine(rangeX.first , xOutOfBoundsLow, xOutOfBoundsHigh); //don't confine to [minX, maxX] which - numeric::confine(rangeX.second, xOutOfBoundsLow, xOutOfBoundsHigh); //would prevent empty ranges - - const int posFrom = std::ceil (cvrtX.realToScreen(std::max(rangeX.first, minX))); //do not step outside [minX, maxX] - const int posTo = std::floor(cvrtX.realToScreen(std::min(rangeX.second, maxX))); // - //conversion from std::floor/std::ceil double return value to int is loss-free for full value range of 32-bit int! tested successfully on MSVC + const std::pair<double, double> rangeX = getRangeX(); - for (int i = posFrom; i <= posTo; ++i) + const double screenLow = cvrtX.realToScreen(std::max(rangeX.first, minX)); //=> xLow >= 0 + const double screenHigh = cvrtX.realToScreen(std::min(rangeX.second, maxX)); //=> xHigh <= pixelWidth - 1 + //if double is larger than what int can represent => undefined behavior! + //=> convert to int not before checking value range! + if (screenLow <= screenHigh) { - const double x = cvrtX.screenToReal(i); - points.push_back(CurvePoint(x, getValue(x))); + const int posFrom = std::ceil (screenLow ); //do not step outside [minX, maxX] in loop below! + const int posTo = std::floor(screenHigh); // + //conversion from std::floor/std::ceil double return value to int is loss-free for full value range of 32-bit int! tested successfully on MSVC + + for (int i = posFrom; i <= posTo; ++i) + { + const double x = cvrtX.screenToReal(i); + points.push_back(CurvePoint(x, getValue(x))); + } } } @@ -330,10 +330,15 @@ void SparseCurveData::getPoints(double minX, double maxX, int pixelWidth, std::v auto addPoint = [&](const CurvePoint& pt) { - warn_static("verify steps") - if (addSteps_ && !points.empty()) - if (pt.y != points.back().y) - points.push_back(CurvePoint(pt.x, points.back().y)); + if (!points.empty()) + { + if (pt.x <= points.back().x) //allow ascending x-positions only! algorithm below may cause double-insertion after empty x-ranges! + return; + + if (addSteps_) + if (pt.y != points.back().y) + points.push_back(CurvePoint(pt.x, points.back().y)); + } points.push_back(pt); }; @@ -345,13 +350,37 @@ void SparseCurveData::getPoints(double minX, double maxX, int pixelWidth, std::v const double x = cvrtX.screenToReal(i); Opt<CurvePoint> ptLe = getLessEq(x); Opt<CurvePoint> ptGe = getGreaterEq(x); - //both non-existent and invalid return values are mapped to out of expected range: => check on posLe/posGe NOT ptLe/ptGE in the following! + //both non-existent and invalid return values are mapped to out of expected range: => check on posLe/posGe NOT ptLe/ptGe in the following! const int posLe = ptLe ? cvrtX.realToScreenRound(ptLe->x) : i + 1; const int posGe = ptGe ? cvrtX.realToScreenRound(ptGe->x) : i - 1; assert(!ptLe || posLe <= i); //check for invalid return values assert(!ptGe || posGe >= i); // - - if (posGe == i) //test if point would be mapped to pixel x-position i + /* + Breakdown of all combinations of posLe, posGe and expected action (n >= 1) + Note: For every empty x-range of at least one pixel, both next and previous points must be saved to keep the interpolating line stable!!! + + posLe | posGe | action + +-------+-------+-------- + | none | none | break + | i | none | save ptLe; break + | i - n | none | break; + +-------+-------+-------- + | none | i | save ptGe; continue + | i | i | save one of ptLe, ptGe; continue + | i - n | i | save ptGe; continue + +-------+-------+-------- + | none | i + n | save ptGe; jump to position posGe + 1 + | i | i + n | save ptLe; if n == 1: continue; else: save ptGe; jump to position posGe + 1 + | i - n | i + n | save ptLe, ptGe; jump to position posGe + 1 + +-------+-------+-------- + */ + if (posGe < i) + { + if (posLe == i) + addPoint(*ptLe); + break; + } + else if (posGe == i) //test if point would be mapped to pixel x-position i { if (posLe == i) // addPoint(x - ptLe->x < ptGe->x - x ? *ptLe : *ptGe); @@ -360,32 +389,14 @@ void SparseCurveData::getPoints(double minX, double maxX, int pixelWidth, std::v } else { - if (posLe == i) + if (posLe <= i) addPoint(*ptLe); - else //no point for x-position i - { - if (i == posFrom && posGe > i) - { - if (posLe < i) - addPoint(*ptLe); //use first point outside display area! - else if (posGe > posTo) //curve starts outside the draw range! - break; - } - } - if (posGe < i) - break; - - if (posGe > posTo) //last point outside the display area! + if (posLe != i || posGe > i + 1) { - if (i == posTo && posLe == i) //no need for outside point if last position was already set above - break; - addPoint(*ptGe); - break; + i = posGe; //skip sparse area: +1 will be added by for-loop! } - if (posGe > i) //skip sparse area - i = posGe - 1; } } } @@ -397,7 +408,7 @@ Graph2D::Graph2D(wxWindow* parent, const wxSize& size, long style, const wxString& name) : wxPanel(parent, winid, pos, size, style, name), - labelFont(wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, L"Arial") + labelFont(wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, L"Arial") { Connect(wxEVT_PAINT, wxPaintEventHandler(Graph2D::onPaintEvent), nullptr, this); Connect(wxEVT_SIZE, wxSizeEventHandler (Graph2D::onSizeEvent ), nullptr, this); @@ -405,11 +416,8 @@ Graph2D::Graph2D(wxWindow* parent, Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(Graph2D::onEraseBackGround), nullptr, this); //SetDoubleBuffered(true); slow as hell! -#if wxCHECK_VERSION(2, 9, 1) + SetBackgroundStyle(wxBG_STYLE_PAINT); -#else - SetBackgroundStyle(wxBG_STYLE_CUSTOM); -#endif Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(Graph2D::OnMouseLeftDown), nullptr, this); Connect(wxEVT_MOTION, wxMouseEventHandler(Graph2D::OnMouseMovement), nullptr, this); @@ -493,7 +501,7 @@ void Graph2D::render(wxDC& dc) const { using namespace numeric; - //set label font right at the start so that it is considered by wxDC::GetTextExtent below! + //set label font right at the start so that it is considered by wxDC::GetTextExtent() below! dc.SetFont(labelFont); const wxRect clientRect = GetClientRect(); //DON'T use wxDC::GetSize()! DC may be larger than visible area! @@ -590,18 +598,17 @@ void Graph2D::render(wxDC& dc) const double maxY = attr.maxYauto ? -std::numeric_limits<double>::infinity() : attr.maxY; // std::vector<std::vector<CurvePoint>> curvePoints(curves_.size()); - std::vector<std::vector<char>> oobMarker (curves_.size()); //effectively a std::vector<bool> marking points that start a out of bounds line + std::vector<std::vector<char>> oobMarker (curves_.size()); //effectively a std::vector<bool> marking points that start an out-of-bounds line - for (auto it = curves_.begin(); it != curves_.end(); ++it) - if (const CurveData* curve = it->first.get()) + for (size_t index = 0; index < curves_.size(); ++index) + if (const CurveData* curve = curves_[index].first.get()) { - const size_t index = it - curves_.begin(); std::vector<CurvePoint>& points = curvePoints[index]; - auto& marker = oobMarker[index]; + auto& marker = oobMarker [index]; curve->getPoints(minX, maxX, graphArea.width, points); - //cut points outside visible x-range now in order to calculate height of visible points only! + //cut points outside visible x-range now in order to calculate height of visible line fragments only! marker.resize(points.size()); //default value: false cutPointsOutsideX(points, marker, minX, maxX); @@ -637,18 +644,17 @@ void Graph2D::render(wxDC& dc) const { //cut points outside visible y-range before calculating pixels: //1. realToScreenRound() deforms out-of-range values! - //2. pixels that are grossly out of range may become a severe performance problem when drawing on the DC (Windows) + //2. pixels that are grossly out of range can be a severe performance problem when drawing on the DC (Windows) cutPointsOutsideY(curvePoints[index], oobMarker[index], minY, maxY); auto& points = drawPoints[index]; - for (const auto& pt : curvePoints[index]) + for (const CurvePoint& pt : curvePoints[index]) points.push_back(wxPoint(cvrtX.realToScreenRound(pt.x), cvrtY.realToScreenRound(pt.y)) + graphAreaOrigin); } //update active mouse selection - if (activeSel.get() && - graphArea.width > 0 && graphArea.height > 0) + if (activeSel.get() && graphArea.width > 0 && graphArea.height > 0) { auto widen = [](double* low, double* high) { @@ -766,30 +772,29 @@ void Graph2D::render(wxDC& dc) const std::vector<wxPoint>& points = drawPoints[index]; //alas wxDC::DrawLines() is not const-correct!!! auto& marker = oobMarker [index]; assert(points.size() == marker.size()); - warn_static("review") - //draw all parts of the curve except for the out-of-bounds ranges - size_t pointsIndexFirst = 0; - while (pointsIndexFirst < points.size()) + //draw all parts of the curve except for the out-of-bounds fragments + size_t drawIndexFirst = 0; + while (drawIndexFirst < points.size()) { - size_t pointsIndexLast = std::find(marker.begin() + pointsIndexFirst, marker.end(), true) - marker.begin(); - if (pointsIndexLast < points.size()) ++ pointsIndexLast; + size_t drawIndexLast = std::find(marker.begin() + drawIndexFirst, marker.end(), true) - marker.begin(); + if (drawIndexLast < points.size()) ++ drawIndexLast; - const int pointCount = static_cast<int>(pointsIndexLast - pointsIndexFirst); + const int pointCount = static_cast<int>(drawIndexLast - drawIndexFirst); if (pointCount > 0) { if (pointCount >= 2) //on OS X wxWidgets has a nasty assert on this - dc.DrawLines(pointCount, &points[pointsIndexFirst]); - dc.DrawPoint(points[pointsIndexLast - 1]); //wxDC::DrawLines() doesn't draw last pixel + dc.DrawLines(pointCount, &points[drawIndexFirst]); + dc.DrawPoint(points[drawIndexLast - 1]); //wxDC::DrawLines() doesn't draw last pixel } - pointsIndexFirst = std::find(marker.begin() + pointsIndexLast, marker.end(), false) - marker.begin(); + drawIndexFirst = std::find(marker.begin() + drawIndexLast, marker.end(), false) - marker.begin(); } } } //5. draw corner texts - for (auto it = attr.cornerTexts.begin(); it != attr.cornerTexts.end(); ++it) - drawCornerText(dc, graphArea, it->second, it->first); + for (const auto& ct : attr.cornerTexts) + drawCornerText(dc, graphArea, ct.second, ct.first); } } } diff --git a/wx+/graph.h b/wx+/graph.h index fe008a38..a752959b 100644 --- a/wx+/graph.h +++ b/wx+/graph.h @@ -11,7 +11,6 @@ #include <vector> #include <memory> #include <wx/panel.h> -//#include <wx/dcbuffer.h> #include <zen/string_tools.h> #include <zen/optional.h> @@ -98,11 +97,11 @@ private: struct VectorCurveData : public ArrayCurveData { - std::vector<double>& refData() { return data; } + std::vector<double>& refData() { return data; } private: - virtual double getValue(size_t pos) const final { return pos < data.size() ? data[pos] : 0; } - virtual size_t getSize() const final { return data.size(); } - std::vector<double> data; + virtual double getValue(size_t pos) const final { return pos < data.size() ? data[pos] : 0; } + virtual size_t getSize() const final { return data.size(); } + std::vector<double> data; }; //------------------------------------------------------------------------------------------------------------ @@ -347,7 +346,7 @@ private: typedef std::vector<std::pair<std::shared_ptr<CurveData>, CurveAttributes>> CurveList; CurveList curves_; - wxFont labelFont; //perf!!! generating the font is *very* expensive! don't do this repeatedly in Graph2D::render()! + wxFont labelFont; //perf!!! generating the font is *very* expensive! don't do this repeatedly in Graph2D::render()! }; } diff --git a/wx+/grid.cpp b/wx+/grid.cpp index c8d418ee..c9dfbbe9 100644 --- a/wx+/grid.cpp +++ b/wx+/grid.cpp @@ -17,8 +17,6 @@ #include <zen/scope_guard.h> #include <zen/utf.h> #include <zen/format_unit.h> -//#include "image_tools.h" -//#include "rtl.h" #include "dc.h" #ifdef ZEN_LINUX @@ -90,11 +88,11 @@ void GridData::renderCell(Grid& grid, wxDC& dc, const wxRect& rect, size_t row, rectTmp.x += COLUMN_BORDER_LEFT; rectTmp.width -= COLUMN_BORDER_LEFT; - drawCellText(dc, rectTmp, getValue(row, colType), grid.IsEnabled()); + drawCellText(dc, rectTmp, getValue(row, colType), true); } -size_t GridData::getBestSize(wxDC& dc, size_t row, ColumnType colType) +int 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 } @@ -131,9 +129,6 @@ void GridData::drawCellBackground(wxDC& dc, const wxRect& rect, bool enabled, bo namespace { -#ifdef _MSC_VER -#pragma warning(disable:4428) // VC wrongly issues warning C4428: universal-character-name encountered in source -#endif const wchar_t ELLIPSIS = L'\u2026'; //... template <class Function> inline @@ -262,11 +257,7 @@ public: //SetDoubleBuffered(true); slow as hell! -#if wxCHECK_VERSION(2, 9, 1) SetBackgroundStyle(wxBG_STYLE_PAINT); -#else - SetBackgroundStyle(wxBG_STYLE_CUSTOM); -#endif Connect(wxEVT_SET_FOCUS, wxFocusEventHandler(SubWindow::onFocus), nullptr, this); Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(SubWindow::onFocus), nullptr, this); @@ -434,7 +425,7 @@ public: wxClientDC dc(this); wxFont labelFont = GetFont(); - labelFont.SetWeight(wxFONTWEIGHT_BOLD); + //labelFont.SetWeight(wxFONTWEIGHT_BOLD); dc.SetFont(labelFont); //harmonize with RowLabelWin::render()! int bestWidth = 0; @@ -455,8 +446,8 @@ public: return -1; } - ptrdiff_t getRowHeight() const { return std::max<ptrdiff_t>(1, rowHeight); } //guarantees to return size >= 1 ! - void setRowHeight(size_t height) { rowHeight = height; } + int getRowHeight() const { return std::max(1, rowHeight); } //guarantees to return size >= 1 ! + void setRowHeight(int height) { rowHeight = height; } wxRect getRowLabelArea(ptrdiff_t row) const { @@ -470,7 +461,7 @@ public: const int yFrom = refParent().CalcUnscrolledPosition(clientRect.GetTopLeft ()).y; const int yTo = refParent().CalcUnscrolledPosition(clientRect.GetBottomRight()).y; - return std::make_pair(std::max<ptrdiff_t>(yFrom / rowHeight, 0), + return std::make_pair(std::max(yFrom / rowHeight, 0), std::min<ptrdiff_t>((yTo / rowHeight) + 1, refParent().getRowCount())); } @@ -481,13 +472,32 @@ private: virtual void render(wxDC& dc, const wxRect& rect) { - if (IsEnabled()) + + /* + IsEnabled() vs IsThisEnabled() since wxWidgets 2.9.5: + + void wxWindowBase::NotifyWindowOnEnableChange(), called from bool wxWindowBase::Enable(), has this buggy exception of NOT + refreshing child elements when disabling a IsTopLevel() dialog, e.g. when showing a modal dialog. + The unfortunate effect on XP for using IsEnabled() when rendering the grid is that the user can move the modal dialog + and *draw* with it on the background while the grid refreshes as disabled incrementally! + + => Don't use IsEnabled() since it considers the top level window. The brittle wxWidgets implementation is right in their intention, + but wrong when not refreshing child-windows: the control designer decides how his control should be rendered! + + => IsThisEnabled() OTOH is too shallow and does not consider parent windows which are not top level. + + The perfect solution would be a bool ShouldBeDrawnActive() { return "IsEnabled() but ignore effects of showing a modal dialog"; } + + However "IsThisEnabled()" is good enough (same like the old IsEnabled() on wxWidgets 2.8.12) and it avoids this pathetic behavior on XP. + (Similar problem on Win 7: e.g. directly click sync button without comparing first) + */ + if (IsThisEnabled()) clearArea(dc, rect, getColorMainWinBackground()); else clearArea(dc, rect, wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); wxFont labelFont = GetFont(); - labelFont.SetWeight(wxFONTWEIGHT_BOLD); + //labelFont.SetWeight(wxFONTWEIGHT_BOLD); dc.SetFont(labelFont); //harmonize with RowLabelWin::getBestWidth()! auto rowRange = getRowsOnClient(rect); //returns range [begin, end) @@ -533,7 +543,7 @@ private: virtual void onMouseMovement(wxMouseEvent& event) { refParent().redirectRowLabelEvent(event); } virtual void onMouseLeftUp (wxMouseEvent& event) { refParent().redirectRowLabelEvent(event); } - ptrdiff_t rowHeight; + int rowHeight; }; @@ -542,7 +552,7 @@ namespace class ColumnResizing { public: - ColumnResizing(wxWindow& wnd, size_t col, size_t compPos, ptrdiff_t startWidth, int clientPosX) : + ColumnResizing(wxWindow& wnd, size_t col, size_t compPos, int startWidth, int clientPosX) : wnd_(wnd), col_(col), compPos_(compPos), startWidth_(startWidth), clientPosX_(clientPosX) { wnd_.CaptureMouse(); @@ -553,17 +563,17 @@ public: wnd_.ReleaseMouse(); } - size_t getColumn () const { return col_; } - size_t getComponentPos() const { return compPos_; } - ptrdiff_t getStartWidth () const { return startWidth_; } - int getStartPosX () const { return clientPosX_; } + size_t getColumn () const { return col_; } + size_t getComponentPos() const { return compPos_; } + int getStartWidth () const { return startWidth_; } + int getStartPosX () const { return clientPosX_; } private: wxWindow& wnd_; - const size_t col_; - const size_t compPos_; - const ptrdiff_t startWidth_; - const int clientPosX_; + const size_t col_; + const size_t compPos_; + const int startWidth_; + const int clientPosX_; }; @@ -609,7 +619,7 @@ private: virtual void render(wxDC& dc, const wxRect& rect) { - if (IsEnabled()) + if (IsThisEnabled()) clearArea(dc, rect, getColorMainWinBackground()); else clearArea(dc, rect, wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); @@ -676,7 +686,7 @@ private: if (action->wantResize) { if (!event.LeftDClick()) //double-clicks never seem to arrive here; why is this checked at all??? - if (Opt<ptrdiff_t> colWidth = refParent().getColWidth(action->col, action->compPos)) + if (Opt<int> colWidth = refParent().getColWidth(action->col, action->compPos)) activeResizing.reset(new ColumnResizing(*this, action->col, action->compPos, *colWidth, event.GetPosition().x)); } else //a move or single click @@ -732,7 +742,7 @@ private: if (action->wantResize) { //auto-size visible range on double-click - const ptrdiff_t bestWidth = refParent().getBestColumnSize(action->col, action->compPos); //return -1 on error + const int bestWidth = refParent().getBestColumnSize(action->col, action->compPos); //return -1 on error if (bestWidth >= 0) { refParent().setColWidthAndNotify(bestWidth, action->col, action->compPos); @@ -748,8 +758,7 @@ private: { const auto col = activeResizing->getColumn(); const auto compPos = activeResizing->getComponentPos(); - - const ptrdiff_t newWidth = activeResizing->getStartWidth() + event.GetPosition().x - activeResizing->getStartPosX(); + const int newWidth = activeResizing->getStartWidth() + event.GetPosition().x - activeResizing->getStartPosX(); //set width tentatively refParent().setColWidthAndNotify(newWidth, col, compPos); @@ -904,7 +913,7 @@ public: private: virtual void render(wxDC& dc, const wxRect& rect) { - if (IsEnabled()) + if (IsThisEnabled()) clearArea(dc, rect, getColorMainWinBackground()); else clearArea(dc, rect, wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); @@ -927,8 +936,9 @@ private: std::vector<std::vector<ColumnWidth>> compAbsWidths = refParent().getColWidths(); //resolve stretched widths for (auto iterComp = compAbsWidths.begin(); iterComp != compAbsWidths.end(); ++iterComp) { - const ptrdiff_t compWidth = std::accumulate(iterComp->begin(), iterComp->end(), static_cast<ptrdiff_t>(0), - [](ptrdiff_t sum, const ColumnWidth& cw) { return sum + cw.width_; }); + int compWidth = 0; + for (const ColumnWidth& cw : *iterComp) + compWidth += cw.width_; const size_t compPos = iterComp - compAbsWidths.begin(); if (auto prov = refParent().getDataProvider(compPos)) @@ -941,21 +951,19 @@ private: } //draw single cells, column by column - for (auto iterCol = iterComp->begin(); iterCol != iterComp->end(); ++iterCol) + for (const ColumnWidth& cw : *iterComp) { - const int width = iterCol->width_; //don't use unsigned for calculations! - if (cellAreaTL.x > rect.GetRight()) return; //done - if (cellAreaTL.x + width > rect.x) + if (cellAreaTL.x + cw.width_ > rect.x) for (int row = rowFirst; row < rowLast; ++row) { - const wxRect& cellRect = wxRect(cellAreaTL.x, cellAreaTL.y + row * rowHeight, width, rowHeight); + const wxRect& cellRect = wxRect(cellAreaTL.x, cellAreaTL.y + row * rowHeight, cw.width_, rowHeight); RecursiveDcClipper clip(dc, cellRect); - prov->renderCell(refParent(), dc, cellRect, row, iterCol->type_); + prov->renderCell(refParent(), dc, cellRect, row, cw.type_); } - cellAreaTL.x += width; + cellAreaTL.x += cw.width_; } } else @@ -977,7 +985,7 @@ private: drawSelection = activeSelection->isPositiveSelect(); //overwrite default } - prov.renderRowBackgound(dc, rect, row, grid.IsEnabled(), drawSelection, wxWindow::FindFocus() == &grid.getMainWin()); + prov.renderRowBackgound(dc, rect, row, grid.IsThisEnabled(), drawSelection, wxWindow::FindFocus() == &grid.getMainWin()); } virtual void onMouseLeftDown (wxMouseEvent& event) { onMouseDown(event); } @@ -1158,8 +1166,8 @@ private: 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 + for (Grid::Component& c : refParent().comp) + c.selection.clear(); //clear selection, do NOT fire event refParent().selectRangeAndNotify(selectionAnchor, row, cursor.second); //set new selection + fire event cursor.first = row; //don't call setCursor() since it writes to "selectionAnchor"! @@ -1418,7 +1426,7 @@ Grid::Grid(wxWindow* parent, colLabelHeight(DEFAULT_COL_LABEL_HEIGHT), drawRowLabel(true), comp(1), - colSizeOld(0) + rowCountOld(0) { Connect(wxEVT_PAINT, wxPaintEventHandler(Grid::onPaintEvent ), nullptr, this); Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(Grid::onEraseBackGround), nullptr, this); @@ -1654,17 +1662,18 @@ size_t Grid::getRowCount() const void Grid::Refresh(bool eraseBackground, const wxRect* rect) { const size_t rowCountNew = getRowCount(); - if (colSizeOld != rowCountNew) + if (rowCountOld != rowCountNew) { - colSizeOld = rowCountNew; - std::for_each(comp.begin(), comp.end(), [&](Component& c) { c.selection.init(rowCountNew); }); + rowCountOld = rowCountNew; + for (Component& c : comp) + c.selection.init(rowCountNew); updateWindowSizes(); } wxScrolledWindow::Refresh(eraseBackground, rect); } -void Grid::setRowHeight(size_t height) +void Grid::setRowHeight(int height) { rowLabelWin_->setRowHeight(height); updateWindowSizes(); @@ -1680,12 +1689,9 @@ void Grid::setColumnConfig(const std::vector<Grid::ColumnAttribute>& attr, size_ comp[compPos].oldColAttributes = attr; std::vector<VisibleColumn> visibleCols; - std::for_each(attr.begin(), attr.end(), - [&](const ColumnAttribute& ca) - { + for (const ColumnAttribute& ca : attr) if (ca.visible_) - visibleCols.push_back(Grid::VisibleColumn(ca.type_, ca.offset_, ca.stretch_)); - }); + visibleCols.push_back(VisibleColumn(ca.type_, ca.offset_, ca.stretch_)); //"ownership" of visible columns is now within Grid comp[compPos].visibleCols = visibleCols; @@ -1707,9 +1713,7 @@ std::vector<Grid::ColumnAttribute> Grid::getColumnConfig(size_t compPos) const auto iterVcolsend = comp[compPos].visibleCols.end(); //update visible columns but keep order of non-visible ones! - std::for_each(output.begin(), output.end(), - [&](ColumnAttribute& ca) - { + for (ColumnAttribute& ca : output) if (ca.visible_) { if (iterVcols != iterVcolsend) @@ -1722,7 +1726,6 @@ std::vector<Grid::ColumnAttribute> Grid::getColumnConfig(size_t compPos) const else assert(false); } - }); assert(iterVcols == iterVcolsend); return output; @@ -1810,7 +1813,7 @@ void Grid::SetScrollbar(int orientation, int position, int thumbSize, int range, break; case SB_SHOW_ALWAYS: - if (range <= 1) //scrollbars hidden if range == 0 or 1 + if (range <= 1) //scrollbars would be hidden for range == 0 or 1! wxScrolledWindow::SetScrollbar(orientation, 0, 199999, 200000, refresh); else wxScrolledWindow::SetScrollbar(orientation, position, thumbSize, range, refresh); @@ -1825,10 +1828,6 @@ void Grid::SetScrollbar(int orientation, int position, int thumbSize, int range, //get rid of scrollbars, but preserve scrolling behavior! #ifdef ZEN_WIN -#ifdef __MINGW32__ //MinGW is clueless... -#define WM_MOUSEHWHEEL 0x020E -#endif - WXLRESULT Grid::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) { //we land here if wxWindowMSW::MSWWindowProc() couldn't handle the message @@ -1873,15 +1872,13 @@ wxRect Grid::getColumnLabelArea(ColumnType colType, size_t compPos) const auto iterCol = std::find_if(iterComp->begin(), iterComp->end(), [&](const ColumnWidth& cw) { return cw.type_ == colType; }); if (iterCol != iterComp->end()) { - ptrdiff_t posX = std::accumulate(compAbsWidths.begin(), iterComp, static_cast<ptrdiff_t>(0), - [](ptrdiff_t sum, const std::vector<ColumnWidth>& cols) - { - return sum + std::accumulate(cols.begin(), cols.end(), static_cast<ptrdiff_t>(0), - [](ptrdiff_t val2, const ColumnWidth& cw) { return val2 + cw.width_; }); - }); + ptrdiff_t posX = 0; + for (auto it = compAbsWidths.begin(); it != iterComp; ++it) + for (const ColumnWidth& cw : *it) + posX += cw.width_; - posX += std::accumulate(iterComp->begin(), iterCol, static_cast<ptrdiff_t>(0), - [](ptrdiff_t sum, const ColumnWidth& cw) { return sum + cw.width_; }); + for (auto it = iterComp->begin(); it != iterCol; ++it) + posX += it->width_; return wxRect(wxPoint(posX, 0), wxSize(iterCol->width_, colLabelHeight)); } @@ -1895,19 +1892,16 @@ Opt<Grid::ColAction> Grid::clientPosToColumnAction(const wxPoint& pos) const const int absPosX = CalcUnscrolledPosition(pos).x; if (absPosX >= 0) { - ptrdiff_t accuWidth = 0; + int accuWidth = 0; std::vector<std::vector<ColumnWidth>> compAbsWidths = getColWidths(); //resolve stretched widths - for (auto iterComp = compAbsWidths.begin(); iterComp != compAbsWidths.end(); ++iterComp) + for (size_t compPos = 0; compPos < compAbsWidths.size(); ++compPos) { - const size_t compPos = iterComp - compAbsWidths.begin(); const int resizeTolerance = columnResizeAllowed(compPos) ? COLUMN_RESIZE_TOLERANCE : 0; - for (auto iterCol = iterComp->begin(); iterCol != iterComp->end(); ++iterCol) + for (size_t col = 0; col < compAbsWidths[compPos].size(); ++col) { - const size_t col = iterCol - iterComp->begin(); - - accuWidth += iterCol->width_; + accuWidth += compAbsWidths[compPos][col].width_; if (std::abs(absPosX - accuWidth) < resizeTolerance) { ColAction out = {}; @@ -1956,16 +1950,14 @@ ptrdiff_t Grid::clientPosToMoveTargetColumn(const wxPoint& pos, size_t compPos) auto iterComp = compAbsWidths.begin() + compPos; const int absPosX = CalcUnscrolledPosition(pos).x; - ptrdiff_t accuWidth = std::accumulate(compAbsWidths.begin(), iterComp, static_cast<ptrdiff_t>(0), - [](ptrdiff_t sum, const std::vector<ColumnWidth>& cols) - { - return sum + std::accumulate(cols.begin(), cols.end(), static_cast<ptrdiff_t>(0), - [](ptrdiff_t sum2, const ColumnWidth& cw) { return sum2 + cw.width_; }); - }); + int accuWidth = 0; + for (auto it = compAbsWidths.begin(); it != iterComp; ++it) + for (const ColumnWidth& cw : *it) + accuWidth += cw.width_; for (auto iterCol = iterComp->begin(); iterCol != iterComp->end(); ++iterCol) { - const ptrdiff_t width = iterCol->width_; //beware dreaded unsigned conversions! + const int width = iterCol->width_; //beware dreaded unsigned conversions! accuWidth += width; if (absPosX < accuWidth - width / 2) @@ -1994,16 +1986,13 @@ Opt<std::pair<ColumnType, size_t>> Grid::getColumnAtPos(int posX) const { std::vector<std::vector<ColumnWidth>> compAbsWidths = getColWidths(); //resolve negative/stretched widths - ptrdiff_t accWidth = 0; - for (auto iterComp = compAbsWidths.begin(); iterComp != compAbsWidths.end(); ++iterComp) - for (auto iterCol = iterComp->begin(); iterCol != iterComp->end(); ++iterCol) + int accWidth = 0; + for (size_t compPos = 0; compPos < compAbsWidths.size(); ++compPos) + for (const ColumnWidth& cw : compAbsWidths[compPos]) { - accWidth += iterCol->width_; + accWidth += cw.width_; if (posX < accWidth) - { - const size_t compPos = iterComp - compAbsWidths.begin(); - return std::make_pair(iterCol->type_, compPos); - } + return std::make_pair(cw.type_, compPos); } } return NoValue(); @@ -2025,7 +2014,8 @@ void Grid::setGridCursor(size_t row, size_t compPos) mainWin_->setCursor(row, compPos); mainWin_->makeRowVisible(row); - std::for_each(comp.begin(), comp.end(), [](Grid::Component& c) { c.selection.clear(); }); //clear selection, do NOT fire event + for (Grid::Component& c : comp) + c.selection.clear(); //clear selection, do NOT fire event selectRangeAndNotify(row, row, compPos); //set new selection + fire event mainWin_->Refresh(); @@ -2114,7 +2104,7 @@ std::pair<size_t, size_t> Grid::getGridCursor() const } -ptrdiff_t Grid::getBestColumnSize(size_t col, size_t compPos) const +int Grid::getBestColumnSize(size_t col, size_t compPos) const { if (compPos < comp.size()) { @@ -2127,7 +2117,7 @@ ptrdiff_t Grid::getBestColumnSize(size_t col, size_t compPos) const wxClientDC dc(mainWin_); dc.SetFont(mainWin_->GetFont()); //harmonize with MainWin::render() - size_t maxSize = 0; + int maxSize = 0; auto rowRange = rowLabelWin_->getRowsOnClient(mainWin_->GetClientRect()); //returns range [begin, end) for (auto row = rowRange.first; row < rowRange.second; ++row) @@ -2140,22 +2130,25 @@ ptrdiff_t Grid::getBestColumnSize(size_t col, size_t compPos) const } -void Grid::setColWidthAndNotify(ptrdiff_t width, size_t col, size_t compPos, bool notifyAsync) +void Grid::setColWidthAndNotify(int width, size_t col, size_t compPos, bool notifyAsync) { if (compPos < comp.size() && col < comp[compPos].visibleCols.size()) { VisibleColumn& vcRs = comp[compPos].visibleCols[col]; - const int mainWinWidth = mainWin_->GetClientSize().GetWidth(); - const ptrdiff_t stretchTotal = getStretchTotal(); - const ptrdiff_t stretchedWithCol = getColStretchedWidth(vcRs.stretch_, stretchTotal, mainWinWidth); - - vcRs.offset_ = width - stretchedWithCol; //width := stretchedWidth + offset + const std::vector<std::vector<int>> stretchedWidths = getColStretchedWidths(mainWin_->GetClientSize().GetWidth()); + if (stretchedWidths.size() != comp.size() || stretchedWidths[compPos].size() != comp[compPos].visibleCols.size()) + { + assert(false); + return; + } //CAVEATS: //I. fixed-size columns: normalize offset so that resulting width is at least COLUMN_MIN_WIDTH: this is NOT enforced by getColWidths()! //II. stretched columns: do not allow user to set offsets so small that they result in negative (non-normalized) widths: this gives an //unusual delay when enlarging the column again later - vcRs.offset_ = std::max(vcRs.offset_, COLUMN_MIN_WIDTH - stretchedWithCol); + width = std::max(width, COLUMN_MIN_WIDTH); + + vcRs.offset_ = width - stretchedWidths[compPos][col]; //width := stretchedWidth + offset //III. resizing any column should normalize *all* other stretched columns' offsets considering current mainWinWidth! // test case: @@ -2163,17 +2156,13 @@ void Grid::setColWidthAndNotify(ptrdiff_t width, size_t col, size_t compPos, boo //2. shrink main window width so that horizontal scrollbars are shown despite the streched column //3. shrink a fixed-size column so that the scrollbars vanish and columns cover full width again //4. now verify that the stretched column is resizing immediately if main window is enlarged again - std::for_each(comp.begin(), comp.end(), [&](Component& c) + for (size_t compPos2 = 0; compPos2 < comp.size(); ++compPos2) { - std::for_each(c.visibleCols.begin(), c.visibleCols.end(), [&](VisibleColumn& vc) - { - if (vc.stretch_ > 0) //normalize stretched columns only - { - const ptrdiff_t stretchedWidth = Grid::getColStretchedWidth(vc.stretch_, stretchTotal, mainWinWidth); - vc.offset_ = std::max(vc.offset_, COLUMN_MIN_WIDTH - stretchedWidth); - } - }); - }); + auto& visibleCols = comp[compPos2].visibleCols; + for (size_t col2 = 0; col2 < visibleCols.size(); ++col2) + if (visibleCols[col2].stretch_ > 0) //normalize stretched columns only + visibleCols[col2].offset_ = std::max(visibleCols[col2].offset_, COLUMN_MIN_WIDTH - stretchedWidths[compPos2][col2]); + } GridColumnResizeEvent sizeEvent(vcRs.offset_, vcRs.type_, compPos); if (wxEvtHandler* evtHandler = GetEventHandler()) @@ -2194,10 +2183,9 @@ void Grid::autoSizeColumns(size_t compPos) if (compPos < comp.size() && comp[compPos].allowColumnResize) { auto& visibleCols = comp[compPos].visibleCols; - for (auto it = visibleCols.begin(); it != visibleCols.end(); ++it) + for (size_t col = 0; col < visibleCols.size(); ++col) { - const size_t col = it - visibleCols.begin(); - const ptrdiff_t bestWidth = getBestColumnSize(col, compPos); //return -1 on error + const int bestWidth = getBestColumnSize(col, compPos); //return -1 on error if (bestWidth >= 0) setColWidthAndNotify(bestWidth, col, compPos, true); } @@ -2207,20 +2195,55 @@ void Grid::autoSizeColumns(size_t compPos) } -ptrdiff_t Grid::getStretchTotal() const //sum of all stretch factors +std::vector<std::vector<int>> Grid::getColStretchedWidths(int clientWidth) const //final width = (normalized) (stretchedWidth + offset) { - return std::accumulate(comp.begin(), comp.end(), static_cast<ptrdiff_t>(0), - [](ptrdiff_t sum, const Component& c) + assert(clientWidth >= 0); + clientWidth = std::max(clientWidth, 0); + int stretchTotal = 0; + for (const Component& c : comp) + for (const VisibleColumn& vc : c.visibleCols) + { + assert(vc.stretch_ >= 0); + stretchTotal += vc.stretch_; + } + + int remainingWidth = clientWidth; + + std::vector<std::vector<int>> output; + for (const Component& c : comp) { - return sum + std::accumulate(c.visibleCols.begin(), c.visibleCols.end(), static_cast<ptrdiff_t>(0), - [](ptrdiff_t val2, const Grid::VisibleColumn& vc) { return val2 + vc.stretch_; }); - }); -} + output.push_back(std::vector<int>()); + auto& compWidths = output.back(); + if (stretchTotal <= 0) + compWidths.resize(c.visibleCols.size()); //fill with zeros + else + for (const VisibleColumn& vc : c.visibleCols) + { + const int width = clientWidth * vc.stretch_ / stretchTotal; //rounds down! + compWidths.push_back(width); + remainingWidth -= width; + } + } -ptrdiff_t Grid::getColStretchedWidth(ptrdiff_t stretch, ptrdiff_t stretchTotal, int mainWinWidth) //final width := stretchedWidth + (normalized) offset -{ - return stretchTotal > 0 ? mainWinWidth * stretch / stretchTotal : 0; //rounds down! => not all of clientWidth is correctly distributed according to stretch factors + //distribute *all* of clientWidth: should suffice to enlarge the first few stretched columns; no need to minimize total absolute error of distribution + if (stretchTotal > 0) + if (remainingWidth > 0) + { + for (size_t compPos2 = 0; compPos2 < comp.size(); ++compPos2) + { + auto& visibleCols = comp[compPos2].visibleCols; + for (size_t col2 = 0; col2 < visibleCols.size(); ++col2) + if (visibleCols[col2].stretch_ > 0) + { + ++output[compPos2][col2]; + if (--remainingWidth == 0) + return output; + } + } + assert(false); + } + return output; } @@ -2232,39 +2255,41 @@ std::vector<std::vector<Grid::ColumnWidth>> Grid::getColWidths() const std::vector<std::vector<Grid::ColumnWidth>> Grid::getColWidths(int mainWinWidth) const //evaluate stretched columns; structure matches "comp" { - std::vector<std::vector<ColumnWidth>> output; + const std::vector<std::vector<int>> stretchedWidths = getColStretchedWidths(mainWinWidth); + assert(stretchedWidths.size() == comp.size()); - const ptrdiff_t stretchTotal = getStretchTotal(); + std::vector<std::vector<ColumnWidth>> output; - std::for_each(comp.begin(), comp.end(), [&](const Component& c) + for (size_t compPos2 = 0; compPos2 < comp.size(); ++compPos2) { + assert(stretchedWidths[compPos2].size() == comp[compPos2].visibleCols.size()); + output.push_back(std::vector<ColumnWidth>()); auto& compWidths = output.back(); - std::for_each(c.visibleCols.begin(), c.visibleCols.end(), [&](const VisibleColumn& vc) + auto& visibleCols = comp[compPos2].visibleCols; + for (size_t col2 = 0; col2 < visibleCols.size(); ++col2) { - ptrdiff_t widthNormalized = Grid::getColStretchedWidth(vc.stretch_, stretchTotal, mainWinWidth) + vc.offset_; + const auto& vc = visibleCols[col2]; + int width = stretchedWidths[compPos2][col2] + vc.offset_; if (vc.stretch_ > 0) - widthNormalized = std::max(widthNormalized, static_cast<ptrdiff_t>(COLUMN_MIN_WIDTH)); //normalization really needed here: e.g. smaller main window would result in negative width + width = std::max(width, COLUMN_MIN_WIDTH); //normalization really needed here: e.g. smaller main window would result in negative width else - widthNormalized = std::max(widthNormalized, static_cast<ptrdiff_t>(0)); //support smaller width than COLUMN_MIN_WIDTH if set via configuration + width = std::max(width, 0); //support smaller width than COLUMN_MIN_WIDTH if set via configuration - compWidths.push_back(Grid::ColumnWidth(vc.type_, widthNormalized)); - }); - }); + compWidths.push_back(ColumnWidth(vc.type_, width)); + } + } return output; } -ptrdiff_t Grid::getColWidthsSum(int mainWinWidth) const +int Grid::getColWidthsSum(int mainWinWidth) const { - auto widths = getColWidths(mainWinWidth); - return std::accumulate(widths.begin(), widths.end(), static_cast<ptrdiff_t>(0), - [](ptrdiff_t sum, const std::vector<Grid::ColumnWidth>& cols) - { - return sum + std::accumulate(cols.begin(), cols.end(), static_cast<ptrdiff_t>(0), - [](ptrdiff_t val2, const Grid::ColumnWidth& cw) { return val2 + cw.width_; }); - }); + int sum = 0; + for (const std::vector<ColumnWidth>& cols : getColWidths(mainWinWidth)) + for (const ColumnWidth& cw : cols) + sum += cw.width_; + return sum; }; - @@ -47,11 +47,11 @@ struct GridClickEvent : public wxMouseEvent struct GridColumnResizeEvent : public wxCommandEvent { - GridColumnResizeEvent(ptrdiff_t offset, ColumnType colType, size_t compPos) : wxCommandEvent(EVENT_GRID_COL_RESIZE), colType_(colType), offset_(offset), compPos_(compPos) {} + GridColumnResizeEvent(int offset, ColumnType colType, size_t compPos) : wxCommandEvent(EVENT_GRID_COL_RESIZE), colType_(colType), offset_(offset), compPos_(compPos) {} virtual wxEvent* Clone() const { return new GridColumnResizeEvent(*this); } const ColumnType colType_; - const ptrdiff_t offset_; + const int offset_; const size_t compPos_; }; @@ -96,7 +96,7 @@ public: 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 int 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 @@ -127,7 +127,7 @@ public: size_t getRowCount() const; - void setRowHeight(size_t height); + void setRowHeight(int 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(); } @@ -135,13 +135,13 @@ public: struct ColumnAttribute { - ColumnAttribute(ColumnType type, ptrdiff_t offset, ptrdiff_t stretch, bool visible = true) : type_(type), visible_(visible), stretch_(std::max<ptrdiff_t>(stretch, 0)), offset_(offset) {} + ColumnAttribute(ColumnType type, int offset, int stretch, bool visible = true) : type_(type), visible_(visible), stretch_(std::max(stretch, 0)), offset_(offset) { assert(stretch >=0 ); } ColumnType type_; bool visible_; - //first client width is partitioned according to all available stretch factors, then "offset_" is added + //first, client width is partitioned according to all available stretch factors, then "offset_" is added //universal model: a non-stretched column has stretch factor 0 with the "offset" becoming identical to final width! - ptrdiff_t stretch_; //>= 0 - ptrdiff_t offset_; + int stretch_; //>= 0 + int offset_; }; void setColumnConfig(const std::vector<ColumnAttribute>& attr, size_t compPos = 0); //set column count + widths @@ -212,7 +212,7 @@ private: virtual WXLRESULT MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); //support horizontal mouse wheel #endif - ptrdiff_t getBestColumnSize(size_t col, size_t compPos) const; //return -1 on error + int getBestColumnSize(size_t col, size_t compPos) const; //return -1 on error friend class GridData; class SubWindow; @@ -229,9 +229,9 @@ private: std::vector<size_t> get() const { std::vector<size_t> selection; - for (auto iter = rowSelectionValue.begin(); iter != rowSelectionValue.end(); ++iter) - if (*iter != 0) - selection.push_back(iter - rowSelectionValue.begin()); + for (size_t row = 0; row < rowSelectionValue.size(); ++row) + if (rowSelectionValue[row] != 0) + selection.push_back(row); return selection; } @@ -257,10 +257,10 @@ private: struct VisibleColumn { - VisibleColumn(ColumnType type, ptrdiff_t offset, ptrdiff_t stretch) : type_(type), stretch_(stretch), offset_(offset) {} + VisibleColumn(ColumnType type, int offset, int stretch) : type_(type), stretch_(stretch), offset_(offset) {} ColumnType type_; - ptrdiff_t stretch_; //>= 0 - ptrdiff_t offset_; + int stretch_; //>= 0 + int offset_; }; struct Component @@ -278,15 +278,16 @@ private: struct ColumnWidth { - ColumnWidth(ColumnType type, ptrdiff_t width) : type_(type), width_(width) {} + ColumnWidth(ColumnType type, int width) : type_(type), width_(width) {} ColumnType type_; - ptrdiff_t width_; + int width_; }; std::vector<std::vector<ColumnWidth>> getColWidths() const; // std::vector<std::vector<ColumnWidth>> getColWidths(int mainWinWidth) const; //evaluate stretched columns; structure matches "comp" - ptrdiff_t getColWidthsSum(int mainWinWidth) const; + int getColWidthsSum(int mainWinWidth) const; + std::vector<std::vector<int>> getColStretchedWidths(int clientWidth) const; //final width = (normalized) (stretchedWidth + offset) - Opt<ptrdiff_t> getColWidth(size_t col, size_t compPos) const + Opt<int> getColWidth(size_t col, size_t compPos) const { const auto& widths = getColWidths(); if (compPos < widths.size() && col < widths[compPos].size()) @@ -294,10 +295,7 @@ private: return NoValue(); } - ptrdiff_t getStretchTotal() const; //sum of all stretch factors - static ptrdiff_t getColStretchedWidth(ptrdiff_t stretch, ptrdiff_t stretchTotal, int mainWinWidth); //final width = stretchedWidth + (normalized) offset - - void setColWidthAndNotify(ptrdiff_t width, size_t col, size_t compPos, bool notifyAsync = false); + void setColWidthAndNotify(int width, size_t col, size_t compPos, bool notifyAsync = false); wxRect getColumnLabelArea(ColumnType colType, size_t compPos) const; //returns empty rect if column not found @@ -342,7 +340,7 @@ private: bool drawRowLabel; std::vector<Component> comp; - size_t colSizeOld; //at the time of last Grid::Refresh() + size_t rowCountOld; //at the time of last Grid::Refresh() }; } diff --git a/wx+/image_tools.cpp b/wx+/image_tools.cpp new file mode 100644 index 00000000..97fe3660 --- /dev/null +++ b/wx+/image_tools.cpp @@ -0,0 +1,185 @@ +// ************************************************************************** +// * 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 (zenju AT gmx DOT de) - All Rights Reserved * +// ************************************************************************** + +#include "image_tools.h" +#include <zen/string_tools.h> +#include <wx/app.h> + + +using namespace zen; + +namespace +{ +void writeToImage(const wxImage& source, wxImage& target, const wxPoint& pos) +{ + const int srcWidth = source.GetWidth (); + const int srcHeight = source.GetHeight(); + const int trgWidth = target.GetWidth (); + + if (srcWidth > 0 && srcHeight > 0) + { + assert(0 <= pos.x && pos.x + srcWidth <= trgWidth ); //draw area must be a + assert(0 <= pos.y && pos.y + srcHeight <= target.GetHeight()); //subset of target image! + assert(target.HasAlpha()); + + { + const unsigned char* sourcePtr = source.GetData(); + unsigned char* targetPtr = target.GetData() + 3 * (pos.x + pos.y * trgWidth); + + for (int row = 0; row < srcHeight; ++row) + ::memcpy(targetPtr + 3 * row * trgWidth, sourcePtr + 3 * row * srcWidth, 3 * srcWidth); + } + + //handle alpha channel + { + unsigned char* targetPtr = target.GetAlpha() + pos.x + pos.y * trgWidth; + if (source.HasAlpha()) + { + const unsigned char* sourcePtr = source.GetAlpha(); + for (int row = 0; row < srcHeight; ++row) + ::memcpy(targetPtr + row * trgWidth, sourcePtr + row * srcWidth, srcWidth); + } + else + for (int row = 0; row < srcHeight; ++row) + ::memset(targetPtr + row * trgWidth, wxIMAGE_ALPHA_OPAQUE, srcWidth); + } + } +} +} + + +wxImage zen::stackImages(const wxImage& img1, const wxImage& img2, ImageStackLayout dir, ImageStackAlignment align, int gap) +{ + assert(gap >= 0); + gap = std::max(0, gap); + + const int img1Width = img1.GetWidth (); + const int img1Height = img1.GetHeight(); + const int img2Width = img2.GetWidth (); + const int img2Height = img2.GetHeight(); + + int width = std::max(img1Width, img2Width); + int height = std::max(img1Height, img2Height); + switch (dir) + { + case ImageStackLayout::HORIZONTAL: + width = img1Width + gap + img2Width; + break; + + case ImageStackLayout::VERTICAL: + height = img1Height + gap + img2Height; + break; + } + wxImage output(width, height); + output.SetAlpha(); + ::memset(output.GetAlpha(), wxIMAGE_ALPHA_TRANSPARENT, width * height); + ::memset(output.GetData (), 0, 3 * width * height); //redundant due to transparent alpha + + auto calcPos = [&](int imageExtent, int totalExtent) + { + switch (align) + { + case ImageStackAlignment::CENTER: + return (totalExtent - imageExtent) / 2; + case ImageStackAlignment::LEFT: + return 0; + case ImageStackAlignment::RIGHT: + return totalExtent - imageExtent; + } + assert(false); + return 0; + }; + + switch (dir) + { + case ImageStackLayout::HORIZONTAL: + writeToImage(img1, output, wxPoint(0, calcPos(img1Height, height))); + writeToImage(img2, output, wxPoint(img1Width + gap, calcPos(img2Height, height))); + break; + + case ImageStackLayout::VERTICAL: + writeToImage(img1, output, wxPoint(calcPos(img1Width, width), 0)); + writeToImage(img2, output, wxPoint(calcPos(img2Width, width), img1Height + gap)); + break; + } + return output; +} + + +namespace +{ +void makeWhiteTransparent(wxImage& image) //assume black text on white background +{ + assert(image.HasAlpha()); + if (unsigned char* alphaPtr = image.GetAlpha()) + { + const int pixelCount = image.GetWidth() * image.GetHeight(); + const unsigned char* dataPtr = image.GetData(); + for (int i = 0; i < pixelCount; ++ i) + { + const unsigned char r = *dataPtr++; + const unsigned char g = *dataPtr++; + const unsigned char b = *dataPtr++; + + //black(0,0,0) becomes fully opaque(255), while white(255,255,255) becomes transparent(0) + alphaPtr[i] = static_cast<unsigned char>((255 - r + 255 - g + 255 - b) / 3); //mixed mode arithmetics! + } + } +} + + +wxSize getTextExtent(const wxString& text, const wxFont& font) +{ + wxMemoryDC dc; //the context used for bitmaps + dc.SetFont(font); //the font parameter of GetMultiLineTextExtent() is not evalated on OS X, wxWidgets 2.9.5, so apply it to the DC directly! + return dc.GetMultiLineTextExtent(replaceCpy(text, L"&", L"", false)); //remove accelerator +} +} + +wxImage zen::createImageFromText(const wxString& text, const wxFont& font, const wxColor& col) +{ + //wxDC::DrawLabel() doesn't respect alpha channel => calculate alpha values manually: + + if (text.empty()) + return wxImage(); + + wxBitmap newBitmap(getTextExtent(text, font)); + { + wxMemoryDC dc(newBitmap); + dc.SetBackground(*wxWHITE_BRUSH); + dc.Clear(); + + dc.SetTextForeground(*wxBLACK); //for use in makeWhiteTransparent + dc.SetTextBackground(*wxWHITE); // + dc.SetFont(font); + + wxString textFmt = replaceCpy(text, L"&", L"", false); + //for some reason wxDC::DrawText messes up "weak" bidi characters even when wxLayout_RightToLeft is set! (--> arrows in hebrew/arabic) + //=> use mark characters instead: + const wchar_t rtlMark = L'\u200F'; + if (wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft) + textFmt = rtlMark + textFmt + rtlMark; + + dc.DrawText(textFmt, wxPoint()); + } + + wxImage output(newBitmap.ConvertToImage()); + output.SetAlpha(); + + //calculate alpha channel + makeWhiteTransparent(output); + + //apply actual text color + unsigned char* dataPtr = output.GetData(); + const int pixelCount = output.GetWidth() * output.GetHeight(); + for (int i = 0; i < pixelCount; ++ i) + { + *dataPtr++ = col.Red(); + *dataPtr++ = col.Green(); + *dataPtr++ = col.Blue(); + } + return output; +} diff --git a/wx+/image_tools.h b/wx+/image_tools.h index ec9e34d4..d3a20a45 100644 --- a/wx+/image_tools.h +++ b/wx+/image_tools.h @@ -15,19 +15,39 @@ namespace zen { -wxBitmap greyScale(const wxBitmap& bmp); //greyscale + brightness adaption +enum class ImageStackLayout +{ + HORIZONTAL, + VERTICAL +}; + +enum class ImageStackAlignment +{ + CENTER, + LEFT, + RIGHT, + TOP = LEFT, + BOTTOM = RIGHT, +}; +wxImage stackImages(const wxImage& img1, const wxImage& img2, ImageStackLayout dir, ImageStackAlignment align, int gap = 0); + +wxImage createImageFromText(const wxString& text, const wxFont& font, const wxColor& col); + + +wxImage greyScale(const wxImage& img); //greyscale + brightness adaption +wxBitmap greyScale(const wxBitmap& bmp); // wxBitmap layOver(const wxBitmap& foreground, const wxBitmap& background); //merge -void move(wxImage& img, int up, int left = 0); +//void moveImage(wxImage& img, int right, int up); void adjustBrightness(wxImage& img, int targetLevel); double getAvgBrightness(const wxImage& img); //in [0, 255] void brighten(wxImage& img, int level); //level: delta per channel in points bool isEqual(const wxBitmap& lhs, const wxBitmap& rhs); //pixel-wise equality (respecting alpha channel) -wxColor gradient(const wxColor& from, const wxColor& to, double fraction); //maps fraction within [0, 1] to an intermediate color +//wxColor gradient(const wxColor& from, const wxColor& to, double fraction); //maps fraction within [0, 1] to an intermediate color -wxColour hsvColor(double h, double s, double v); //h within [0, 360), s, v within [0, 1] +//wxColour hsvColor(double h, double s, double v); //h within [0, 360), s, v within [0, 1] @@ -43,20 +63,20 @@ wxColour hsvColor(double h, double s, double v); //h within [0, 360), s, v withi //################################### implementation ################################### +/* inline -void move(wxImage& img, int up, int left) +void moveImage(wxImage& img, int right, int up) { - img = img.GetSubImage(wxRect(std::max(0, left), std::max(0, up), img.GetWidth() - abs(left), img.GetHeight() - abs(up))); - img.Resize(wxSize(img.GetWidth() + abs(left), img.GetHeight() + abs(up)), wxPoint(-std::min(0, left), -std::min(0, up))); + img = img.GetSubImage(wxRect(std::max(0, -right), std::max(0, up), img.GetWidth() - abs(right), img.GetHeight() - abs(up))); + img.Resize(wxSize(img.GetWidth() + abs(right), img.GetHeight() + abs(up)), wxPoint(std::max(0, right), std::max(0, -up))); } +*/ inline -wxBitmap greyScale(const wxBitmap& bmp) +wxImage greyScale(const wxImage& img) { - assert(!bmp.GetMask()); //wxWidgets screws up for the gazillionth time applying a mask instead of alpha channel if the .png image has only 0 and 0xff opacity values!!! - - wxImage output = bmp.ConvertToImage().ConvertToGreyscale(1.0 / 3, 1.0 / 3, 1.0 / 3); //treat all channels equally! + wxImage output = img.ConvertToGreyscale(1.0 / 3, 1.0 / 3, 1.0 / 3); //treat all channels equally! //wxImage output = bmp.ConvertToImage().ConvertToGreyscale(); adjustBrightness(output, 160); return output; @@ -64,6 +84,14 @@ wxBitmap greyScale(const wxBitmap& bmp) inline +wxBitmap greyScale(const wxBitmap& bmp) +{ + assert(!bmp.GetMask()); //wxWidgets screws up for the gazillionth time applying a mask instead of alpha channel if the .png image has only 0 and 0xff opacity values!!! + return greyScale(bmp.ConvertToImage()); +} + + +inline double getAvgBrightness(const wxImage& img) { const int pixelCount = img.GetWidth() * img.GetHeight(); @@ -160,6 +188,7 @@ bool isEqual(const wxBitmap& lhs, const wxBitmap& rhs) return std::equal(imLhs.GetData(), imLhs.GetData() + pixelCount * 3, imRhs.GetData()); } +/* inline wxColor gradient(const wxColor& from, const wxColor& to, double fraction) { @@ -170,8 +199,9 @@ wxColor gradient(const wxColor& from, const wxColor& to, double fraction) from.Blue () + (to.Blue () - from.Blue ()) * fraction, from.Alpha() + (to.Alpha() - from.Alpha()) * fraction); } +*/ - +/* inline wxColour hsvColor(double h, double s, double v) //h within [0, 360), s, v within [0, 1] { @@ -218,6 +248,7 @@ wxColour hsvColor(double h, double s, double v) //h within [0, 360), s, v within assert(false); return *wxBLACK; } +*/ } #endif //IMAGE_TOOLS_HEADER_45782456427634254 diff --git a/wx+/no_flicker.h b/wx+/no_flicker.h index fd64628f..c5b0d238 100644 --- a/wx+/no_flicker.h +++ b/wx+/no_flicker.h @@ -15,7 +15,7 @@ namespace zen inline void setText(wxTextCtrl& control, const wxString& newText, bool* additionalLayoutChange = nullptr) { - const wxString& label = control.GetValue(); //perf: don't call twice! + const wxString& label = control.GetValue(); //perf: don't call twice! if (additionalLayoutChange && !*additionalLayoutChange) //never revert from true to false! *additionalLayoutChange = label.length() != newText.length(); //avoid screen flicker: update layout only when necessary @@ -27,11 +27,11 @@ inline void setText(wxStaticText& control, wxString newText, bool* additionalLayoutChange = nullptr) { #ifdef ZEN_WIN - //wxStaticText handles ampersands incorrectly: https://sourceforge.net/p/freefilesync/bugs/279/ - replace(newText, L'&', L"&&"); -#endif + //wxStaticText handles ampersands incorrectly: https://sourceforge.net/p/freefilesync/bugs/279/ + replace(newText, L'&', L"&&"); +#endif - const wxString& label = control.GetLabel(); //perf: don't call twice! + const wxString& label = control.GetLabel(); //perf: don't call twice! if (additionalLayoutChange && !*additionalLayoutChange) *additionalLayoutChange = label.length() != newText.length(); //avoid screen flicker: update layout only when necessary diff --git a/zen/FindFilePlus/FindFilePlus.vcxproj b/zen/FindFilePlus/FindFilePlus.vcxproj index 73b7f70e..15ea6adf 100644 --- a/zen/FindFilePlus/FindFilePlus.vcxproj +++ b/zen/FindFilePlus/FindFilePlus.vcxproj @@ -28,23 +28,23 @@ <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> @@ -90,7 +90,7 @@ <ClCompile> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>_X86_;_DEBUG;_WINDOWS;_USRDLL;FIND_FILE_PLUS_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> + <MinimalRebuild>false</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <PrecompiledHeader> @@ -101,6 +101,7 @@ <DisableSpecificWarnings>4100</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> <SmallerTypeCheck>true</SmallerTypeCheck> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> @@ -125,7 +126,7 @@ <ClCompile> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>_AMD64_;_DEBUG;_WINDOWS;_USRDLL;FIND_FILE_PLUS_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> + <MinimalRebuild>false</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <PrecompiledHeader> @@ -136,6 +137,7 @@ <DisableSpecificWarnings>4100</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> <SmallerTypeCheck>true</SmallerTypeCheck> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> @@ -168,6 +170,7 @@ <DisableSpecificWarnings>4100</DisableSpecificWarnings> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> @@ -205,6 +208,7 @@ <DisableSpecificWarnings>4100</DisableSpecificWarnings> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> diff --git a/zen/IFileOperation/FileOperation_Vista.vcxproj b/zen/IFileOperation/FileOperation_Vista.vcxproj index e5165514..20f09a00 100644 --- a/zen/IFileOperation/FileOperation_Vista.vcxproj +++ b/zen/IFileOperation/FileOperation_Vista.vcxproj @@ -29,23 +29,23 @@ <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> @@ -87,7 +87,7 @@ <ClCompile> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>WXINTL_NO_GETTEXT_MACRO;ZEN_WIN;_DEBUG;_WINDOWS;_USRDLL;FILE_OP_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> + <MinimalRebuild>false</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <PrecompiledHeader> @@ -99,6 +99,7 @@ <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> <SmallerTypeCheck>true</SmallerTypeCheck> <ForcedIncludeFiles>zen/warn_static.h</ForcedIncludeFiles> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> @@ -124,7 +125,7 @@ <ClCompile> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>WXINTL_NO_GETTEXT_MACRO;ZEN_WIN;_DEBUG;_WINDOWS;_USRDLL;FILE_OP_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> + <MinimalRebuild>false</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <PrecompiledHeader> @@ -136,6 +137,7 @@ <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> <SmallerTypeCheck>true</SmallerTypeCheck> <ForcedIncludeFiles>zen/warn_static.h</ForcedIncludeFiles> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> @@ -170,11 +172,12 @@ <DisableSpecificWarnings>4100;4996;4512</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> <ForcedIncludeFiles>zen/warn_static.h</ForcedIncludeFiles> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> + <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> @@ -209,11 +212,12 @@ <DisableSpecificWarnings>4100;4996;4512</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> <ForcedIncludeFiles>zen/warn_static.h</ForcedIncludeFiles> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> + <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> diff --git a/zen/basic_math.h b/zen/basic_math.h index 05d892ee..56cfd923 100644 --- a/zen/basic_math.h +++ b/zen/basic_math.h @@ -228,6 +228,8 @@ bool isNull(T value) inline int round(double d) { + assert(d - 0.5 >= std::numeric_limits<int>::min() && //if double is larger than what int can represent: + d + 0.5 <= std::numeric_limits<int>::max()); //=> undefined behavior! return static_cast<int>(d < 0 ? d - 0.5 : d + 0.5); } diff --git a/zen/file_handling.cpp b/zen/file_handling.cpp index 103a39f7..3f8d5bbd 100644 --- a/zen/file_handling.cpp +++ b/zen/file_handling.cpp @@ -45,74 +45,44 @@ using namespace zen; -warn_static("remove after test") -namespace -{ -void writeSysErrorIfNeeded(std::wstring* sysErrorMsg, const wchar_t* functionName, ErrorCode lastError) -{ - if (sysErrorMsg) - { - //skip uninteresting error codes: -#ifdef ZEN_WIN - if (lastError == ERROR_FILE_NOT_FOUND || - lastError == ERROR_PATH_NOT_FOUND) return; - //lastError == ERROR_BAD_NETPATH || //e.g. for a path like: \\192.168.1.1\test - //lastError == ERROR_NETNAME_DELETED; - -#elif defined ZEN_LINUX || defined ZEN_MAC - if (lastError == ENOENT) return; -#endif - *sysErrorMsg = formatSystemError(functionName, lastError); - } -} -} - - -bool zen::fileExists(const Zstring& filename, std::wstring* sysErrorMsg) +bool zen::fileExists(const Zstring& filename) { //symbolic links (broken or not) are also treated as existing files! #ifdef ZEN_WIN - const wchar_t functionName[] = L"GetFileAttributes"; const DWORD attr = ::GetFileAttributes(applyLongPathPrefix(filename).c_str()); if (attr != INVALID_FILE_ATTRIBUTES) return (attr & FILE_ATTRIBUTE_DIRECTORY) == 0; //returns true for (file-)symlinks also #elif defined ZEN_LINUX || defined ZEN_MAC - const wchar_t functionName[] = L"lstat"; struct ::stat fileInfo = {}; - if (::lstat(filename.c_str(), &fileInfo) == 0) - return S_ISREG(fileInfo.st_mode) || S_ISLNK(fileInfo.st_mode); //in Linux a symbolic link is neither file nor directory + if (::stat(filename.c_str(), &fileInfo) == 0) //follow symlinks! + return S_ISREG(fileInfo.st_mode); #endif - writeSysErrorIfNeeded(sysErrorMsg, functionName, getLastError()); return false; } -bool zen::dirExists(const Zstring& dirname, std::wstring* sysErrorMsg) +bool zen::dirExists(const Zstring& dirname) { //symbolic links (broken or not) are also treated as existing directories! #ifdef ZEN_WIN - const wchar_t functionName[] = L"GetFileAttributes"; const DWORD attr = ::GetFileAttributes(applyLongPathPrefix(dirname).c_str()); if (attr != INVALID_FILE_ATTRIBUTES) return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0; //returns true for (dir-)symlinks also #elif defined ZEN_LINUX || defined ZEN_MAC - const wchar_t functionName[] = L"lstat"; struct ::stat dirInfo = {}; - if (::lstat(dirname.c_str(), &dirInfo) == 0) - return S_ISDIR(dirInfo.st_mode) || S_ISLNK(dirInfo.st_mode); //in Linux a symbolic link is neither file nor directory + if (::stat(dirname.c_str(), &dirInfo) == 0) //follow symlinks! + return S_ISDIR(dirInfo.st_mode); #endif - writeSysErrorIfNeeded(sysErrorMsg, functionName, getLastError()); return false; } -bool zen::symlinkExists(const Zstring& linkname, std::wstring* sysErrorMsg) +bool zen::symlinkExists(const Zstring& linkname) { #ifdef ZEN_WIN - const wchar_t functionName[] = L"FindFirstFile"; WIN32_FIND_DATA linkInfo = {}; const HANDLE searchHandle = ::FindFirstFile(applyLongPathPrefix(linkname).c_str(), &linkInfo); if (searchHandle != INVALID_HANDLE_VALUE) @@ -122,20 +92,17 @@ bool zen::symlinkExists(const Zstring& linkname, std::wstring* sysErrorMsg) } #elif defined ZEN_LINUX || defined ZEN_MAC - const wchar_t functionName[] = L"lstat"; struct ::stat linkInfo = {}; if (::lstat(linkname.c_str(), &linkInfo) == 0) return S_ISLNK(linkInfo.st_mode); #endif - writeSysErrorIfNeeded(sysErrorMsg, functionName, getLastError()); return false; } -bool zen::somethingExists(const Zstring& objname, std::wstring* sysErrorMsg) +bool zen::somethingExists(const Zstring& objname) { #ifdef ZEN_WIN - const wchar_t functionName[] = L"GetFileAttributes"; const DWORD attr = ::GetFileAttributes(applyLongPathPrefix(objname).c_str()); if (attr != INVALID_FILE_ATTRIBUTES) return true; @@ -143,35 +110,14 @@ bool zen::somethingExists(const Zstring& objname, std::wstring* sysErrorMsg) return true; #elif defined ZEN_LINUX || defined ZEN_MAC - const wchar_t functionName[] = L"lstat"; struct ::stat fileInfo = {}; if (::lstat(objname.c_str(), &fileInfo) == 0) return true; #endif - writeSysErrorIfNeeded(sysErrorMsg, functionName, getLastError()); return false; } -SymLinkType zen::getSymlinkType(const Zstring& linkname) //throw() -{ - assert(symlinkExists(linkname)); -#ifdef ZEN_WIN - const DWORD attr = ::GetFileAttributes(applyLongPathPrefix(linkname).c_str()); - if (attr == INVALID_FILE_ATTRIBUTES) - return SYMLINK_TYPE_UNKNOWN; - return (attr & FILE_ATTRIBUTE_DIRECTORY) ? SYMLINK_TYPE_DIR : SYMLINK_TYPE_FILE; - -#elif defined ZEN_LINUX || defined ZEN_MAC - //S_ISDIR and S_ISLNK are mutually exclusive on Linux => explicitly need to follow link - struct ::stat fileInfo = {}; - if (::stat(linkname.c_str(), &fileInfo) != 0) - return SYMLINK_TYPE_UNKNOWN; - return S_ISDIR(fileInfo.st_mode) ? SYMLINK_TYPE_DIR : SYMLINK_TYPE_FILE; -#endif -} - - namespace { #ifdef ZEN_WIN @@ -531,7 +477,7 @@ public: { renameFile_sub(unrelatedFileParked, unrelatedFile); //throw FileError, ErrorDifferentVolume } - catch (...) {} + catch (FileError&) {} } private: Zstring unrelatedFile; @@ -580,17 +526,10 @@ public: } virtual HandleLink onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) { - switch (getSymlinkType(fullName)) - { - case SYMLINK_TYPE_DIR: - dirs_.push_back(shortName); - break; - - case SYMLINK_TYPE_FILE: - case SYMLINK_TYPE_UNKNOWN: - files_.push_back(shortName); - break; - } + if (dirExists(fullName)) //dir symlink + dirs_.push_back(shortName); + else //file symlink, broken symlink + files_.push_back(shortName); return LINK_SKIP; } virtual TraverseCallback* onDir(const Zchar* shortName, const Zstring& fullName) @@ -918,7 +857,7 @@ void zen::setFileTime(const Zstring& filename, const Int64& modTime, ProcSymlink } } #ifndef NDEBUG //dst hack: verify data written - if (dst::isFatDrive(filename) && !dirExists(filename)) //throw() + if (dst::isFatDrive(filename) && fileExists(filename)) //throw() { FILETIME creationTimeDbg = {}; FILETIME lastWriteTimeDbg = {}; @@ -1282,13 +1221,13 @@ void zen::makeDirectory(const Zstring& directory, bool failIfExists) //throw Fil } catch (const FileError&) { - if (dirExists(directory)) //a file system race-condition! + /* + could there be situations where a directory/network path exists, + but creation fails with error different than "ErrorTargetExisting"?? + - creation of C:\ fails with ERROR_ACCESS_DENIED rather than ERROR_ALREADY_EXISTS + */ + if (somethingExists(directory)) //a file system race-condition! don't use dirExists() => harmonize with ErrorTargetExisting! { - /* - could there be situations where a directory/network path exists, - but creation fails with error different than "ErrorTargetExisting"?? - - creation of C:\ fails with ERROR_ACCESS_DENIED rather than ERROR_ALREADY_EXISTS - */ assert(false); if (failIfExists) throw; //do NOT convert to ErrorTargetExisting: if "failIfExists", not getting a ErrorTargetExisting *atomically* is unexpected! @@ -1313,7 +1252,7 @@ void zen::makeDirectoryPlain(const Zstring& directory, //throw FileError, ErrorT { dirTmp += FILE_NAME_SEPARATOR; //we do not support "C:" to represent a relative path! - const ErrorCode lastError = dirExists(dirTmp) ? ERROR_ALREADY_EXISTS : ERROR_PATH_NOT_FOUND; + const ErrorCode lastError = somethingExists(dirTmp) ? ERROR_ALREADY_EXISTS : ERROR_PATH_NOT_FOUND; //don't use dirExists() => harmonize with ErrorTargetExisting! const std::wstring errorMsg = replaceCpy(_("Cannot create directory %x."), L"%x", fmtFileName(dirTmp)); const std::wstring errorDescr = formatSystemError(L"CreateDirectory", lastError); @@ -1429,7 +1368,7 @@ void zen::makeDirectoryPlain(const Zstring& directory, //throw FileError, ErrorT } #endif - zen::ScopeGuard guardNewDir = zen::makeGuard([&] { try { removeDirectory(directory); } catch (...) {} }); //ensure cleanup: + zen::ScopeGuard guardNewDir = zen::makeGuard([&] { try { removeDirectory(directory); } catch (FileError&) {} }); //ensure cleanup: //enforce copying file permissions: it's advertized on GUI... if (copyFilePermissions) @@ -1475,12 +1414,12 @@ void zen::copySymlink(const Zstring& sourceLink, const Zstring& targetLink, bool { #ifdef ZEN_WIN if (isDirLink) - removeDirectory(targetLink); + removeDirectory(targetLink); //throw FileError else #endif - removeFile(targetLink); + removeFile(targetLink); //throw FileError } - catch (...) {} + catch (FileError&) {} }); //file times: essential for sync'ing a symlink: enforce this! (don't just try!) @@ -1676,7 +1615,7 @@ void copyFileWindowsSparse(const Zstring& sourceFile, throw FileError(errorMsg, errorDescr); } - ScopeGuard guardTarget = makeGuard([&] { try { removeFile(targetFile); } catch (...) {} }); //transactional behavior: guard just after opening target and before managing hFileOut + ScopeGuard guardTarget = makeGuard([&] { try { removeFile(targetFile); } catch (FileError&) {} }); //transactional behavior: guard just after opening target and before managing hFileOut ZEN_ON_SCOPE_EXIT(::CloseHandle(hFileTarget)); //---------------------------------------------------------------------- @@ -2018,7 +1957,7 @@ void copyFileWindowsDefault(const Zstring& sourceFile, try { activatePrivilege(SE_RESTORE_NAME); } catch (const FileError&) {} - zen::ScopeGuard guardTarget = zen::makeGuard([&] { try { removeFile(targetFile); } catch (...) {} }); + zen::ScopeGuard guardTarget = zen::makeGuard([&] { try { removeFile(targetFile); } catch (FileError&) {} }); //transactional behavior: guard just before starting copy, we don't trust ::CopyFileEx(), do we? ;) DWORD copyFlags = COPY_FILE_FAIL_IF_EXISTS; @@ -2091,7 +2030,7 @@ void copyFileWindowsDefault(const Zstring& sourceFile, //note: ERROR_INVALID_PARAMETER can also occur when copying to a SharePoint server or MS SkyDrive and the target filename is of a restricted type. } - catch (...) {} + catch (FileError&) {} throw FileError(errorMsg, errorDescr); } @@ -2165,7 +2104,7 @@ void copyFileLinuxMac(const Zstring& sourceFile, if (::fstat(fileIn.getDescriptor(), &sourceInfo) != 0) //read file attributes from source throw FileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(sourceFile)), formatSystemError(L"fstat", getLastError())); - zen::ScopeGuard guardTarget = zen::makeGuard([&] { try { removeFile(targetFile); } catch (...) {} }); //transactional behavior: place guard before lifetime of FileOutput + zen::ScopeGuard guardTarget = zen::makeGuard([&] { try { removeFile(targetFile); } catch (FileError&) {} }); //transactional behavior: place guard before lifetime of FileOutput try { //create targetFile and open it for writing @@ -2269,7 +2208,6 @@ void zen::copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPath if (transactionalCopy) { Zstring temporary = targetFile + zen::TEMP_FILE_ENDING; //use temporary file until a correct date has been set - zen::ScopeGuard guardTempFile = zen::makeGuard([&] { try { removeFile(temporary); } catch (...) {} }); //transactional behavior: ensure cleanup (e.g. network drop) -> ref to temporary[!] //raw file copy try @@ -2286,9 +2224,12 @@ void zen::copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPath copyFileSelectOs(sourceFile, temporary, callback, sourceAttr); //throw FileError } + //transactional behavior: ensure cleanup; not needed before copyFileSelectOs() which is already transactional + zen::ScopeGuard guardTempFile = zen::makeGuard([&] { try { removeFile(temporary); } catch (FileError&) {} }); + //have target file deleted (after read access on source and target has been confirmed) => allow for almost transactional overwrite if (callback) - callback->deleteTargetFile(targetFile); + callback->deleteTargetFile(targetFile); //throw X //rename temporary file: //perf: this call is REALLY expensive on unbuffered volumes! ~40% performance decrease on FAT USB stick! @@ -2319,7 +2260,6 @@ void zen::copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPath } else { - //have target file deleted if (callback) callback->deleteTargetFile(targetFile); copyFileSelectOs(sourceFile, targetFile, callback, sourceAttr); //throw FileError: ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked @@ -2335,7 +2275,7 @@ void zen::copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPath //file permissions if (copyFilePermissions) { - zen::ScopeGuard guardTargetFile = zen::makeGuard([&] { try { removeFile(targetFile); } catch (...) {}}); + zen::ScopeGuard guardTargetFile = zen::makeGuard([&] { try { removeFile(targetFile); } catch (FileError&) {}}); copyObjectPermissions(sourceFile, targetFile, SYMLINK_FOLLOW); //throw FileError diff --git a/zen/file_handling.h b/zen/file_handling.h index 3cb8a68c..c437e7bc 100644 --- a/zen/file_handling.h +++ b/zen/file_handling.h @@ -18,19 +18,10 @@ struct CallbackRemoveDir; struct CallbackCopyFile; -bool fileExists (const Zstring& filename, std::wstring* sysErrorMsg = nullptr); //noexcept; check whether file *or* (file) symlink exists -bool dirExists (const Zstring& dirname , std::wstring* sysErrorMsg = nullptr); //noexcept; check whether directory *or* (dir) symlink exists -bool symlinkExists (const Zstring& linkname, std::wstring* sysErrorMsg = nullptr); //noexcept; check whether a symbolic link exists -bool somethingExists(const Zstring& objname , std::wstring* sysErrorMsg = nullptr); //noexcept; check whether any object with this name exists -//sysErrorMsg: optional in + optional out! written only for non-expected errors other than ERROR_FILE_NOT_FOUND/ENOENT, ect... - -enum SymLinkType -{ - SYMLINK_TYPE_DIR, //Windows: may be broken - SYMLINK_TYPE_FILE, //Windows: may be broken - SYMLINK_TYPE_UNKNOWN, //Windows: unable to determine type; Linux: broken Symlink -}; -SymLinkType getSymlinkType(const Zstring& linkname); //noexcept +bool fileExists (const Zstring& filename); //noexcept; check whether file or file-symlink exists +bool dirExists (const Zstring& dirname ); //noexcept; check whether directory or dir-symlink exists +bool symlinkExists (const Zstring& linkname); //noexcept; check whether a symbolic link exists +bool somethingExists(const Zstring& objname ); //noexcept; check whether any object with this name exists enum ProcSymlink { diff --git a/zen/notify_removal.cpp b/zen/notify_removal.cpp index 3815887a..4b00cadf 100644 --- a/zen/notify_removal.cpp +++ b/zen/notify_removal.cpp @@ -186,12 +186,7 @@ private: { PDEV_BROADCAST_HANDLE body = reinterpret_cast<PDEV_BROADCAST_HANDLE>(lParam); -#ifdef __MINGW32__ - const HDEVNOTIFY requestNotification = reinterpret_cast<HDEVNOTIFY>(body->dbch_hdevnotify); -#else - const HDEVNOTIFY requestNotification = body->dbch_hdevnotify; -#endif - if (requestNotification == hNotification) //is it for the notification we registered? + if (body->dbch_hdevnotify == hNotification) //is it for the notification we registered? switch (wParam) { case DBT_DEVICEQUERYREMOVE: diff --git a/zen/optional.h b/zen/optional.h index 6e54408a..15d27f4b 100644 --- a/zen/optional.h +++ b/zen/optional.h @@ -7,6 +7,8 @@ #ifndef OPTIONAL_H_2857428578342203589 #define OPTIONAL_H_2857428578342203589 +#include <cassert> + namespace zen { /* @@ -45,26 +47,19 @@ public: if (tmp.valid) value = tmp.value; valid = tmp.valid; - return *this; + return *this; } ////rvalue optimization: only basic exception safety: // Opt(Opt&& tmp) : value(std::move(tmp.value)), valid(tmp.valid) {} -#ifdef _MSC_VER -private: - struct ConversionToBool { int dummy; }; -public: - operator int ConversionToBool::* () const { return valid ? &ConversionToBool::dummy : nullptr; } -#else explicit operator bool() const { return valid; } //thank you C++11!!! -#endif - const T& operator*() const { return value; } - /**/ T& operator*() { return value; } + const T& operator*() const { assert(valid); return value; } + /**/ T& operator*() { assert(valid); return value; } - const T* operator->() const { return &value; } - /**/ T* operator->() { return &value; } + const T* operator->() const { assert(valid); return &value; } + /**/ T* operator->() { assert(valid); return &value; } void reset() { valid = false; } diff --git a/zen/privilege.cpp b/zen/privilege.cpp index 44318517..d4f956a8 100644 --- a/zen/privilege.cpp +++ b/zen/privilege.cpp @@ -104,13 +104,15 @@ private: ~Privileges() //clean up: deactivate all privileges that have been activated by this application { - for (auto it = activePrivileges.begin(); it != activePrivileges.end(); ++it) - if (it->second) + for (const auto& priv : activePrivileges) + if (priv.second) + { try { - setPrivilege(it->first.c_str(), false); //throw FileError + setPrivilege(priv.first.c_str(), false); //throw FileError } - catch (...) {} + catch (FileError&) {} + } } std::map<Zstring, bool> activePrivileges; //bool: enabled by this application diff --git a/zen/recycler.cpp b/zen/recycler.cpp index f1b8381a..20e1a4af 100644 --- a/zen/recycler.cpp +++ b/zen/recycler.cpp @@ -91,7 +91,7 @@ void zen::recycleOrDelete(const std::vector<Zstring>& filenames, CallbackRecycli const DllFun<FunType_getLastError> getLastError (getDllName(), funName_getLastError); if (!moveToRecycler || !getLastError) - throw FileError(replaceCpy(_("Unable to move %x to the Recycle Bin."), L"%x", fmtFileName(filenames[0])), + throw FileError(replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(filenames[0])), replaceCpy(_("Cannot load file %x."), L"%x", fmtFileName(getDllName()))); std::vector<const wchar_t*> cNames; @@ -108,7 +108,7 @@ void zen::recycleOrDelete(const std::vector<Zstring>& filenames, CallbackRecycli if (filenames.size() > 1) filenameFmt += L", ..."; //give at least some hint that there are multiple files, and the error need not be related to the first one - throw FileError(replaceCpy(_("Unable to move %x to the Recycle Bin."), L"%x", filenameFmt), getLastError()); //already includes details about locking errors! + throw FileError(replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", filenameFmt), getLastError()); //already includes details about locking errors! } } else //regular recycle bin usage: available since XP @@ -133,7 +133,7 @@ void zen::recycleOrDelete(const std::vector<Zstring>& filenames, CallbackRecycli //"You should use fully-qualified path names with this function. Using it with relative path names is not thread safe." if (::SHFileOperation(&fileOp) != 0 || fileOp.fAnyOperationsAborted) { - throw FileError(replaceCpy(_("Unable to move %x to the Recycle Bin."), L"%x", fmtFileName(filenames[0]))); //probably not the correct file name for file list larger than 1! + throw FileError(replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(filenames[0]))); //probably not the correct file name for file list larger than 1! } } } @@ -159,7 +159,7 @@ bool zen::recycleOrDelete(const Zstring& filename) //throw FileError if (!::g_file_trash(file, nullptr, &error)) { - const std::wstring errorMsg = replaceCpy(_("Unable to move %x to the Recycle Bin."), L"%x", fmtFileName(filename)); + const std::wstring errorMsg = replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(filename)); if (!error) throw FileError(errorMsg, L"Unknown error."); //user should never see this @@ -190,7 +190,7 @@ bool zen::recycleOrDelete(const Zstring& filename) //throw FileError auto throwFileError = [&](OSStatus oss) { - const std::wstring errorMsg = replaceCpy(_("Unable to move %x to the Recycle Bin."), L"%x", fmtFileName(filename)); + const std::wstring errorMsg = replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(filename)); std::wstring errorDescr = L"OSStatus Code " + numberTo<std::wstring>(oss); if (const char* description = ::GetMacOSStatusCommentString(oss)) //found no documentation for proper use of GetMacOSStatusCommentString diff --git a/zen/scroll_window_under_cursor.cpp b/zen/scroll_window_under_cursor.cpp index f201bb04..ccc00bcf 100644 --- a/zen/scroll_window_under_cursor.cpp +++ b/zen/scroll_window_under_cursor.cpp @@ -13,15 +13,11 @@ #include <cassert> #include "win.h" //includes "windows.h" -#include "Windowsx.h" //WM_MOUSEWHEEL +#include <Windowsx.h> //WM_MOUSEWHEEL namespace { -#ifndef WM_MOUSEHWHEEL //MinGW is clueless... -#define WM_MOUSEHWHEEL 0x020E -#endif - LRESULT CALLBACK mouseInputHook(int nCode, WPARAM wParam, LPARAM lParam) { //"if nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function diff --git a/zen/serialize.h b/zen/serialize.h index 64c07213..14d0cdf7 100644 --- a/zen/serialize.h +++ b/zen/serialize.h @@ -95,7 +95,7 @@ struct BinStreamIn //throw UnexpectedEndOfStreamError } private: - const BinaryStream buffer; + BinaryStream buffer; size_t pos; }; diff --git a/zen/string_tools.h b/zen/string_tools.h index 4639e1dd..180056cb 100644 --- a/zen/string_tools.h +++ b/zen/string_tools.h @@ -389,7 +389,7 @@ 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 ;) { #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()!!! + 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 diff --git a/zen/symlink_target.h b/zen/symlink_target.h index bfd9e038..e3e2ac4d 100644 --- a/zen/symlink_target.h +++ b/zen/symlink_target.h @@ -12,7 +12,7 @@ #ifdef ZEN_WIN #include "win.h" //includes "windows.h" -#include "WinIoCtl.h" +//#include <WinIoCtl.h> #include "privilege.h" #include "long_path_prefix.h" #include "dll.h" @@ -43,7 +43,8 @@ Zstring getSymlinkTargetRaw(const Zstring& linkPath); //throw FileError //################################ implementation ################################ -#ifdef _MSC_VER //I don't have Windows Driver Kit at hands right now, so unfortunately we need to redefine this structures and cross fingers... +#ifdef ZEN_WIN +//I don't have Windows Driver Kit at hands right now, so unfortunately we need to redefine this structure and cross fingers... typedef struct _REPARSE_DATA_BUFFER //from ntifs.h { ULONG ReparseTag; @@ -77,7 +78,6 @@ typedef struct _REPARSE_DATA_BUFFER //from ntifs.h #define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer) #endif - namespace { //retrieve raw target data of symlink or junction diff --git a/zen/thread.h b/zen/thread.h index 76596513..1fa2c951 100644 --- a/zen/thread.h +++ b/zen/thread.h @@ -17,6 +17,9 @@ #pragma GCC diagnostic ignored "-Wstrict-aliasing" #pragma GCC diagnostic ignored "-Wredundant-decls" #pragma GCC diagnostic ignored "-Wshadow" +#ifndef __clang__ //clang defines __GNUC__, but doesn't support this warning +#pragma GCC diagnostic ignored "-Wunused-local-typedefs" +#endif #endif #ifdef _MSC_VER #pragma warning(push) diff --git a/zen/warn_static.h b/zen/warn_static.h index 737a56fb..b9673ed6 100644 --- a/zen/warn_static.h +++ b/zen/warn_static.h @@ -15,19 +15,19 @@ Usage: */ #ifdef _MSC_VER -#define MAKE_STRING_SUB(NUM) #NUM -#define MAKE_STRING(NUM) MAKE_STRING_SUB(NUM) +#define STATIC_WARNING_MAKE_STRINGIZE_SUB(NUM) #NUM +#define STATIC_WARNING_MAKE_STRINGIZE(NUM) STATIC_WARNING_MAKE_STRINGIZE_SUB(NUM) #define warn_static(TXT) \ - __pragma(message (__FILE__ "(" MAKE_STRING(__LINE__) "): Warning: " ## TXT)) + __pragma(message (__FILE__ "(" STATIC_WARNING_MAKE_STRINGIZE(__LINE__) "): Warning: " ## TXT)) #elif defined __GNUC__ -#define ZEN_CONCAT_SUB(X, Y) X ## Y -#define ZEN_CONCAT(X, Y) ZEN_CONCAT_SUB(X, Y) +#define STATIC_WARNING_CONCAT_SUB(X, Y) X ## Y +#define STATIC_WARNING_CONCAT(X, Y) STATIC_WARNING_CONCAT_SUB(X, Y) #define warn_static(TXT) \ typedef int STATIC_WARNING_87903124 __attribute__ ((deprecated)); \ - enum { ZEN_CONCAT(warn_static_dummy_value, __LINE__) = sizeof(STATIC_WARNING_87903124) }; + enum { STATIC_WARNING_CONCAT(warn_static_dummy_value, __LINE__) = sizeof(STATIC_WARNING_87903124) }; #endif #endif //WARN_STATIC_HEADER_08724567834560832745 diff --git a/zen/zstring.cpp b/zen/zstring.cpp index 1cc037e8..6eb68f7b 100644 --- a/zen/zstring.cpp +++ b/zen/zstring.cpp @@ -127,10 +127,6 @@ time per call | function #ifdef ZEN_WIN namespace { -#ifdef __MINGW32__ //MinGW is clueless... -#define LOCALE_INVARIANT 0x007f -#endif - //warning: LOCALE_INVARIANT is NOT available with Windows 2000, so we have to make yet another distinction... const LCID ZSTRING_INVARIANT_LOCALE = zen::winXpOrLater() ? LOCALE_INVARIANT : |