diff options
author | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 17:30:04 +0200 |
---|---|---|
committer | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 17:30:04 +0200 |
commit | 4cfb31bf6abb2d42181e78e8d0758cf74a8a774a (patch) | |
tree | 9dca518008e4811b84b9a670df5b5ebcbc2a9dd5 | |
parent | 5.23 (diff) | |
download | FreeFileSync-4cfb31bf6abb2d42181e78e8d0758cf74a8a774a.tar.gz FreeFileSync-4cfb31bf6abb2d42181e78e8d0758cf74a8a774a.tar.bz2 FreeFileSync-4cfb31bf6abb2d42181e78e8d0758cf74a8a774a.zip |
6.0
119 files changed, 3763 insertions, 2850 deletions
diff --git a/FreeFileSync/Build/Changelog.txt b/FreeFileSync/Build/Changelog.txt index 4e96b14b..7db0e62c 100644 --- a/FreeFileSync/Build/Changelog.txt +++ b/FreeFileSync/Build/Changelog.txt @@ -1,5 +1,22 @@ -FreeFileSync 5.23 ------------------ +FreeFileSync 6.0 [2013-12-01] +----------------------------- +Revised main dialog panel layout +Show arrow icon for shortcut files and symlinks +Execute the "on completion" command asynchronously +Resolved invalid grid background when context menu is shown +Set negative file time tolerance to disable file time check +Optimized sequence of steps when saving database files +Prevent temporary incorrect statistics after unexpected increase in workload +Fixed default height when mixing panels with and without caption on main dialog +New view filter button "show excluded items" +New keyboard shortcuts for file filter and sync settings +Removed libpng15.so dependency for openSUSE 13.1 +Updated help file +Updated translation files + + +FreeFileSync 5.23 [2013-11-01] +------------------------------ Allow sorting root nodes on overview panel Support retry on failure to resolve path by volume name Copy high-precision modification times for files and symlinks @@ -13,7 +30,7 @@ Save RealtimeSync settings before forced exit due to shutdown or log off Resolved contract violation error due to out of memory RealtimeSync does not block system shutdown anymore Added "select all" context menu option for progess log -Handle progress log keyboard input ignoring input focus +Have progress log keyboard input ignore focus Fixed category icon background color issues Report error when reading active config file failed during save Preload adjacent file icons on grid diff --git a/FreeFileSync/Build/Help/html/Expert Settings.html b/FreeFileSync/Build/Help/html/Expert Settings.html index 17c73533..80e83a17 100644 --- a/FreeFileSync/Build/Help/html/Expert Settings.html +++ b/FreeFileSync/Build/Help/html/Expert Settings.html @@ -11,9 +11,12 @@ <P>FreeFileSync has a number of special purpose settings that can only be accessed directly via the global configuration file <FONT FACE="Courier New, monospace">GlobalSettings.xml</FONT>. -To locate this file enter <FONT FACE="Courier New, monospace">%appdata%\FreeFileSync</FONT> in the Windows Explorer address bar or go to the FreeFileSync +Note that this file is read once when FreeFileSync starts and saved when it closes. Therefore do only apply changes while FreeFileSync is not running. <br> + <br> +To locate this file on Windows enter <FONT FACE="Courier New, monospace">%appdata%\FreeFileSync</FONT> in the Windows Explorer address bar or go to the FreeFileSync installation folder if you are using the portable installation. -Note that this file is read once when FreeFileSync starts and saved when it closes. Therefore do only apply changes while FreeFileSync is not running. +On Linux you can find the file in <FONT FACE="Courier New, monospace">~/.FreeFileSync</FONT> for the Launchpad release and in the installation folder for the portable version. +On OS X go to <FONT FACE="Courier New, monospace">~/Library/Application Support/FreeFileSync</FONT>. </P> <div class="greybox"> @@ -41,10 +44,11 @@ are allowed to have a 2 second difference while still being considered equal. This is required by FAT/FAT32 file systems which store file times with a 2 second precision only.<BR>This setting can also be used to simulate a "compare by file size", -ignoring last modification times: If tolerance is set to some high -value, e.g. 2000000000, then changed files will be detected as a +ignoring last modification times: +Set tolerance to -1 which will be considered as an unlimited file time tolerance. +Changed files will then be detected as a conflict (same date, different file size) and the -synchronization direction for conflicts can be set accordingly. +synchronization direction for conflicts can be used accordingly. </P> <P><B>RunWithBackgroundPriority:</B><BR> diff --git a/FreeFileSync/Build/Help/html/FreeFileSync.html b/FreeFileSync/Build/Help/html/FreeFileSync.html index 964cb7e3..106b8d3c 100644 --- a/FreeFileSync/Build/Help/html/FreeFileSync.html +++ b/FreeFileSync/Build/Help/html/FreeFileSync.html @@ -42,6 +42,7 @@ <OL> <LI><FONT SIZE=4>Start comparison</FONT> <LI><FONT SIZE=4>Change comparison settings</FONT> + <LI><FONT SIZE=4>Include/exclude specific files</FONT> <LI><FONT SIZE=4>Change synchronization settings</FONT> <LI><FONT SIZE=4>Start synchronization</FONT> <LI><FONT SIZE=4>Tree overview panel</FONT> @@ -49,7 +50,6 @@ <LI><FONT SIZE=4>Select left and right folders</FONT> <LI><FONT SIZE=4>Synchronization preview </FONT> <LI><FONT SIZE=4>Save/load configuration</FONT> - <LI><FONT SIZE=4>Include/exclude specific files</FONT> <LI><FONT SIZE=4>Select categories to show on grid</FONT> <LI><FONT SIZE=4>Synchronization statistics</FONT> </OL> diff --git a/FreeFileSync/Build/Help/html/Versioning.html b/FreeFileSync/Build/Help/html/Versioning.html index cd1d49db..85958bbe 100644 --- a/FreeFileSync/Build/Help/html/Versioning.html +++ b/FreeFileSync/Build/Help/html/Versioning.html @@ -35,9 +35,9 @@ A file <FONT FACE="Courier New, monospace">Folder\File.txt</FONT> was updated th <div class="greybox"> <div class="greybox_inner"> <FONT FACE="Courier New, monospace"> - C:\Revisions\Folder\File.txt<B>2012-12-12 111111</B>.txt<BR> - C:\Revisions\Folder\File.txt<B>2012-12-12 122222</B>.txt<BR> - C:\Revisions\Folder\File.txt<B>2012-12-12 133333</B>.txt + C:\Revisions\Folder\File.txt <B>2012-12-12 111111</B>.txt<BR> + C:\Revisions\Folder\File.txt <B>2012-12-12 122222</B>.txt<BR> + C:\Revisions\Folder\File.txt <B>2012-12-12 133333</B>.txt </FONT> </div> </div> diff --git a/FreeFileSync/Build/Help/img/MainDialog.png b/FreeFileSync/Build/Help/img/MainDialog.png Binary files differindex 9f2f2566..2ccae3e3 100644 --- a/FreeFileSync/Build/Help/img/MainDialog.png +++ b/FreeFileSync/Build/Help/img/MainDialog.png diff --git a/FreeFileSync/Build/Languages/arabic.lng b/FreeFileSync/Build/Languages/arabic.lng index 4a893332..ebc87c28 100644 --- a/FreeFileSync/Build/Languages/arabic.lng +++ b/FreeFileSync/Build/Languages/arabic.lng @@ -88,18 +88,18 @@ <source>Any number of alternative directories for at most one config file.</source> <target>أي عدد من المسارات البديلة لملف خيارات وحيد على الأكثر.</target> -<source>A folder input field is empty.</source> -<target>حقل إدخال خاص بمجلد فارغ.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>سيتم اعتبار المجلد الموافق كمجلد فارغ</target> - <source>Cannot find the following folders:</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>A folder input field is empty.</source> +<target>حقل إدخال خاص بمجلد فارغ.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>سيتم اعتبار المجلد الموافق كمجلد فارغ</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>للمجلدات التالية مسارات مستقلة عن بعضها. انتبه عند ضبط إعدادات المزامنة:</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>لا يمكن الحصول على معلومات العملية.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>في انتظار تأمين قفل للمسار (%x)...</target> +<source>Waiting while directory is locked:</source> +<target>انتظر بينما يتم إنشاء قفل للمسار:</target> + +<source>Lock owner:</source> +<target>صاحب القفل:</target> <source> <pluralform>1 sec</pluralform> @@ -236,6 +239,9 @@ <pluralform>%x ثانية</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>اكتشاف قفل مهمل...</target> + <source>Creating file %x</source> <target>إنشاء الملف %x</target> @@ -314,7 +320,7 @@ <target>تصفح المسار</target> <source>Cannot access the Volume Shadow Copy Service.</source> -<target>لا يمكن الوصول إلى خدمة النسخ الظلي الوسيط.</target> +<target>لا يمكن الوصول إلى خدمة "نسخ الظل لوحدة التخزين".</target> <source>Please use FreeFileSync 64-bit version to create shadow copies on this system.</source> <target>الرجاء استخدام إصدار الـ 64-bit للبرنامج لإنشاء ملفات الظل الاحتياطية على هذا النظام.</target> @@ -326,7 +332,7 @@ <target>تعذر تحديد اسم الوسط %x</target> <source>Volume name %x is not part of file path %y.</source> -<target>اسم الوسط %x ليس جزءا من مسار الملق %y.</target> +<target>اسم وحدة التخزين %x ليس جزءاُ من اسم الملف %y.</target> <source>Stop requested: Waiting for current operation to finish...</source> <target>طلب إحباط المهمة: في انتظار انتهاء المهمة الحالية...</target> @@ -374,7 +380,7 @@ <target>للبدء قم باستيراد ملف .ffs_batch.</target> <source>Folders to watch:</source> -<target>المجلدات المراقبة</target> +<target>المجلدات للمتابعة:</target> <source>Add folder</source> <target>إضافة مجلد</target> @@ -498,6 +504,12 @@ The command is triggered if: <source>Updating attributes of %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>Cannot find %x.</source> <target>تعذر العثور على %x.</target> @@ -537,12 +549,6 @@ The command is triggered if: <source>Generating database...</source> <target>إنشاء قاعدة بيانات...</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> @@ -584,13 +590,19 @@ The command is triggered if: <pluralform>Automatic retry in %x seconds...</pluralform> </source> <target> +<pluralform>إعادة المحاولة بعد 0 ثانية...</pluralform> +<pluralform>إعادة المحاولة بعد 1 ثانية واحدة...</pluralform> +<pluralform>إعادة المحاولة بعد 2 ثانيتين...</pluralform> +<pluralform>إعادة المحاولة بعد %x ثواني...</pluralform> +<pluralform>إعادة المحاولة بعد %x ثانية...</pluralform> +<pluralform>إعادة المحاولة بعد %x ثانية...</pluralform> </target> <source>&Ignore subsequent errors</source> <target>&تجاهلا الأخطاء المماثلة</target> <source>Retrying operation...</source> -<target></target> +<target>إعادة محاولة العملية...</target> <source>Serious Error</source> <target>خطأ فادح</target> @@ -617,7 +629,7 @@ The command is triggered if: <target>لم نستطع العثور على على رقم إصدار FreeFileSync على الشبكة. هل تريد التحقق يدوياً؟</target> <source>&Check</source> -<target></target> +<target>&تحقق</target> <source>Symlink</source> <target>ارتباط-رمزي</target> @@ -775,12 +787,6 @@ The command is triggered if: <source>Save as batch job</source> <target>حفظ كمهمة دفعية</target> -<source>Hide excluded items</source> -<target>إخفاء العناصر المستبعدة</target> - -<source>Show filtered or temporarily excluded files</source> -<target>إظهار الملفات التي تم فلترتها أو استبعادها بشكل مؤقت</target> - <source>Number of files and folders that will be created</source> <target>عدد الملفات و المجلدات التي سيتم إنشاؤها</target> @@ -812,10 +818,10 @@ The command is triggered if: <target>موافق</target> <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> -<target>تحديد التغيرات و مواكبتها على الجانبين. عمليات الحذف, النقل و المشاكل المكتشفة بواسطة قواعد البيانات</target> +<target>تحديد التغيرات و مواكبتها على الجانبين. عمليات الحذف, النقل و المشاكل المكتشفة باستخدام قواعد البيانات</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>إنشاء نسخة نظيرة للمجلد على اليسار بحيث يطابق المجلد على اليمين بعد المزامنة</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>إنشاء نسخة احتياطية من الجانب الأيمن عن طريق تعديل الطرف الأيسر ليطابق الأيمن.</target> <source>Copy new and updated files to the right folder.</source> <target>نسخ الملفات المحدثة إلى المجلد المناسب</target> @@ -826,8 +832,16 @@ The command is triggered if: <source>Detect moved files</source> <target>اكتشاف الملفات المنقولة</target> -<source>Requires database files. Not supported by all file systems.</source> -<target>يتطلب ملفات قواعد بيانات. غير مدعوم من قبل جميع أنظمة الملفات.</target> +<source> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- بحاجة لإنشاء قواعد بيانات لجميع الملفات +- يبدأ التعرف على التغيرات بعد المزامنة الأولية +- غير مدعوم من قبل جميع أنطمة الملفات (file systems) +</target> <source>Delete files:</source> <target>حذف الملفات:</target> @@ -917,7 +931,7 @@ The command is triggered if: <target>إنشاء ملف دفعي من أجل عمليات المزامنة غير المحضورة. للبدأ, انقر نقراً مزدوجاً على الملف أو المهمة المجدولة في منظم المهام: %x</target> <source>Stop synchronization at first error</source> -<target>إيقاف المزامنة عند أول خطأ</target> +<target>إحباط المزامنة عند أول خطأ</target> <source>Show progress dialog</source> <target>إظهار نافذة حوار تقدم العملية</target> @@ -959,10 +973,10 @@ The command is triggered if: <target>حجم الملف:</target> <source>Minimum:</source> -<target>أصغري</target> +<target>الحد الأدنى:</target> <source>Maximum:</source> -<target>أعظمي</target> +<target>الحد الأقصى:</target> <source>&Clear</source> <target>&إزالة</target> @@ -1063,6 +1077,9 @@ This guarantees a consistent state even in case of a serious error. <source>Find</source> <target>بحث</target> +<source>Select View</source> +<target>اخيار طريقة العرض</target> + <source>Overview</source> <target>نظرة عامة</target> @@ -1072,12 +1089,6 @@ This guarantees a consistent state even in case of a serious error. <source>Main Bar</source> <target>الشريط الرئيسي</target> -<source>Filter Files</source> -<target>فلترة الملفات</target> - -<source>Select View</source> -<target>اخيار طريقة العرض</target> - <source>Open...</source> <target>فتح...</target> @@ -1104,6 +1115,12 @@ This guarantees a consistent state even in case of a serious error. <pluralform>Do you really want to execute the command %y for %x items?</pluralform> </source> <target> +<pluralform>هل تريد حقاً تنفيذ العملية %y من أجل عنصر 0</pluralform> +<pluralform>هل تريد حقاً تنفيذ العملية %y من أجل عنصر وحيد 1</pluralform> +<pluralform>هل تريد حقاً تنفيذ العملية %y من أجل عنصرين اثنين 2</pluralform> +<pluralform>هل تريد حقاً تنفيذ العملية %y من أجل %x عناصر</pluralform> +<pluralform>هل تريد حقاً تنفيذ العملية %y من أجل %x عنصراً</pluralform> +<pluralform>هل تريد حقاً تنفيذ العملية %y من أجل %x عنصر</pluralform> </target> <source>&Execute</source> @@ -1136,13 +1153,13 @@ This guarantees a consistent state even in case of a serious error. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>الظاهر %y من أصل 0 سطر</pluralform> -<pluralform>الظاهر %y من أصل 1 (سطر وحيد)</pluralform> -<pluralform>الظاهر %y من أصل 2 (سطرين)</pluralform> +<pluralform>الظاهر %y من أصل سطر 0</pluralform> +<pluralform>الظاهر %y من أصل سطر وحيد 1</pluralform> +<pluralform>الظاهر %y من أصل سطرين اثنين 2</pluralform> <pluralform>الظاهر %y من أصل %x سطور</pluralform> <pluralform>الظاهر %y من أصل %x سطراً</pluralform> <pluralform>الظاهر %y من أصل %x سطر</pluralform> @@ -1262,6 +1279,9 @@ This guarantees a consistent state even in case of a serious error. <source>Show files that won't be copied</source> <target>إظهار الملفات التي لن يتم نسخها</target> +<source>Show filtered or temporarily excluded files</source> +<target>إظهار الملفات التي تم فلترتها أو استبعادها بشكل مؤقت</target> + <source>Set as default</source> <target>تحديد كوضع افتراضي</target> @@ -1269,16 +1289,16 @@ This guarantees a consistent state even in case of a serious error. <target>جميع المجلدات متزامنة</target> <source>Synchronization Settings</source> -<target>خيارات المزامنة</target> +<target>إعدادات المزامنة</target> <source>Comparison Settings</source> -<target>خيارات المقارنة</target> +<target>إعدادات المقارنة</target> <source>Cannot find %x</source> <target>لا يمكن العثور على %x</target> <source>Comma-separated values</source> -<target>قيم مفصولة بواسطة فواصل</target> +<target>قائمة قيم مفصولة بفواصل</target> <source>File list exported</source> <target>تم تصدير قائمة الملفات</target> @@ -1298,6 +1318,9 @@ This guarantees a consistent state even in case of a serious error. <source>Warning</source> <target>تحذير</target> +<source>Select all</source> +<target>اختيار الجميع</target> + <source>Paused</source> <target>تم الإيقاف مؤقتاً</target> @@ -1308,10 +1331,10 @@ This guarantees a consistent state even in case of a serious error. <target>توقف</target> <source>Completed</source> -<target>تم الإنتهاء</target> +<target>انتهت العملية</target> <source>&Continue</source> -<target>&متابعة</target> +<target>&مواصلة</target> <source>Log</source> <target>السجل</target> @@ -1547,7 +1570,7 @@ This guarantees a consistent state even in case of a serious error. <target>تعذر تغيير أولويات I/O للعملية</target> <source>Unable to move %x to the recycle bin.</source> -<target>تعذر نقل %x إلى سلة المهملات.</target> +<target>تعذر نقل %x إلى سلة المحذوفات.</target> <source>Cannot determine final path for %x.</source> <target>تعذر تحديد المسار النهائي لـ %x.</target> diff --git a/FreeFileSync/Build/Languages/chinese_simple.lng b/FreeFileSync/Build/Languages/chinese_simple.lng index d204ffd0..639a7873 100644 --- a/FreeFileSync/Build/Languages/chinese_simple.lng +++ b/FreeFileSync/Build/Languages/chinese_simple.lng @@ -88,18 +88,18 @@ <source>Any number of alternative directories for at most one config file.</source> <target>任意数量的替代目录中至多有一个配置文件.</target> -<source>A folder input field is empty.</source> -<target>有一个文件夹输入框为空.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>相应的文件夹将被视为空.</target> - <source>Cannot find the following folders:</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>A folder input field is empty.</source> +<target>有一个文件夹输入框为空.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>相应的文件夹将被视为空.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>如下的文件夹有路径依赖性. 请在设置同步规则时特别小心:</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>无法取得进程信息.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>由于目录已锁定而正在等待(%x)...</target> +<source>Waiting while directory is locked:</source> +<target>正在等待因目录被锁定:</target> + +<source>Lock owner:</source> +<target>锁定的所有者:</target> <source> <pluralform>1 sec</pluralform> @@ -231,6 +234,9 @@ <pluralform>%x 秒</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>正在检测被遗弃的锁定...</target> + <source>Creating file %x</source> <target>正在创建文件 %x</target> @@ -483,6 +489,12 @@ The command is triggered if: <source>Updating attributes of %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>Cannot find %x.</source> <target>无法找到 %x.</target> @@ -522,12 +534,6 @@ The command is triggered if: <source>Generating database...</source> <target>正在生成数据库...</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> @@ -569,13 +575,14 @@ The command is triggered if: <pluralform>Automatic retry in %x seconds...</pluralform> </source> <target> +<pluralform>在 %x 秒后自动重试...</pluralform> </target> <source>&Ignore subsequent errors</source> <target>忽略后续的错误(&I)</target> <source>Retrying operation...</source> -<target></target> +<target>正在重试操作...</target> <source>Serious Error</source> <target>严重错误</target> @@ -602,7 +609,7 @@ The command is triggered if: <target>无法在线找到当前FreeFileSync版本号. 你要手动检查吗?</target> <source>&Check</source> -<target></target> +<target>检查(&C)</target> <source>Symlink</source> <target>符号连接</target> @@ -760,12 +767,6 @@ The command is triggered if: <source>Save as batch job</source> <target>另存为批处理作业</target> -<source>Hide excluded items</source> -<target>隐藏排除项目</target> - -<source>Show filtered or temporarily excluded files</source> -<target>显示已被过滤或被临时排除的文件</target> - <source>Number of files and folders that will be created</source> <target>将被创建的文件和文件夹数</target> @@ -799,8 +800,8 @@ The command is triggered if: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>识别和传播两侧的变化. 删除, 移动和冲突会使用一个数据库来自动检测.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>创建左侧文件夹的镜像备份, 在同步之后右侧文件夹完全精确匹配.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>以适配右侧文件夹来匹配从而创建左侧文件夹的镜像备份.</target> <source>Copy new and updated files to the right folder.</source> <target>复制新的和已更新的文件到右侧文件夹.</target> @@ -811,8 +812,16 @@ The command is triggered if: <source>Detect moved files</source> <target>检测被移动的文件</target> -<source>Requires database files. Not supported by all file systems.</source> -<target>需要数据库文件. 不是所有文件系统都支持.</target> +<source> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- 需求和创建数据库文件 +- 在初始同步后检测活动 +- 不是所有文件系统都支持 +</target> <source>Delete files:</source> <target>删除文件:</target> @@ -1045,6 +1054,9 @@ This guarantees a consistent state even in case of a serious error. <source>Find</source> <target>查找</target> +<source>Select View</source> +<target>选择视图</target> + <source>Overview</source> <target>摘要</target> @@ -1054,12 +1066,6 @@ This guarantees a consistent state even in case of a serious error. <source>Main Bar</source> <target>主工具栏</target> -<source>Filter Files</source> -<target>过滤器文件</target> - -<source>Select View</source> -<target>选择视图</target> - <source>Open...</source> <target>打开...</target> @@ -1086,6 +1092,7 @@ This guarantees a consistent state even in case of a serious error. <pluralform>Do you really want to execute the command %y for %x items?</pluralform> </source> <target> +<pluralform>你是否要为 %x 个项目执行 %y 命令?</pluralform> </target> <source>&Execute</source> @@ -1108,11 +1115,11 @@ This guarantees a consistent state even in case of a serious error. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>%x 中的 %y 行在视图中</pluralform> +<pluralform>显示 %x 中的 %y 行</pluralform> </target> <source>Set direction:</source> @@ -1229,6 +1236,9 @@ This guarantees a consistent state even in case of a serious error. <source>Show files that won't be copied</source> <target>显示将不被复制的文件</target> +<source>Show filtered or temporarily excluded files</source> +<target>显示已被过滤或被临时排除的文件</target> + <source>Set as default</source> <target>设置为默认值</target> @@ -1265,6 +1275,9 @@ This guarantees a consistent state even in case of a serious error. <source>Warning</source> <target>警告</target> +<source>Select all</source> +<target>选择全部</target> + <source>Paused</source> <target>已暂停</target> diff --git a/FreeFileSync/Build/Languages/chinese_traditional.lng b/FreeFileSync/Build/Languages/chinese_traditional.lng index b13ffb1a..ea5801d3 100644 --- a/FreeFileSync/Build/Languages/chinese_traditional.lng +++ b/FreeFileSync/Build/Languages/chinese_traditional.lng @@ -88,18 +88,18 @@ <source>Any number of alternative directories for at most one config file.</source> <target>備用目錄的任意數量中最多有一個配置文件。</target> -<source>A folder input field is empty.</source> -<target>資料夾輸入欄位是空的。</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>對應的資料夾將視為空的。</target> - <source>Cannot find the following folders:</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>A folder input field is empty.</source> +<target>資料夾輸入欄位是空的。</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>對應的資料夾將視為空的。</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>下列資料夾有相依路徑。請小心設定同步規則:</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>無法得到進程資訊。</target> -<source>Waiting while directory is locked (%x)...</source> -<target>等待同時目錄被鎖定(%x)...</target> +<source>Waiting while directory is locked:</source> +<target>等待同時目錄被鎖定...</target> + +<source>Lock owner:</source> +<target>鎖定擁有者:</target> <source> <pluralform>1 sec</pluralform> @@ -231,6 +234,9 @@ <pluralform>%x 秒</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>正在檢測被放棄的鎖定...</target> + <source>Creating file %x</source> <target>正在新建檔案 %x</target> @@ -483,6 +489,12 @@ The command is triggered if: <source>Updating attributes of %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>Cannot find %x.</source> <target>找不到 %x。</target> @@ -522,12 +534,6 @@ The command is triggered if: <source>Generating database...</source> <target>正在產生資料庫...</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> @@ -576,7 +582,7 @@ The command is triggered if: <target>忽略後續的錯誤(&I)</target> <source>Retrying operation...</source> -<target></target> +<target>重試操作...</target> <source>Serious Error</source> <target>嚴重錯誤</target> @@ -603,7 +609,7 @@ The command is triggered if: <target>找不到目前線上FreeFileSync版號!是否要手動檢查?</target> <source>&Check</source> -<target></target> +<target>檢查(&C)</target> <source>Symlink</source> <target>符號連結</target> @@ -761,12 +767,6 @@ The command is triggered if: <source>Save as batch job</source> <target>另存為批次處理作業</target> -<source>Hide excluded items</source> -<target>隱藏排除項目</target> - -<source>Show filtered or temporarily excluded files</source> -<target>顯示已篩選或暫時排除的檔案</target> - <source>Number of files and folders that will be created</source> <target>將被新建的檔案和資料夾數量</target> @@ -800,8 +800,8 @@ The command is triggered if: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>識別和傳播兩邊的變更。自動檢測刪除、移動和衝突使用的資料庫。</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>新建左邊資料夾的鏡像備份,同步後完整匹配右邊資料夾。</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>新建一個鏡像備份的左邊資料夾來調整匹配右邊資料夾。</target> <source>Copy new and updated files to the right folder.</source> <target>將新的和已更新的檔案複製到右邊資料夾。</target> @@ -812,8 +812,16 @@ The command is triggered if: <source>Detect moved files</source> <target>檢測被移動的檔案</target> -<source>Requires database files. Not supported by all file systems.</source> -<target>需要資料庫檔案。不支援所有檔案系統。</target> +<source> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- 要求並新建資料庫檔案 +- 初始化同步後檢測活動 +- 不支援所有檔案系統 +</target> <source>Delete files:</source> <target>刪除檔案:</target> @@ -1049,6 +1057,9 @@ This guarantees a consistent state even in case of a serious error. <source>Find</source> <target>尋找</target> +<source>Select View</source> +<target>選擇檢視</target> + <source>Overview</source> <target>摘要</target> @@ -1058,12 +1069,6 @@ This guarantees a consistent state even in case of a serious error. <source>Main Bar</source> <target>主欄位</target> -<source>Filter Files</source> -<target>篩選檔案</target> - -<source>Select View</source> -<target>選擇檢視</target> - <source>Open...</source> <target>開啟...</target> @@ -1113,11 +1118,11 @@ This guarantees a consistent state even in case of a serious error. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>視圖中的第 %x 列中的第 %y 列</pluralform> +<pluralform>顯示第 %x 列中的第 %y 列</pluralform> </target> <source>Set direction:</source> @@ -1234,6 +1239,9 @@ This guarantees a consistent state even in case of a serious error. <source>Show files that won't be copied</source> <target>顯示將不會被複製的檔案</target> +<source>Show filtered or temporarily excluded files</source> +<target>顯示已篩選或暫時排除的檔案</target> + <source>Set as default</source> <target>設為預設值</target> @@ -1270,6 +1278,9 @@ This guarantees a consistent state even in case of a serious error. <source>Warning</source> <target>警告</target> +<source>Select all</source> +<target>全選</target> + <source>Paused</source> <target>已暫停</target> diff --git a/FreeFileSync/Build/Languages/croatian.lng b/FreeFileSync/Build/Languages/croatian.lng index a5458089..b3077965 100644 --- a/FreeFileSync/Build/Languages/croatian.lng +++ b/FreeFileSync/Build/Languages/croatian.lng @@ -7,27 +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> -<pluralform>Do you really want to execute the command %y for one item?</pluralform> -<pluralform>Do you really want to execute the command %y for %x items?</pluralform> -</source> -<target> -</target> - -<source> -<pluralform>Automatic retry in 1 second...</pluralform> -<pluralform>Automatic retry in %x seconds...</pluralform> -</source> -<target> -</target> - -<source>Detecting abandoned lock...</source> -<target></target> - -<source>Lock owner:</source> -<target></target> - -<source>Waiting while directory is locked:</source> +<source>MyButton</source> <target></target> <source>Both sides have changed since last synchronization.</source> @@ -243,6 +223,12 @@ <source>Cannot get process information.</source> <target>Ne mogu dobit informacije o procesu</target> +<source>Waiting while directory is locked:</source> +<target>Čekam dok se mapa zaključa:</target> + +<source>Lock owner:</source> +<target>Vlasnik ključa:</target> + <source> <pluralform>1 sec</pluralform> <pluralform>%x sec</pluralform> @@ -253,6 +239,9 @@ <pluralform>%x sek</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>Pronalazim napušteni ključ...</target> + <source>Creating file %x</source> <target>Izrađujem datoteku %x</target> @@ -534,7 +523,7 @@ Naredba će biti pokrenuta ako se: <target>Slijedeće stavke imaju nedefiniranih sukoba te neće biti sinkronizirane:</target> <source>The following folders are significantly different. Make sure you are matching the correct folders for synchronization.</source> -<target>Navedene mape se značajno razlikuju. Prvojerite dali uspoređujete ispravne mape za sinkronizaciju.</target> +<target>Navedene mape se značajno razlikuju. Prvojerite da li uspoređujete ispravne mape za sinkronizaciju.</target> <source>Not enough free disk space available in:</source> <target>Nedovoljno prostora na disku:</target> @@ -590,6 +579,16 @@ Naredba će biti pokrenuta ako se: <source>Switching to FreeFileSync's main window</source> <target>Prebacujem na glavni prozor FreeFileSync</target> +<source> +<pluralform>Automatic retry in 1 second...</pluralform> +<pluralform>Automatic retry in %x seconds...</pluralform> +</source> +<target> +<pluralform>Automatski pokušaj za %x sekundi...</pluralform> +<pluralform>Automatski pokušaj za %x sekunda...</pluralform> +<pluralform>Automatski pokušaj za %x sekundi...</pluralform> +</target> + <source>&Ignore subsequent errors</source> <target>&Zanemari naknadne pogreške</target> @@ -618,7 +617,7 @@ Naredba će biti pokrenuta ako se: <target>Ne mogu se povezati na sourceforge.net.</target> <source>Cannot find current FreeFileSync version number online. Do you want to check manually?</source> -<target>Ne mogu pronaći trenutnu verziju FreeFileSync-a online. Dali želite ručno potražiti?</target> +<target>Ne mogu pronaći trenutnu verziju FreeFileSync-a online. Da li želite ručno potražiti?</target> <source>&Check</source> <target>&Provjeri</target> @@ -779,12 +778,6 @@ Naredba će biti pokrenuta ako se: <source>Save as batch job</source> <target>Spremi kao Slijedni zadatak</target> -<source>Hide excluded items</source> -<target>Sakrij isključene stavke</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Prikaži filtrirane ili privremeno izdvojene datoteke</target> - <source>Number of files and folders that will be created</source> <target>Broj datoteka i foldera koji će se stvoriti</target> @@ -818,8 +811,8 @@ Naredba će biti pokrenuta ako se: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Pronađi i izvrši izmjene na obje strane. Izbrisano, premješteno te sukobi se otkriju automatski pomoću baze.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>Izradi zrcalnu kopiju lijeve mape koja će se točno podudarati s desnom mapom nakon sinkronizacije.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>Izradi zrcalnu pričuvu lijeve mape prilagođavajući desnu mapu da bude jednaka.</target> <source>Copy new and updated files to the right folder.</source> <target>Kopiraj nove i ažurirane datoteke u desnu mapu.</target> @@ -830,8 +823,16 @@ Naredba će biti pokrenuta ako se: <source>Detect moved files</source> <target>Otkrij premještene datoteke</target> -<source>Requires database files. Not supported by all file systems.</source> -<target>Potrebne datoteke baze. Nije podržano kod svih datotečnih sustava.</target> +<source> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Zahtjeva i stvara baznu datoteku +- Otkrivanje aktivno nakon početne sinkronizacije +- Nije podržano od svih datotečnih sustava +</target> <source>Delete files:</source> <target>Izbriši datoteke:</target> @@ -1067,6 +1068,9 @@ To jamči dosljedno stanje čak i u slučaju ozbiljne pogreške <source>Find</source> <target>Pronađi</target> +<source>Select View</source> +<target>Odaberi pogled</target> + <source>Overview</source> <target>Pregled</target> @@ -1076,12 +1080,6 @@ To jamči dosljedno stanje čak i u slučaju ozbiljne pogreške <source>Main Bar</source> <target>Glavna traka</target> -<source>Filter Files</source> -<target>Filtriraj datoteke</target> - -<source>Select View</source> -<target>Odaberi pogled</target> - <source>Open...</source> <target>Otvori...</target> @@ -1103,6 +1101,16 @@ To jamči dosljedno stanje čak i u slučaju ozbiljne pogreške <source>Confirm</source> <target>Potvrdi</target> +<source> +<pluralform>Do you really want to execute the command %y for one item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target> +<pluralform>Da li doista želite izvršiti naredbu %y za %x stavke?</pluralform> +<pluralform>Da li doista želite izvršiti naredbu %y za %x stavki?</pluralform> +<pluralform>Da li doista želite izvršiti naredbu %y za %x stavki?</pluralform> +</target> + <source>&Execute</source> <target>&Izvrši</target> @@ -1127,13 +1135,13 @@ To jamči dosljedno stanje čak i u slučaju ozbiljne pogreške </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>%y od %x reda u prikazu</pluralform> -<pluralform>%y od %x reda u prikazu</pluralform> -<pluralform>%y od %x reda u prikazu</pluralform> +<pluralform>Prikazano %y od %x reda</pluralform> +<pluralform>Prikazano %y od %x redova</pluralform> +<pluralform>Prikazano %y od %x redova</pluralform> </target> <source>Set direction:</source> @@ -1250,6 +1258,9 @@ To jamči dosljedno stanje čak i u slučaju ozbiljne pogreške <source>Show files that won't be copied</source> <target>Prikaži datoteke koje neće biti kopirane</target> +<source>Show filtered or temporarily excluded files</source> +<target>Prikaži filtrirane ili privremeno izdvojene datoteke</target> + <source>Set as default</source> <target>Postavi kao zadano</target> @@ -1336,9 +1347,9 @@ To jamči dosljedno stanje čak i u slučaju ozbiljne pogreške <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> -<pluralform>Dali stvarno želite premjestiti sljedeće %x stavke u koš?</pluralform> -<pluralform>Dali stvarno želite premjestiti sljedećih %x stavki u koš?</pluralform> +<pluralform>Da li stvarno želite premjestiti sljedeću %x stavku u koš?</pluralform> +<pluralform>Da li stvarno želite premjestiti sljedeće %x stavke u koš?</pluralform> +<pluralform>Da li stvarno želite premjestiti sljedećih %x stavki u koš?</pluralform> </target> <source>Move</source> @@ -1349,9 +1360,9 @@ To jamči dosljedno stanje čak i u slučaju ozbiljne pogreške <pluralform>Do you really want to delete the following %x items?</pluralform> </source> <target> -<pluralform>Dali stvarno želite obrisati sljedeću %x stavku?</pluralform> -<pluralform>Dali stvarno želite obristi sljedeće %x stavke?</pluralform> -<pluralform>Dali stvarno želite obristi sljedećih %x stavki?</pluralform> +<pluralform>Da li stvarno želite obrisati sljedeću %x stavku?</pluralform> +<pluralform>Da li stvarno želite obristi sljedeće %x stavke?</pluralform> +<pluralform>Da li stvarno želite obristi sljedećih %x stavki?</pluralform> </target> <source>Exclude</source> diff --git a/FreeFileSync/Build/Languages/czech.lng b/FreeFileSync/Build/Languages/czech.lng index 8e4db524..d2f5b587 100644 --- a/FreeFileSync/Build/Languages/czech.lng +++ b/FreeFileSync/Build/Languages/czech.lng @@ -88,18 +88,18 @@ <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>A folder input field is empty.</source> -<target>Není zadána vstupní složka.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>Odpovídající složka bude považována za prázdnou.</target> - <source>Cannot find the following folders:</source> <target>Nelze najít následující složky:</target> <source>You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.</source> <target>Tuto chybu můžete přeskočit a považovat neexistující složku za prázdnou. Složka pak bude vytvořena při synchronizaci automaticky.</target> +<source>A folder input field is empty.</source> +<target>Není zadána vstupní složka.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>Odpovídající složka bude považována za prázdnou.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>Následující složky mají navzájem závislé cesty! Buďte opatrní s definicí synchronizačních pravidel:</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>Nelze získat informace procesu.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Čekání na uzamčení adresáře (%x)</target> +<source>Waiting while directory is locked:</source> +<target>Čekání na uzamčení adresáře:</target> + +<source>Lock owner:</source> +<target>Používá:</target> <source> <pluralform>1 sec</pluralform> @@ -233,6 +236,9 @@ <pluralform>%x sekund</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>Prověřování uzamčení...</target> + <source>Creating file %x</source> <target>Vytváření souboru %x</target> @@ -489,6 +495,12 @@ Příkaz je spuštěn když: <source>Updating attributes of %x</source> <target>Aktualizace atributů souboru %x</target> +<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>Cannot find %x.</source> <target>Nelze najít %x.</target> @@ -528,12 +540,6 @@ Příkaz je spuštěn když: <source>Generating database...</source> <target>Vytváření databáze...</target> -<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> @@ -575,13 +581,16 @@ Příkaz je spuštěn když: <pluralform>Automatic retry in %x seconds...</pluralform> </source> <target> +<pluralform>Automaticky opakování za 1 sekundu...</pluralform> +<pluralform>Automaticky opakovat za %x sekundy...</pluralform> +<pluralform>Autoamticky opakovat za %x sekund...</pluralform> </target> <source>&Ignore subsequent errors</source> <target>Pře&skočit další chyby</target> <source>Retrying operation...</source> -<target></target> +<target>Opakovaní operace...</target> <source>Serious Error</source> <target>Závažná chyba</target> @@ -608,7 +617,7 @@ Příkaz je spuštěn když: <target>Současná verze FreeFileSync nebyla nalezena online! Chcete verzi zkontrolovat ručně?</target> <source>&Check</source> -<target></target> +<target>&Kontrola</target> <source>Symlink</source> <target>Symlink</target> @@ -766,12 +775,6 @@ Příkaz je spuštěn když: <source>Save as batch job</source> <target>Uložit jako dávku</target> -<source>Hide excluded items</source> -<target>Skrýt vynechané položky</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Zobrazit filtrované nebo dočasně vynechané soubory</target> - <source>Number of files and folders that will be created</source> <target>Počet souborů a složek k vytvoření</target> @@ -805,7 +808,7 @@ Příkaz je spuštěn když: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Rozpoznat a provést změny na obou stranách. Odstraněné, přesunuté nebo přejmenované soubory a konflikty budou detekovány automaticky pomocí databáze.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> <target>Vytvořit zrcadlovou kopii levé složky tak, aby po synchronizci pravá složka přesně odpovídala levé.</target> <source>Copy new and updated files to the right folder.</source> @@ -817,8 +820,16 @@ Příkaz je spuštěn když: <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> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- vyžaduje a vytváří soubor databáze +- je k dispozici po prvotní synchronizaci +- není dostupné na všech systémech +</target> <source>Delete files:</source> <target>Mazání souborů:</target> @@ -1051,6 +1062,9 @@ This guarantees a consistent state even in case of a serious error. <source>Find</source> <target>Najít</target> +<source>Select View</source> +<target>Zobrazení</target> + <source>Overview</source> <target>Přehled</target> @@ -1060,12 +1074,6 @@ This guarantees a consistent state even in case of a serious error. <source>Main Bar</source> <target>Hlavní lišta</target> -<source>Filter Files</source> -<target>Filtr souborů</target> - -<source>Select View</source> -<target>Zobrazení</target> - <source>Open...</source> <target>Otevřít...</target> @@ -1092,6 +1100,9 @@ This guarantees a consistent state even in case of a serious error. <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>&Execute</source> @@ -1118,13 +1129,13 @@ This guarantees a consistent state even in case of a serious error. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>%y z 1 řádku</pluralform> -<pluralform>%y z %x řádků</pluralform> -<pluralform>%y z %x řádků</pluralform> +<pluralform>Zobrazení %y z 1 řádku</pluralform> +<pluralform>Zobrazení %y z %x řádků</pluralform> +<pluralform>Zobrazení %y z %x řádků</pluralform> </target> <source>Set direction:</source> @@ -1241,6 +1252,9 @@ This guarantees a consistent state even in case of a serious error. <source>Show files that won't be copied</source> <target>Zobrazit soubory, které nebudou kopírovány</target> +<source>Show filtered or temporarily excluded files</source> +<target>Zobrazit filtrované nebo dočasně vynechané soubory</target> + <source>Set as default</source> <target>Nastavit jako výchozí</target> @@ -1277,6 +1291,9 @@ This guarantees a consistent state even in case of a serious error. <source>Warning</source> <target>Varování</target> +<source>Select all</source> +<target>Vybrat vše</target> + <source>Paused</source> <target>Pauza</target> diff --git a/FreeFileSync/Build/Languages/danish.lng b/FreeFileSync/Build/Languages/danish.lng index 092686cd..d7f9d27c 100644 --- a/FreeFileSync/Build/Languages/danish.lng +++ b/FreeFileSync/Build/Languages/danish.lng @@ -88,18 +88,18 @@ <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>A folder input field is empty.</source> -<target>Der er ikke valgt nogen mapper.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>Den tilsvarende mappe betragtes som tom.</target> - <source>Cannot find the following folders:</source> <target>Kan ikke finde følgende mapper:</target> <source>You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.</source> <target>Ignorer denne fejl for at betragte hver mappe som tom. Mapperne bliver så automatisk oprettet ved synkronisering.</target> +<source>A folder input field is empty.</source> +<target>Der er ikke valgt nogen mapper.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>Den tilsvarende mappe betragtes som tom.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>Følgende mapper har afhængige stier. Opsæt synkroniseringsreglerne med omhu:</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>Kan ikke hente procesinformation.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Venter mens mappe låses (%x)...</target> +<source>Waiting while directory is locked:</source> +<target>Venter mens mappe låses:</target> + +<source>Lock owner:</source> +<target>Låsens ejer</target> <source> <pluralform>1 sec</pluralform> @@ -232,6 +235,9 @@ <pluralform>%x sek</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>Finder efterladt lås...</target> + <source>Creating file %x</source> <target>Opretter filen %x</target> @@ -486,6 +492,12 @@ Kommandoen udføres hvis: <source>Updating attributes of %x</source> <target>Opdaterer attributter for %x</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>Opretter 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>Cannot find %x.</source> <target>Kan ikke finde %x.</target> @@ -525,12 +537,6 @@ Kommandoen udføres hvis: <source>Generating database...</source> <target>Opretter database...</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> @@ -572,13 +578,15 @@ Kommandoen udføres hvis: <pluralform>Automatic retry in %x seconds...</pluralform> </source> <target> +<pluralform>Prøver igen om 1 sekund...</pluralform> +<pluralform>Prøver igen om %x sekunder...</pluralform> </target> <source>&Ignore subsequent errors</source> <target>&Ignorer efterfølgende fejl</target> <source>Retrying operation...</source> -<target></target> +<target>Prøver igen...</target> <source>Serious Error</source> <target>Kritisk fejl</target> @@ -605,7 +613,7 @@ Kommandoen udføres hvis: <target>Kunne ikke finde FreeFileSync's versionsnummer online. Vil du kontrollere manuelt?</target> <source>&Check</source> -<target></target> +<target>&Kontroller</target> <source>Symlink</source> <target>Symlink</target> @@ -763,12 +771,6 @@ Kommandoen udføres hvis: <source>Save as batch job</source> <target>Gem som batchfil</target> -<source>Hide excluded items</source> -<target>Skjul ekskluderede emner</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Vis filtrerede eller midlertidigt ekskluderede filer</target> - <source>Number of files and folders that will be created</source> <target>Antal filer og mapper der oprettes</target> @@ -802,8 +804,8 @@ Kommandoen udføres hvis: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Find og udbred ændringer på begge sider. Sletninger, omdøbninger og konflikter findes automatisk i en database.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>Spejl venstre mappe. Efter synkronisering er højre mappe en kopi af venstre.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>Opret spejling af venstre mappe ved at tilpasse den højre mappe</target> <source>Copy new and updated files to the right folder.</source> <target>Kopier nye og opdaterede filer til højre mappe.</target> @@ -814,8 +816,16 @@ Kommandoen udføres hvis: <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> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Kræver og opretter databasefiler +- Genkendelse aktiv efter første synk +- Understøtter ikke alle filsystemer +</target> <source>Delete files:</source> <target>Filsletning:</target> @@ -1048,6 +1058,9 @@ This guarantees a consistent state even in case of a serious error. <source>Find</source> <target>Søg</target> +<source>Select View</source> +<target>Tilpas visning</target> + <source>Overview</source> <target>Oversigt</target> @@ -1057,12 +1070,6 @@ This guarantees a consistent state even in case of a serious error. <source>Main Bar</source> <target>Hovedlinie</target> -<source>Filter Files</source> -<target>Filtrer filer</target> - -<source>Select View</source> -<target>Tilpas visning</target> - <source>Open...</source> <target>Åben...</target> @@ -1089,6 +1096,8 @@ This guarantees a consistent state even in case of a serious error. <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>&Execute</source> @@ -1113,12 +1122,12 @@ This guarantees a consistent state even in case of a serious error. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>%y af 1 række i visning</pluralform> -<pluralform>%y af %x rækker i visning</pluralform> +<pluralform>Viser %y af 1 række</pluralform> +<pluralform>Viser %y af %x rækker</pluralform> </target> <source>Set direction:</source> @@ -1235,6 +1244,9 @@ This guarantees a consistent state even in case of a serious error. <source>Show files that won't be copied</source> <target>Vis filer der ikke kopieres</target> +<source>Show filtered or temporarily excluded files</source> +<target>Vis filtrerede eller midlertidigt ekskluderede filer</target> + <source>Set as default</source> <target>Sæt som standard</target> @@ -1271,6 +1283,9 @@ This guarantees a consistent state even in case of a serious error. <source>Warning</source> <target>Advarsel</target> +<source>Select all</source> +<target>Vælg alt</target> + <source>Paused</source> <target>Pauset</target> diff --git a/FreeFileSync/Build/Languages/dutch.lng b/FreeFileSync/Build/Languages/dutch.lng index e5bd8c9e..bb2c19fb 100644 --- a/FreeFileSync/Build/Languages/dutch.lng +++ b/FreeFileSync/Build/Languages/dutch.lng @@ -88,18 +88,18 @@ <source>Any number of alternative directories for at most one config file.</source> <target>Elk aantal alternatieve bestandslocaties voor een configuratiebestand.</target> -<source>A folder input field is empty.</source> -<target>Een map invoerveld is leeg.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>De overeenkomstige map zal als leeg worden beschouwd.</target> - <source>Cannot find the following folders:</source> <target>Kan de volgende mappen niet vinden:</target> <source>You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.</source> <target>U kunt deze foutmelding negeren om elke map als leeg te markeren. De mappen worden dan automatisch aangemaakt tijdens de synchronisatie.</target> +<source>A folder input field is empty.</source> +<target>Een map invoerveld is leeg.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>De overeenkomstige map zal als leeg worden beschouwd.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>De volgende mappen hebben afhankelijke paden. Wees voorzichtig bij het opzetten van synchronisatieregels:</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>Kan geen procesinformatie verkrijgen.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Wachten totdat map is vergrendeld (%x)...</target> +<source>Waiting while directory is locked:</source> +<target>Wachten terwijl directory gelocked is:</target> + +<source>Lock owner:</source> +<target>Lock eigenaar:</target> <source> <pluralform>1 sec</pluralform> @@ -232,6 +235,9 @@ <pluralform>%x sec</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>Detecteren van achter gelaten lock...</target> + <source>Creating file %x</source> <target>Bestand %x wordt aangemaakt</target> @@ -287,7 +293,7 @@ <target>/sec</target> <source>%x items/sec</source> -<target></target> +<target>%x items per seconde</target> <source>Configuration file %x loaded partially only.</source> <target>Configuratiebestand %x alleen deels geladen.</target> @@ -317,10 +323,10 @@ <target>Schijfnaam %x is geen deel van bestandspad %y.</target> <source>Stop requested: Waiting for current operation to finish...</source> -<target></target> +<target>Stop aangegeven: Wachten tot de huidige handeling klaar is...</target> <source>Unable to create timestamp for versioning:</source> -<target></target> +<target>Niet mogelijk om een timestamp voor versiebeheer te maken:</target> <source>Cannot read the following XML elements:</source> <target>Kan de volgende XML elementen niet lezen:</target> @@ -338,7 +344,7 @@ <target>&Programma</target> <source>&View help</source> -<target></target> +<target>Help &bekijken</target> <source>&About</source> <target>&Over</target> @@ -362,7 +368,7 @@ <target>Importeer een .ffs_batch bestand om te beginnen.</target> <source>Folders to watch:</source> -<target></target> +<target>Mappen om te bekijken:</target> <source>Add folder</source> <target>Map toevoegen</target> @@ -377,13 +383,13 @@ <target>Selecteer een map</target> <source>Idle time (in seconds):</source> -<target></target> +<target>Stationaire tijd (in seconden):</target> <source>Idle time between last detected change and execution of command</source> <target>Tijd tussen de laatste gedetecteerde verandering en de uitvoering van het commando</target> <source>Command line:</source> -<target></target> +<target>Command line:</target> <source> The command is triggered if: @@ -397,7 +403,7 @@ De opdracht word geactiveerd als: </target> <source>&Start</source> -<target></target> +<target>&Start</target> <source>About</source> <target>Informatie</target> @@ -409,7 +415,7 @@ De opdracht word geactiveerd als: <target>Alle bestanden</target> <source>Automated Synchronization</source> -<target></target> +<target>Automatische Synchronisatie</target> <source>Directory monitoring active</source> <target>Bestandslocatie controle actief</target> @@ -430,7 +436,7 @@ De opdracht word geactiveerd als: <target>&Afsluiten</target> <source>Incorrect command line:</source> -<target></target> +<target>Incorrectie command line:</target> <source>&Retry</source> <target>&Opnieuw proberen</target> @@ -486,6 +492,12 @@ De opdracht word geactiveerd als: <source>Updating attributes of %x</source> <target>Attributen bijwerken van %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>Cannot find %x.</source> <target>Kan %x niet vinden.</target> @@ -496,7 +508,7 @@ De opdracht word geactiveerd als: <target>Doelmap mag niet leeg zijn.</target> <source>Please enter a target folder for versioning.</source> -<target></target> +<target>Selecteer alstublieft een doelmap voor versiebeheer.</target> <source>Source folder %x not found.</source> <target>Bronmap %x niet gevonden.</target> @@ -525,17 +537,11 @@ De opdracht word geactiveerd als: <source>Generating database...</source> <target>Genereren van database...</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 stopped</source> -<target></target> +<target>Synchronisatie gestopt</target> <source>Synchronization completed with errors</source> <target>Synchronisatie is met fouten afgerond</target> @@ -553,7 +559,7 @@ De opdracht word geactiveerd als: <target>Opslaan van logbestand %x...</target> <source>You can switch to FreeFileSync's main window to resolve this issue.</source> -<target></target> +<target>U kunt naar het hoofdvenster overschakelen om dit probleem op te lossen.</target> <source>&Don't show this warning again</source> <target>Laat deze &waarschuwing niet meer zien</target> @@ -565,26 +571,28 @@ De opdracht word geactiveerd als: <target>&Omschakelen</target> <source>Switching to FreeFileSync's main window</source> -<target></target> +<target>Overschakelen naar FreeFileSync's hoofdvenster</target> <source> <pluralform>Automatic retry in 1 second...</pluralform> <pluralform>Automatic retry in %x seconds...</pluralform> </source> <target> +<pluralform>Automatisch opnieuw proberen in 1 seconde...</pluralform> +<pluralform>Automatisch opnieuw proberen in %x seconden...</pluralform> </target> <source>&Ignore subsequent errors</source> <target>&Negeer volgende foutmeldingen</target> <source>Retrying operation...</source> -<target></target> +<target>Handeling opnieuw proberen...</target> <source>Serious Error</source> -<target></target> +<target>Serieuze Error</target> <source>Check for Program Updates</source> -<target></target> +<target>Controleer op programma updates</target> <source>A new version of FreeFileSync is available:</source> <target>Er is een nieuwe versie van FreeFileSync beschikbaar:</target> @@ -605,7 +613,7 @@ De opdracht word geactiveerd als: <target>Kan huidige FreeFileSync versienummer niet online vinden. Wilt u handmatig controleren?</target> <source>&Check</source> -<target></target> +<target>&Check</target> <source>Symlink</source> <target>Symlink</target> @@ -659,19 +667,19 @@ De opdracht word geactiveerd als: <target>Slaapstand</target> <source>Alternate comparison settings</source> -<target></target> +<target>Alternatieve vergelijkings instellingen</target> <source>Alternate synchronization settings</source> -<target></target> +<target>Alternatieve synchronisatie instellingen</target> <source>Local filter</source> -<target></target> +<target>Lokale filter</target> <source>Active</source> -<target></target> +<target>Actieve</target> <source>None</source> -<target></target> +<target>Geen</target> <source>Remove alternate settings</source> <target>Verwijder alternatieve instellingen</target> @@ -686,13 +694,13 @@ De opdracht word geactiveerd als: <target>Plakken</target> <source>Alternate Comparison Settings</source> -<target></target> +<target>Alternatieve vergelijkings instellingen</target> <source>Alternate Synchronization Settings</source> -<target></target> +<target>Alternatieve synchronisatie instellingen</target> <source>Local Filter</source> -<target></target> +<target>Lokale filter</target> <source>&New</source> <target>&Nieuw</target> @@ -716,7 +724,7 @@ De opdracht word geactiveerd als: <target>&Taal</target> <source>&Find...</source> -<target></target> +<target>&Zoek...</target> <source>&Export file list...</source> <target>&Exporteer bestandslijst...</target> @@ -731,7 +739,7 @@ De opdracht word geactiveerd als: <target>Controleer &automatisch eens per week</target> <source>&Check for new version</source> -<target></target> +<target>&Controleer voor nieuwe versie</target> <source>Compare</source> <target>Vergelijk</target> @@ -752,10 +760,10 @@ De opdracht word geactiveerd als: <target>Wissel zijdes</target> <source>Close search bar</source> -<target></target> +<target>Sluit zoekbalk</target> <source>Find:</source> -<target></target> +<target>Zoek:</target> <source>Match case</source> <target>Hoofdlettergevoelig</target> @@ -763,12 +771,6 @@ De opdracht word geactiveerd als: <source>Save as batch job</source> <target>Opslaan als batch opdracht</target> -<source>Hide excluded items</source> -<target>Verberg uitgesloten bestanden</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Laat gefilterde of tijdelijk uitgesloten bestanden zien</target> - <source>Number of files and folders that will be created</source> <target>Aantal bestanden en mappen die zullen worden aangemaakt</target> @@ -782,19 +784,19 @@ De opdracht word geactiveerd als: <target>Aantal bytes om te kopiëren</target> <source>Select a variant:</source> -<target></target> +<target>Selecteer een variant:</target> <source>Identify equal files by comparing modification time and size.</source> -<target></target> +<target>Identificeer gelijke bestanden door bewerkingstijd en grootte te vergelijken.</target> <source>Identify equal files by comparing the file content.</source> -<target></target> +<target>Identificeer gelijke bestanden door de bestandsinhoud te vergelijken.</target> <source>Symbolic links:</source> -<target></target> +<target>Snelkoppelingen:</target> <source>More information</source> -<target></target> +<target>Meer informatie</target> <source>OK</source> <target>OK</target> @@ -802,11 +804,11 @@ De opdracht word geactiveerd als: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Identificeer en pas veranderingen toe aan beide kanten. Verwijderingen, verplaatsingen en conflicten worden automatisch gevonden met behulp van een database.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target></target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>Maak een spiegelbackup van de linkermap door te zorgen dat de rechtermap gelijk is.</target> <source>Copy new and updated files to the right folder.</source> -<target></target> +<target>Kopiëer nieuwe en geupdate bestanden naar de rechtermap.</target> <source>Configure your own synchronization rules.</source> <target>Configureer uw eigen synchronisatieregels.</target> @@ -814,11 +816,19 @@ De opdracht word geactiveerd als: <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> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Vereist en creeërt database bestanden +- Detectie actief na eerste synchronisatie +- Niet ondersteund door alle bestandssystemen +</target> <source>Delete files:</source> -<target></target> +<target>Verwijder bestanden:</target> <source>Permanent</source> <target>Permanent</target> @@ -842,10 +852,10 @@ De opdracht word geactiveerd als: <target>Naamgevingsconventie</target> <source>Show examples</source> -<target></target> +<target>Laat voorbeelden zien</target> <source>Handle errors:</source> -<target></target> +<target>Fouten afhandelen:</target> <source>Ignore</source> <target>Negeer</target> @@ -860,13 +870,13 @@ De opdracht word geactiveerd als: <target>Laat pop-up zien bij foutmeldingen of waarschuwingen</target> <source>On completion:</source> -<target></target> +<target>Bij voltooiing:</target> <source>Start synchronization now?</source> -<target></target> +<target>Start de synchronisatie nu?</target> <source>Variant:</source> -<target></target> +<target>Variant:</target> <source>Statistics</source> <target>Statistieken</target> @@ -899,31 +909,31 @@ De opdracht word geactiveerd als: <target>&Pauze</target> <source>Stop</source> -<target></target> +<target>Stop</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>Stop synchronization at first error</source> -<target></target> +<target>Stop synchronisatie bij eerste foutmelding</target> <source>Show progress dialog</source> <target>Toon voortgangsdialoogvenster</target> <source>Save log:</source> -<target></target> +<target>Bewaar logbestand:</target> <source>Limit:</source> -<target></target> +<target>Beperk:</target> <source>Limit maximum number of log files</source> <target>Limiteer maximaal aantal log bestanden</target> <source>How can I schedule a batch job?</source> -<target></target> +<target>Hoe kan ik een batch taak inroosteren?</target> <source>&Recycle bin</source> -<target></target> +<target>&Prullebak</target> <source>Delete on both sides</source> <target>Verwijder aan beide zijdes</target> @@ -932,31 +942,31 @@ De opdracht word geactiveerd als: <target>Verwijder aan beide zijdes ook al is het bestand maar aan één zijde geselecteerd</target> <source>Select filter rules to exclude certain files from synchronization. Enter file paths relative to their corresponding folder pair.</source> -<target></target> +<target>Selecteer filter regels om bepaalde bestanden uit te sluiten van synchronisatie. Geef bestandspaden in die relatief zijn aan hun corresponderende folderparen.</target> <source>Include:</source> -<target></target> +<target>Meerekenen:</target> <source>Exclude:</source> -<target></target> +<target>Uitsluiten:</target> <source>Time span:</source> -<target></target> +<target>Tijdspanne:</target> <source>File size:</source> -<target></target> +<target>Bestandsgrootte:</target> <source>Minimum:</source> -<target></target> +<target>Minimum:</target> <source>Maximum:</source> -<target></target> +<target>Maximum:</target> <source>&Clear</source> <target>&Leegmaken</target> <source>The following settings are used for all synchronization jobs.</source> -<target></target> +<target>De volgende instellingen worden gebruikt voor alle synchronisaties.</target> <source>Fail-safe file copy</source> <target>Fail-safe bestandskopie</target> @@ -965,43 +975,46 @@ De opdracht word geactiveerd als: Copy to a temporary file (*.ffs_tmp) before overwriting target. This guarantees a consistent state even in case of a serious error. </source> -<target></target> +<target> +Kopiëer naar een tijdelijk bestand (*.ffs_tmp) voor je het doel overschrijft. +Dit garandeert een consistente staat, zelfs in het geval van een serieuze fout. +</target> <source>(recommended)</source> -<target></target> +<target>(aanbevolen)</target> <source>Copy locked files</source> <target>Kopiëer vergrendelde bestanden</target> <source>Copy shared or locked files using the Volume Shadow Copy Service.</source> -<target></target> +<target>Kopiëer gedeelde of vergrendelde bestanden met behulp van de Volume Shadow Copy Service.</target> <source>(requires administrator rights)</source> -<target></target> +<target>(vereist administrator rechten)</target> <source>Copy file access permissions</source> <target>Kopiëer toegangsrechten van bestand.</target> <source>Transfer file and folder permissions.</source> -<target></target> +<target>Draag bestands- en maprechten over.</target> <source>Automatic retry on error:</source> -<target></target> +<target>Probeer automatisch opnieuw bij foutmelding:</target> <source>Retry count:</source> -<target></target> +<target>Aantal pogingen:</target> <source>Delay (in seconds):</source> -<target></target> +<target>Vertraging (in seconden):</target> <source>Customize context menu:</source> -<target></target> +<target>Contextmenu aanpassen:</target> <source>Description</source> <target>Omschrijving</target> <source>Restore hidden windows</source> -<target></target> +<target>Herstel verborgen vensters</target> <source>&Default</source> <target>&Standaard</target> @@ -1031,23 +1044,26 @@ This guarantees a consistent state even in case of a serious error. <target>Veel dank voor de vertalingen:</target> <source>Save as Batch Job</source> -<target></target> +<target>Opslaan als batch opdracht</target> <source>Delete Items</source> -<target></target> +<target>Verwijder items</target> <source>Global Settings</source> -<target></target> +<target>Globale instellingen</target> <source>Select Time Span</source> -<target></target> +<target>Selecteer tijdspanne</target> <source>Folder Pairs</source> -<target></target> +<target>Map koppelingen</target> <source>Find</source> <target>Vind</target> +<source>Select View</source> +<target>Selecteer zichtbaarheid</target> + <source>Overview</source> <target>Overzicht</target> @@ -1055,13 +1071,7 @@ This guarantees a consistent state even in case of a serious error. <target>Configuratie</target> <source>Main Bar</source> -<target></target> - -<source>Filter Files</source> -<target></target> - -<source>Select View</source> -<target></target> +<target>Hoofdbalk</target> <source>Open...</source> <target>Open...</target> @@ -1089,6 +1099,8 @@ This guarantees a consistent state even in case of a serious error. <pluralform>Do you really want to execute the command %y for %x items?</pluralform> </source> <target> +<pluralform>Wilt u echt het commando %y uitvoeren voor 1 item?</pluralform> +<pluralform>Wilt u echt het commando %y uitvoeren voor %x items?</pluralform> </target> <source>&Execute</source> @@ -1113,12 +1125,12 @@ This guarantees a consistent state even in case of a serious error. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>%y van 1 rij in weergave</pluralform> -<pluralform>%y van %x rijen in weergave</pluralform> +<pluralform>Bezig met%y van 1 rij laten zien</pluralform> +<pluralform>Bezig met %y van %x rijen laten zien</pluralform> </target> <source>Set direction:</source> @@ -1235,6 +1247,9 @@ This guarantees a consistent state even in case of a serious error. <source>Show files that won't be copied</source> <target>Toon bestanden die niet gekopiëerd zullen worden</target> +<source>Show filtered or temporarily excluded files</source> +<target>Laat gefilterde of tijdelijk uitgesloten bestanden zien</target> + <source>Set as default</source> <target>Instellen als standaard</target> @@ -1242,10 +1257,10 @@ This guarantees a consistent state even in case of a serious error. <target>Alle mappen zijn gesynchroniseerd</target> <source>Synchronization Settings</source> -<target></target> +<target>Synchronisatie instellingen</target> <source>Comparison Settings</source> -<target></target> +<target>Vergelijkings instellingen</target> <source>Cannot find %x</source> <target>Kan %x niet vinden</target> @@ -1271,6 +1286,9 @@ This guarantees a consistent state even in case of a serious error. <source>Warning</source> <target>Waarschuwing</target> +<source>Select all</source> +<target>Selecteer alles</target> + <source>Paused</source> <target>Gepauzeerd</target> @@ -1278,7 +1296,7 @@ This guarantees a consistent state even in case of a serious error. <target>Initialiseren...</target> <source>Stopped</source> -<target></target> +<target>Gestopt</target> <source>Completed</source> <target>Voltooid</target> @@ -1323,7 +1341,7 @@ This guarantees a consistent state even in case of a serious error. </target> <source>Move</source> -<target></target> +<target>Verplaats</target> <source> <pluralform>Do you really want to delete the following item?</pluralform> @@ -1362,7 +1380,7 @@ This guarantees a consistent state even in case of a serious error. <target>- Tegenhanger van de andere kant naar %item_folder%</target> <source>Restore all hidden windows and warnings?</source> -<target></target> +<target>Herstel alle verborgen vensters en waarschuwingen?</target> <source>Leave as unresolved conflict</source> <target>Beschouw als onopgelost conflict</target> @@ -1488,13 +1506,13 @@ This guarantees a consistent state even in case of a serious error. </target> <source>Unable to register to receive system messages.</source> -<target></target> +<target>Registreren voor het verkrijgen van systeemmeldingen is niet mogelijk.</target> <source>Cannot set privilege %x.</source> <target>Kan privilege %x niet instellen.</target> <source>Unable to suspend system sleep mode.</source> -<target></target> +<target>Niet in staat om slaapstand uit te stellen.</target> <source>Cannot change process I/O priorities.</source> <target>Kan de I/O prioriteiten niet aanpassen.</target> diff --git a/FreeFileSync/Build/Languages/english_uk.lng b/FreeFileSync/Build/Languages/english_uk.lng index c793b010..ae1d0cb4 100644 --- a/FreeFileSync/Build/Languages/english_uk.lng +++ b/FreeFileSync/Build/Languages/english_uk.lng @@ -771,12 +771,6 @@ The command is triggered if: <source>Save as batch job</source> <target>Save as batch job</target> -<source>Hide excluded items</source> -<target>Hide excluded items</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Show filtered or temporarily excluded files</target> - <source>Number of files and folders that will be created</source> <target>Number of files and folders that will be created</target> @@ -810,8 +804,8 @@ The command is triggered if: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>Create a mirror backup of the left folder which exactly matches the right folder after synchronisation.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>Create a mirror backup of the left folder by adapting the right folder to match.</target> <source>Copy new and updated files to the right folder.</source> <target>Copy new and updated files to the right folder.</target> @@ -822,8 +816,16 @@ The command is triggered if: <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> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</target> <source>Delete files:</source> <target>Delete files:</target> @@ -1059,6 +1061,9 @@ This guarantees a consistent state even in case of a serious error. <source>Find</source> <target>Find</target> +<source>Select View</source> +<target>Select View</target> + <source>Overview</source> <target>Overview</target> @@ -1068,12 +1073,6 @@ This guarantees a consistent state even in case of a serious error. <source>Main Bar</source> <target>Main Bar</target> -<source>Filter Files</source> -<target>Filter Files</target> - -<source>Select View</source> -<target>Select View</target> - <source>Open...</source> <target>Open...</target> @@ -1126,12 +1125,12 @@ This guarantees a consistent state even in case of a serious error. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </target> <source>Set direction:</source> @@ -1248,6 +1247,9 @@ This guarantees a consistent state even in case of a serious error. <source>Show files that won't be copied</source> <target>Show files that won't be copied</target> +<source>Show filtered or temporarily excluded files</source> +<target>Show filtered or temporarily excluded files</target> + <source>Set as default</source> <target>Set as default</target> diff --git a/FreeFileSync/Build/Languages/finnish.lng b/FreeFileSync/Build/Languages/finnish.lng index eae610ca..1ca0d45b 100644 --- a/FreeFileSync/Build/Languages/finnish.lng +++ b/FreeFileSync/Build/Languages/finnish.lng @@ -88,18 +88,18 @@ <source>Any number of alternative directories for at most one config file.</source> <target>Vapaa määrä eri hakemistoja yhdessä määrittelytiedostossa.</target> -<source>A folder input field is empty.</source> -<target>Hakemiston syöte on tyhjä.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>Hakemisto tulkitaan tyhjäksi.</target> - <source>Cannot find the following folders:</source> <target>Hakemistot ei löydy:</target> <source>You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.</source> <target>Voit ohita virhe olettamalla hakemistot tyhjiksi. Hakemistot luodaan täsmäytyksen aikana.</target> +<source>A folder input field is empty.</source> +<target>Hakemiston syöte on tyhjä.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>Hakemisto tulkitaan tyhjäksi.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>Hakemistolla on polkumäärittely. Luo täsmäytyksen vertailusäännöt huolella:</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>Prosessin tietoja ei saada.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Odotan hakemiston lukitusta (%x)...</target> +<source>Waiting while directory is locked:</source> +<target>Odotetaan hakemiston lukitusta:</target> + +<source>Lock owner:</source> +<target>Lukitse haltija:</target> <source> <pluralform>1 sec</pluralform> @@ -232,6 +235,9 @@ <pluralform>%x s</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>Hylätty lukitus löydetty...</target> + <source>Creating file %x</source> <target>Luodaan tiedosto %x</target> @@ -486,6 +492,12 @@ Käsky suoritetaan jos: <source>Updating attributes of %x</source> <target>Päivitän %x:n ominaisuudet</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>Cannot find %x.</source> <target>%x ei löydy.</target> @@ -525,12 +537,6 @@ Käsky suoritetaan jos: <source>Generating database...</source> <target>Tietokanta luodaan...</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> @@ -572,13 +578,15 @@ Käsky suoritetaan jos: <pluralform>Automatic retry in %x seconds...</pluralform> </source> <target> +<pluralform>Uusi yritys 1 sekuntti...</pluralform> +<pluralform>Uusi yritys %x sekunttia...</pluralform> </target> <source>&Ignore subsequent errors</source> <target>&Hylkää toistuvat virheet</target> <source>Retrying operation...</source> -<target></target> +<target>Yritetään uudestaan...</target> <source>Serious Error</source> <target>Vakava virhe</target> @@ -605,7 +613,7 @@ Käsky suoritetaan jos: <target>Nykyinen FreeFileSync versio ei löydy verkosta, etsitäänkö manuaalisesti?</target> <source>&Check</source> -<target></target> +<target>&Tarkista</target> <source>Symlink</source> <target>Pikakuvake</target> @@ -763,12 +771,6 @@ Käsky suoritetaan jos: <source>Save as batch job</source> <target>Tallenna eräajona</target> -<source>Hide excluded items</source> -<target>Piilota ohitettavat</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Näytä suodatetut/nyt pois suljetut tiedostot</target> - <source>Number of files and folders that will be created</source> <target>Luotavien tiedostojen ja hakemistojen määrä</target> @@ -802,8 +804,8 @@ Käsky suoritetaan jos: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Löydä ja suorita muutokset molemmilla puolilla. Poistot, siirrot ja eroavuudet tunnistetaan tietokannan avulla.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>Tee tarkka kopio vasemmasta oikealle.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>Luo näköisversio vasemmasta hakemistosta muokkaamalla oikeata.</target> <source>Copy new and updated files to the right folder.</source> <target>Monista muuttuneet ja uudet oikealle.</target> @@ -814,8 +816,16 @@ Käsky suoritetaan jos: <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> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Luodaan tarvittavat tietokannat +- Tunnistus alkaa 1:tä täsmäytyksestä +- Ei toimi kaikissa tietojärjestelmissä +</target> <source>Delete files:</source> <target>Poista tiedosto:</target> @@ -827,7 +837,7 @@ Käsky suoritetaan jos: <target>Poista tai korvaa tiedostoja pysyvästi</target> <source>Recycle bin</source> -<target></target> +<target>Roskakori</target> <source>Back up deleted and overwritten files in the recycle bin</source> <target>Tallenna poistetut/ylikirjoitetut tiedostot Roskakoriin</target> @@ -1051,6 +1061,9 @@ Tällä varmistetaa eheys vaikka vakava virhe tapahtuisi. <source>Find</source> <target>Etsi</target> +<source>Select View</source> +<target>Valitse näkymä</target> + <source>Overview</source> <target>Yleiskatsaus</target> @@ -1060,12 +1073,6 @@ Tällä varmistetaa eheys vaikka vakava virhe tapahtuisi. <source>Main Bar</source> <target>Pääpalkki</target> -<source>Filter Files</source> -<target>Suodata tiedostot</target> - -<source>Select View</source> -<target>Valitse näkymä</target> - <source>Open...</source> <target>Avaa...</target> @@ -1092,6 +1099,8 @@ Tällä varmistetaa eheys vaikka vakava virhe tapahtuisi. <pluralform>Do you really want to execute the command %y for %x items?</pluralform> </source> <target> +<pluralform>Haluatko varmasti suorittaa %y tälle kohteelle?</pluralform> +<pluralform>Haluatko varmasti suorittaa %y näille %x kohteelle?</pluralform> </target> <source>&Execute</source> @@ -1116,12 +1125,12 @@ Tällä varmistetaa eheys vaikka vakava virhe tapahtuisi. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>%y rivi 1:stä näytetään</pluralform> -<pluralform>%y riviä %x:stä näytetään</pluralform> +<pluralform>Näytetään %y 1 riville</pluralform> +<pluralform>Näytetään %y , %x riville</pluralform> </target> <source>Set direction:</source> @@ -1238,6 +1247,9 @@ Tällä varmistetaa eheys vaikka vakava virhe tapahtuisi. <source>Show files that won't be copied</source> <target>Näytä kopioimatta jäävät tiedostot</target> +<source>Show filtered or temporarily excluded files</source> +<target>Näytä suodatetut/nyt pois suljetut tiedostot</target> + <source>Set as default</source> <target>Aseta oletukseksi</target> @@ -1274,6 +1286,9 @@ Tällä varmistetaa eheys vaikka vakava virhe tapahtuisi. <source>Warning</source> <target>Varoitus</target> +<source>Select all</source> +<target>Valitse kaikki</target> + <source>Paused</source> <target>Pysäytetty</target> diff --git a/FreeFileSync/Build/Languages/french.lng b/FreeFileSync/Build/Languages/french.lng index b0fa82e5..ac33a190 100644 --- a/FreeFileSync/Build/Languages/french.lng +++ b/FreeFileSync/Build/Languages/french.lng @@ -88,18 +88,18 @@ <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>A folder input field is empty.</source> -<target>Une entrée dossier est vide.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>Le dossier correspondant sera considéré comme vide.</target> - <source>Cannot find the following folders:</source> <target>Impossible de trouver les dossiers suivants :</target> <source>You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.</source> <target>Vous pouvez ignorer cette erreur en considérant chaque dossier comme vide. Les dossiers seront automatiquement créés pendant la synchronisation.</target> +<source>A folder input field is empty.</source> +<target>Une entrée dossier est vide.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>Le dossier correspondant sera considéré comme vide.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>Les fichiers suivants ont des chemins interdépendants. Attention à la mise à jour des règles de synchronisation :</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>Impossible d'obtenir les informations du traitement.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>En attente tant que le répertoire est verrouillé (%x)...</target> +<source>Waiting while directory is locked:</source> +<target>En attente tant que le répertoire est verrouillé :</target> + +<source>Lock owner:</source> +<target>Propriétaire du verrou :</target> <source> <pluralform>1 sec</pluralform> @@ -232,6 +235,9 @@ <pluralform>%x sec</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>Détection de verrouillage abandonné ...</target> + <source>Creating file %x</source> <target>Création du fichier %x</target> @@ -486,6 +492,12 @@ La commande est déclenchée si : <source>Updating attributes of %x</source> <target>Mise à jour des attributs de %x</target> +<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>Cannot find %x.</source> <target>Impossible de trouver %x</target> @@ -525,12 +537,6 @@ La commande est déclenchée si : <source>Generating database...</source> <target>Génération de la base de données...</target> -<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> @@ -572,13 +578,15 @@ La commande est déclenchée si : <pluralform>Automatic retry in %x seconds...</pluralform> </source> <target> +<pluralform>Nouvel essai dans %x seconde ...</pluralform> +<pluralform>Nouvel essai dans %x secondes ...</pluralform> </target> <source>&Ignore subsequent errors</source> <target>&Ignorer les erreurs suivantes</target> <source>Retrying operation...</source> -<target></target> +<target>Opération retentée ...</target> <source>Serious Error</source> <target>Erreur Grave</target> @@ -605,7 +613,7 @@ La commande est déclenchée si : <target>Impossible de trouver en ligne une nouvelle version de FreeFileSync.Voulez-vous le faire manuellement ?</target> <source>&Check</source> -<target></target> +<target>&Contrôle</target> <source>Symlink</source> <target>Lien symbolique</target> @@ -763,12 +771,6 @@ La commande est déclenchée si : <source>Save as batch job</source> <target>Enrgistrer en temps que fichier batch</target> -<source>Hide excluded items</source> -<target>Cacher les éléments exclus</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Afficher les fichiers filtrés ou temporairement exclus</target> - <source>Number of files and folders that will be created</source> <target>Nombre de fichiers et de dossiers qui seront créés</target> @@ -802,8 +804,8 @@ La commande est déclenchée si : <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Identifier et propager les modifications des deux côtés. Suppressions, déplacements et conflits sont détectés automatiquement en utilisant une base de données.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>Créer une copie miroir du dossier de gauche qui correspondra exactement à celui de droite après la synchronisation.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>Créer une sauvegarde miroir du dossier de gauche de telle sorte que le dossier de droite lui corresponde exactement.</target> <source>Copy new and updated files to the right folder.</source> <target>Copier les fichiers nouveaux ou mis à jour dans le dossier de droite.</target> @@ -814,8 +816,16 @@ La commande est déclenchée si : <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> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Nécessite et crée les fichiers de la base de données +- Détection active après la synchronisation initiale +- Non supporté par tout les fichiers système +</target> <source>Delete files:</source> <target>Supprimer les fichiers :</target> @@ -1051,6 +1061,9 @@ Cela garantit la cohérence du système de fichiers en cas d'erreur grave. <source>Find</source> <target>Rechercher</target> +<source>Select View</source> +<target>Sélection de l'Affichage</target> + <source>Overview</source> <target>Présentation</target> @@ -1060,12 +1073,6 @@ Cela garantit la cohérence du système de fichiers en cas d'erreur grave. <source>Main Bar</source> <target>Barre Principale</target> -<source>Filter Files</source> -<target>Filtrage des Fichiers</target> - -<source>Select View</source> -<target>Sélection de l'Affichage</target> - <source>Open...</source> <target>Ouvrir ...</target> @@ -1092,6 +1099,8 @@ Cela garantit la cohérence du système de fichiers en cas d'erreur grave. <pluralform>Do you really want to execute the command %y for %x items?</pluralform> </source> <target> +<pluralform>Êtes-vous sûr de vouloir exécuter la commande %y pour %x élément ?</pluralform> +<pluralform>Êtes-vous sûr de vouloir exécuter la commande %y pour %x éléments ?</pluralform> </target> <source>&Execute</source> @@ -1116,12 +1125,12 @@ Cela garantit la cohérence du système de fichiers en cas d'erreur grave. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>vue de %y ligne sur %x</pluralform> -<pluralform>vue de %y lignes sur %x</pluralform> +<pluralform>Affiche %y sur %x ligne</pluralform> +<pluralform>Affiche %y sur %x lignes</pluralform> </target> <source>Set direction:</source> @@ -1238,6 +1247,9 @@ Cela garantit la cohérence du système de fichiers en cas d'erreur grave. <source>Show files that won't be copied</source> <target>Afficher les fichiers qui ne seront pas copiés</target> +<source>Show filtered or temporarily excluded files</source> +<target>Afficher les fichiers filtrés ou temporairement exclus</target> + <source>Set as default</source> <target>Définir par défaut</target> @@ -1274,6 +1286,9 @@ Cela garantit la cohérence du système de fichiers en cas d'erreur grave. <source>Warning</source> <target>Attention</target> +<source>Select all</source> +<target>Tout sélectionner</target> + <source>Paused</source> <target>En pause</target> diff --git a/FreeFileSync/Build/Languages/german.lng b/FreeFileSync/Build/Languages/german.lng index 3a8e264e..26534798 100644 --- a/FreeFileSync/Build/Languages/german.lng +++ b/FreeFileSync/Build/Languages/german.lng @@ -771,12 +771,6 @@ Die Befehlszeile wird ausgelöst, wenn: <source>Save as batch job</source> <target>Als Batch-Auftrag speichern</target> -<source>Hide excluded items</source> -<target>Ausgeschlossene Elemente verstecken</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Gefilterte oder temporär ausgeschlossene Dateien zeigen</target> - <source>Number of files and folders that will be created</source> <target>Anzahl der zu erstellenden Dateien und Ordner</target> @@ -810,7 +804,7 @@ Die Befehlszeile wird ausgelöst, wenn: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Identifiziere und propagiere Änderungen auf beiden Seiten. Löschungen, Verschiebungen und Konflikte werden automatisch mit Hilfe einer Datenbank erkannt.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> <target>Eine Spiegelkopie des linken Ordners erstellen, indem der rechte Ordner angeglichen wird.</target> <source>Copy new and updated files to the right folder.</source> @@ -822,8 +816,16 @@ Die Befehlszeile wird ausgelöst, wenn: <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> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Benötigt und erstellt Datenbankdateien. +- Erst nach einmaliger Synchronisation aktiv. +- Wird nicht von allen Dateisystemen unterstützt. +</target> <source>Delete files:</source> <target>Dateien löschen:</target> @@ -1059,6 +1061,9 @@ Dadurch wird ein konsistenter Datenstand auch im schweren Fehlerfall garantiert. <source>Find</source> <target>Suchen</target> +<source>Select View</source> +<target>Ansicht auswählen</target> + <source>Overview</source> <target>Übersicht</target> @@ -1068,12 +1073,6 @@ Dadurch wird ein konsistenter Datenstand auch im schweren Fehlerfall garantiert. <source>Main Bar</source> <target>Hauptleiste</target> -<source>Filter Files</source> -<target>Dateien filtern</target> - -<source>Select View</source> -<target>Ansicht auswählen</target> - <source>Open...</source> <target>Öffnen...</target> @@ -1126,8 +1125,8 @@ Dadurch wird ein konsistenter Datenstand auch im schweren Fehlerfall garantiert. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> <pluralform>Zeige %y von 1 Zeile</pluralform> @@ -1248,6 +1247,9 @@ Dadurch wird ein konsistenter Datenstand auch im schweren Fehlerfall garantiert. <source>Show files that won't be copied</source> <target>Dateien die nicht kopiert werden anzeigen</target> +<source>Show filtered or temporarily excluded files</source> +<target>Gefilterte oder temporär ausgeschlossene Dateien zeigen</target> + <source>Set as default</source> <target>Als Standard festlegen</target> diff --git a/FreeFileSync/Build/Languages/greek.lng b/FreeFileSync/Build/Languages/greek.lng index 176f0409..216bea96 100644 --- a/FreeFileSync/Build/Languages/greek.lng +++ b/FreeFileSync/Build/Languages/greek.lng @@ -88,18 +88,18 @@ <source>Any number of alternative directories for at most one config file.</source> <target>Οποιοσδήποτε αριθμός εναλλακτικών υποκαταλόγων για το πολύ ένα αρχείο διάταξης.</target> -<source>A folder input field is empty.</source> -<target>Ένα πεδίο εισαγωγής υποκαταλόγων είναι άδειο.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>Ο αντίστοιχος υποκατάλογος θα θεωρηθεί κενός.</target> - <source>Cannot find the following folders:</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>A folder input field is empty.</source> +<target>Ένα πεδίο εισαγωγής υποκαταλόγων είναι άδειο.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>Ο αντίστοιχος υποκατάλογος θα θεωρηθεί κενός.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>Οι παρακάτω υποκατάλογοι δεν έχουν σταθερή διαδρομή. Προσοχή όταν ορίσετε κανόνες συγχρονισμού:</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>Δεν μπορούν να ληφθούν πληροφορίες για τις τρέχουσες διαδικασίες.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Αναμονή μέχρι να κλειδωθεί ο υποκατάλογος (%x)...</target> +<source>Waiting while directory is locked:</source> +<target>Αναμονή μέχρι να κλειδωθεί ο υποκατάλογος:</target> + +<source>Lock owner:</source> +<target>Ιδιοκτήτης κλειδώματος:</target> <source> <pluralform>1 sec</pluralform> @@ -232,6 +235,9 @@ <pluralform>%x δ/λεπτα</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>Ανίχνευση κλειδώματος που εγκαταλείφθηκε...</target> + <source>Creating file %x</source> <target>Δημιουργία του αρχείου %x</target> @@ -486,6 +492,12 @@ The command is triggered if: <source>Updating attributes of %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>Cannot find %x.</source> <target>Το %x δεν μπορεί να βρεθεί.</target> @@ -525,12 +537,6 @@ The command is triggered if: <source>Generating database...</source> <target>Δημιουργία βάσης δεδομένων...</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> @@ -580,13 +586,13 @@ The command is triggered if: <target>&Αγνόηση επόμενων σφαλμάτων</target> <source>Retrying operation...</source> -<target></target> +<target>Επανάληψη της προσπάθειας...</target> <source>Serious Error</source> <target>Σοβαρό Σφάλμα</target> <source>Check for Program Updates</source> -<target>Έλεγχος για Ενημερώσεις του Προγράμματος</target> +<target>Έλεγχος για ενημερώσεις του προγράμματος</target> <source>A new version of FreeFileSync is available:</source> <target>Μια νέα έκδοση του FreeFileSync είναι διαθέσιμη:</target> @@ -607,7 +613,7 @@ The command is triggered if: <target>Ο αριθμός της τρέχουσας έκδοσης του FreeFileSync δεν βρέθηκε στο δίκτυο. Θέλετε να το ελέγξετε εσείς;</target> <source>&Check</source> -<target></target> +<target>Έλε&γχος</target> <source>Symlink</source> <target>Συμβολικός δεσμός</target> @@ -765,12 +771,6 @@ The command is triggered if: <source>Save as batch job</source> <target>Αποθήκευση ως δέσμη ενεργειών</target> -<source>Hide excluded items</source> -<target>Απόκρυψη στοιχείων που εξαιρέθηκαν</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Εμφάνιση φιλτραρισμένων ή προσωρινά εξαιρεθέντων αρχείων</target> - <source>Number of files and folders that will be created</source> <target>Αριθμός αρχείων και υποκαταλόγων που θα δημιουργηθούν</target> @@ -804,8 +804,8 @@ The command is triggered if: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Αναγνώριση και εφαρμογή αλλαγών και στις δυο πλευρές. Οι διαγραφές, οι μεταφορές και οι διενέξεις αναγνωρίζονται αυτόματα με τη βοήθεια μιας βάσης δεδομένων.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>Δημιουργία ενός κατοπτρικού αντιγράφου του υποκαταλόγου αριστερά, ώστε μετά το συγχρονισμό ο υποκατάλογος δεξιά να είναι ένα ακριβές αντίγραφό του.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>Τροποποίηση του υποκαταλόγου δεξιά, ώστε να γίνει ακριβές αντίγραφο του υποκαταλόγου αριστερά.</target> <source>Copy new and updated files to the right folder.</source> <target>Αντιγραφή των νέων και των τροποποιημένων αρχείων στον υποκατάλογο δεξιά.</target> @@ -816,8 +816,16 @@ The command is triggered if: <source>Detect moved files</source> <target>Ανίχνευση των αρχείων που μεταφέρθηκαν</target> -<source>Requires database files. Not supported by all file systems.</source> -<target>Απαιτεί αρχεία βάσης δεδομένων. Δεν υποστηρίζεται από όλα τα συστήματα αρχείων.</target> +<source> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Απαιτεί και δημιουργεί αρχεία-βάσεις δεδομένων +- Η ανίχνευση είναι ενεργή μετά τον αρχικό συγχρονισμό +- Δεν υποστηρίζεται από όλα τα συστήματα αρχείων +</target> <source>Delete files:</source> <target>Διαγραφή αρχείων:</target> @@ -1053,6 +1061,9 @@ This guarantees a consistent state even in case of a serious error. <source>Find</source> <target>Αναζήτηση</target> +<source>Select View</source> +<target>Επιλογή Εμφάνισης</target> + <source>Overview</source> <target>Σύνοψη</target> @@ -1062,12 +1073,6 @@ This guarantees a consistent state even in case of a serious error. <source>Main Bar</source> <target>Κύρια Γραμμή</target> -<source>Filter Files</source> -<target>Φιλτράρισμα Αρχείων</target> - -<source>Select View</source> -<target>Επιλογή Εμφάνισης</target> - <source>Open...</source> <target>Άνοιγμα...</target> @@ -1094,6 +1099,8 @@ This guarantees a consistent state even in case of a serious error. <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>&Execute</source> @@ -1118,12 +1125,12 @@ This guarantees a consistent state even in case of a serious error. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>%y από τη 1 φανερή γραμμή</pluralform> -<pluralform>%y από τις %x φανερές γραμμές</pluralform> +<pluralform>Εμφανίζεται %y από 1 γραμμή</pluralform> +<pluralform>Εμφανίζονται %y από %x γραμμές</pluralform> </target> <source>Set direction:</source> @@ -1240,6 +1247,9 @@ This guarantees a consistent state even in case of a serious error. <source>Show files that won't be copied</source> <target>Εμφάνιση των αρχείων που δε θα αντιγραφούν</target> +<source>Show filtered or temporarily excluded files</source> +<target>Εμφάνιση φιλτραρισμένων ή προσωρινά εξαιρεθέντων αρχείων</target> + <source>Set as default</source> <target>Ορισμός ως προεπιλογής</target> @@ -1276,6 +1286,9 @@ This guarantees a consistent state even in case of a serious error. <source>Warning</source> <target>Προειδοποίηση</target> +<source>Select all</source> +<target>Επιλογή όλων</target> + <source>Paused</source> <target>Σε παύση</target> diff --git a/FreeFileSync/Build/Languages/hebrew.lng b/FreeFileSync/Build/Languages/hebrew.lng index 1667333d..2f9cf56a 100644 --- a/FreeFileSync/Build/Languages/hebrew.lng +++ b/FreeFileSync/Build/Languages/hebrew.lng @@ -7,6 +7,18 @@ <plural_definition>n == 1 ? 0 : 1</plural_definition> </header> +<source> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> +</source> +<target></target> + +<source> +<pluralform>Automatic retry in 1 second...</pluralform> +<pluralform>Automatic retry in %x seconds...</pluralform> +</source> +<target></target> + <source>Both sides have changed since last synchronization.</source> <target>שני הצדדים שונו מאז הסנכרון האחרון.</target> @@ -88,18 +100,18 @@ <source>Any number of alternative directories for at most one config file.</source> <target>כל כמות של מחיצות אלטרנטיביות עבור לפחות קובץ קונפיגורציה אחד.</target> -<source>A folder input field is empty.</source> -<target>שדה קלט תיקייה ריק.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>המחיצה המתאימה תחשב כריקה.</target> - <source>Cannot find the following folders:</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>A folder input field is empty.</source> +<target>שדה קלט תיקייה ריק.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>המחיצה המתאימה תחשב כריקה.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>מסלול המחיצות הבאות מותנה. שים לב כאשר חוקי הסינכרון מוגדרים:</target> @@ -220,8 +232,11 @@ <source>Cannot get process information.</source> <target>לא יכול לקבל את נתוני התהליך.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>ממתין כאשר מחיצה נעולה (%x)...</target> +<source>Waiting while directory is locked:</source> +<target>ממתין בזמן שהמחיצה נעולה:</target> + +<source>Lock owner:</source> +<target>בעלים נעול:</target> <source> <pluralform>1 sec</pluralform> @@ -232,6 +247,9 @@ <pluralform>%x שניות</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>מגלה נעילה נטושה...</target> + <source>Creating file %x</source> <target>יוצר קובץ %x</target> @@ -486,6 +504,12 @@ The command is triggered if: <source>Updating attributes of %x</source> <target>מעדכן תכונות של %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>Cannot find %x.</source> <target>לא מוצא %x.</target> @@ -525,12 +549,6 @@ The command is triggered if: <source>Generating database...</source> <target>מייצר מסד נתונים...</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> @@ -567,18 +585,11 @@ The command is triggered if: <source>Switching to FreeFileSync's main window</source> <target>מעבר אל החלון הראשי של FreeFileSybc</target> -<source> -<pluralform>Automatic retry in 1 second...</pluralform> -<pluralform>Automatic retry in %x seconds...</pluralform> -</source> -<target> -</target> - <source>&Ignore subsequent errors</source> <target>&התעלם מאזהרות נוספות</target> <source>Retrying operation...</source> -<target></target> +<target>מנסה שוב פעולה...</target> <source>Serious Error</source> <target>שגיאה חמורה</target> @@ -605,7 +616,7 @@ The command is triggered if: <target>לא מוצא מספר גירסה עדכנית של FreeFileSync באופן מכוון. האם אתה רוצה לבדוק באופן ידני?</target> <source>&Check</source> -<target></target> +<target>&בדוק</target> <source>Symlink</source> <target>קשור סימבולי</target> @@ -763,12 +774,6 @@ The command is triggered if: <source>Save as batch job</source> <target>שמור כעבודת אצווה</target> -<source>Hide excluded items</source> -<target>הסתר פריטים שלט נכללו</target> - -<source>Show filtered or temporarily excluded files</source> -<target>הראה קבצים שסוננו או לא נכללו זמנית</target> - <source>Number of files and folders that will be created</source> <target>מספר הקבצים והתיקיות שייוצרו</target> @@ -802,8 +807,8 @@ The command is triggered if: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>זהה והפץ שינויים בשני הצדדים. מחיקות העברות וסתירות מתגלים באופן אוטומטי באמצעות מסד נתונים.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>צור גבוי מראה של התיקייה השמאלית אשר יהיה זהה לתיקייה הימנית לאחר הסנכרון.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>צור גיבוי מראה של התיקיה משמאל באמצעות התאמת התיקיה מימין להתאמה.</target> <source>Copy new and updated files to the right folder.</source> <target>העתק קבצים חדשים ומעודכנים לתיקייה הימנית.</target> @@ -814,8 +819,16 @@ The command is triggered if: <source>Detect moved files</source> <target>גלה קבצים מועברים</target> -<source>Requires database files. Not supported by all file systems.</source> -<target>דורש קבצי בסיס נתונים. לא נתמך ע"י כל מערכות הקבצים.</target> +<source> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- דורש ויוצר קבצי בסיס נתונים +- גילוי פעיל לאחר סינכרון ראשוני +- לא נתמך ע"י כל מערכות הקבצים +</target> <source>Delete files:</source> <target>מחק קבצים:</target> @@ -1051,6 +1064,9 @@ This guarantees a consistent state even in case of a serious error. <source>Find</source> <target>חפש</target> +<source>Select View</source> +<target>בחר מבט</target> + <source>Overview</source> <target>מבט כללי</target> @@ -1060,12 +1076,6 @@ This guarantees a consistent state even in case of a serious error. <source>Main Bar</source> <target>סרגל ראשי</target> -<source>Filter Files</source> -<target>סנן קבצים</target> - -<source>Select View</source> -<target>בחר מבט</target> - <source>Open...</source> <target>פתח...</target> @@ -1117,15 +1127,6 @@ This guarantees a consistent state even in case of a serious error. <pluralform>%x קבצים</pluralform> </target> -<source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> -</source> -<target> -<pluralform>%y של שורה 1 במראה</pluralform> -<pluralform>%y של %x שורות במראה</pluralform> -</target> - <source>Set direction:</source> <target>בחר כוון:</target> @@ -1240,6 +1241,9 @@ This guarantees a consistent state even in case of a serious error. <source>Show files that won't be copied</source> <target>הראה קבצים שלא יועתקו</target> +<source>Show filtered or temporarily excluded files</source> +<target>הראה קבצים שסוננו או לא נכללו זמנית</target> + <source>Set as default</source> <target>הגדר כברירת מחדל</target> @@ -1276,6 +1280,9 @@ This guarantees a consistent state even in case of a serious error. <source>Warning</source> <target>אזהרה</target> +<source>Select all</source> +<target>בחר הכל</target> + <source>Paused</source> <target>עצור</target> diff --git a/FreeFileSync/Build/Languages/hungarian.lng b/FreeFileSync/Build/Languages/hungarian.lng index a9447de8..2bdd0c57 100644 --- a/FreeFileSync/Build/Languages/hungarian.lng +++ b/FreeFileSync/Build/Languages/hungarian.lng @@ -88,18 +88,18 @@ <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>A folder input field is empty.</source> -<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> - <source>Cannot find the following folders:</source> <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 ekkor automatikusan létrejönnek a szinkronizálás folyamán.</target> +<source>A folder input field is empty.</source> +<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> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>A következő könyvtárak egymástól függő útvonalat tartalmaznak. Légy óvatos a szinkronizálás szabályainak meghatározásánál!</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>Nem sikerült lekérdezni processz-információkat.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Várakozás a könyvtár zárolásának a feloldására (%x)...</target> +<source>Waiting while directory is locked:</source> +<target>Várakozás amíg a könyvtár zárolt:</target> + +<source>Lock owner:</source> +<target>Zárolás gazdája:</target> <source> <pluralform>1 sec</pluralform> @@ -232,6 +235,9 @@ <pluralform>%x másodperc</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>Elhagyott zárolást érzékel...</target> + <source>Creating file %x</source> <target>%x fájl létrehozása</target> @@ -486,6 +492,12 @@ A parancs végrehajtódik, ha: <source>Updating attributes of %x</source> <target>%x attribútumainak frissítése</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target>Készít egy árnyé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>Cannot find %x.</source> <target>%x nem található.</target> @@ -525,12 +537,6 @@ A parancs végrehajtódik, ha: <source>Generating database...</source> <target>Adatbázis generálása...</target> -<source>Creating a Volume Shadow Copy for %x...</source> -<target>Készít egy árnyé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> @@ -572,13 +578,15 @@ A parancs végrehajtódik, ha: <pluralform>Automatic retry in %x seconds...</pluralform> </source> <target> +<pluralform>Automatikus ismételt próbálkozás 1 másodperc múlva...</pluralform> +<pluralform>Automatikus ismételt próbálkozás %x másodperc múlva...</pluralform> </target> <source>&Ignore subsequent errors</source> <target>F&igyelmen kívül hagyja az utána következő hibákat</target> <source>Retrying operation...</source> -<target></target> +<target>Újra próbálja a műveletet...</target> <source>Serious Error</source> <target>Komoly hiba</target> @@ -605,7 +613,7 @@ A parancs végrehajtódik, ha: <target>Nem lehet online megtalálni a jelenlegi FreeFileSync verziószámot. Meg akarod keresni manuálisan?</target> <source>&Check</source> -<target></target> +<target>&Ellenőriz</target> <source>Symlink</source> <target>Symlink</target> @@ -763,12 +771,6 @@ A parancs végrehajtódik, ha: <source>Save as batch job</source> <target>Mentse kötegelt feladatként</target> -<source>Hide excluded items</source> -<target>Rejtse el a kizárt elemeket</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Mutassa a szűrt vagy ideiglenesen kizárt fájlokat</target> - <source>Number of files and folders that will be created</source> <target>A létrehozandó fájlok és könyvtárak száma</target> @@ -802,8 +804,8 @@ A parancs végrehajtódik, ha: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Változások keresése és bemutatása mindkét oldalon. A törléseket, mozgatásokat és ütközéseket automatikusan ismeri fel egy adatbázis segítségével.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>Készítse el a bal oldali könyvtár egy tükör-másolatát, amely pontosan megegyezik a jobb oldali könyvtárral a szinkronizálás után.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>A baloldali könyvtár tükörmásolatát készíti el úgy, hogy a jobb oldali könyvtár egyezzen meg</target> <source>Copy new and updated files to the right folder.</source> <target>Másolja az új és módosult fájlokat a jobb oldali könyvtárba.</target> @@ -814,8 +816,16 @@ A parancs végrehajtódik, ha: <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> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Adatbázis fájlokat feltételez és készít +- Az érzékelés a kezdeti szinkronizálás után válik aktívvá +- Nem minden fájlrendszer támogatja +</target> <source>Delete files:</source> <target>Törölje a következő fájlokat:</target> @@ -1051,6 +1061,9 @@ Ez garantálja a konzisztens állapotot egy komoly hiba esetén is. <source>Find</source> <target>Keres</target> +<source>Select View</source> +<target>Válasszon nézetet</target> + <source>Overview</source> <target>Áttekintés</target> @@ -1060,12 +1073,6 @@ Ez garantálja a konzisztens állapotot egy komoly hiba esetén is. <source>Main Bar</source> <target>Fő sáv</target> -<source>Filter Files</source> -<target>Szűrje a fájlokat</target> - -<source>Select View</source> -<target>Válasszon nézetet</target> - <source>Open...</source> <target>Megnyit...</target> @@ -1118,12 +1125,12 @@ Ez garantálja a konzisztens állapotot egy komoly hiba esetén is. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>1 sorból %y sor látható</pluralform> -<pluralform>%x sorból %y látható</pluralform> +<pluralform>%y sort mutat az 1-ből</pluralform> +<pluralform>%y sort mutat az %x közül</pluralform> </target> <source>Set direction:</source> @@ -1240,6 +1247,9 @@ Ez garantálja a konzisztens állapotot egy komoly hiba esetén is. <source>Show files that won't be copied</source> <target>Mutassa a nem másolandó fájlokat</target> +<source>Show filtered or temporarily excluded files</source> +<target>Mutassa a szűrt vagy ideiglenesen kizárt fájlokat</target> + <source>Set as default</source> <target>Beállítás alapértelmezettként</target> @@ -1276,6 +1286,9 @@ Ez garantálja a konzisztens állapotot egy komoly hiba esetén is. <source>Warning</source> <target>Figyelmeztetés</target> +<source>Select all</source> +<target>Összeset kiválasztja</target> + <source>Paused</source> <target>Megállítva</target> diff --git a/FreeFileSync/Build/Languages/italian.lng b/FreeFileSync/Build/Languages/italian.lng index 04b3e5c8..6609ff30 100644 --- a/FreeFileSync/Build/Languages/italian.lng +++ b/FreeFileSync/Build/Languages/italian.lng @@ -88,18 +88,18 @@ <source>Any number of alternative directories for at most one config file.</source> <target>Qualsiasi numero di directory alternative per al massimo un file di configurazione.</target> -<source>A folder input field is empty.</source> -<target>Un campo di input cartella è vuoto.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>La cartella corrispondente sarà considerata come vuota.</target> - <source>Cannot find the following folders:</source> <target>Impossibile trovare le seguenti cartelle:</target> <source>You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.</source> <target>È possibile ignorare questo errore che considera ogni cartella come vuota. Le cartelle poi verranno create automaticamente durante la sincronizzazione.</target> +<source>A folder input field is empty.</source> +<target>Un campo di input cartella è vuoto.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>La cartella corrispondente sarà considerata come vuota.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>Le seguenti cartelle hanno percorsi dipendenti. Fare attenzione quando si imposta le regole di sincronizzazione:</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>Impossibile ottenere informazioni sul processo.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Attendere, la cartella viene bloccata (%x)...</target> +<source>Waiting while directory is locked:</source> +<target>In attesa mentre la cartella è bloccata:</target> + +<source>Lock owner:</source> +<target>Bloccare il proprietario:</target> <source> <pluralform>1 sec</pluralform> @@ -232,6 +235,9 @@ <pluralform>%x sec</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>Rilevamento blocco abbandonato ...</target> + <source>Creating file %x</source> <target>Creazione file %x</target> @@ -412,10 +418,10 @@ Il comando è attivato se: <target>Sincronizzazione automatizzata</target> <source>Directory monitoring active</source> -<target>Monitoraggio directory attivo</target> +<target>Monitoraggio Cartella attivo</target> <source>Waiting until all directories are available...</source> -<target>Attendere finchè tutte le directory diventano disponibili...</target> +<target>Attendere finchè tutte le cartelle diventano disponibili...</target> <source>Error</source> <target>Errore</target> @@ -486,6 +492,12 @@ Il comando è attivato se: <source>Updating attributes of %x</source> <target>Aggiornamento attributi di %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>Cannot find %x.</source> <target>Impossibile trovare %x.</target> @@ -525,12 +537,6 @@ Il comando è attivato se: <source>Generating database...</source> <target>Generazione database...</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> @@ -765,12 +771,6 @@ Il comando è attivato se: <source>Save as batch job</source> <target>Salva come processo batch</target> -<source>Hide excluded items</source> -<target>Nascondi oggetti esclusi</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Mostra file filtrati o temporaneamente esclusi</target> - <source>Number of files and folders that will be created</source> <target>Numero di file e cartelle che verranno creati</target> @@ -804,8 +804,8 @@ Il comando è attivato se: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Identifica e propaga cambiamenti su entrambi i lati. Cancellazioni, spostamenti e conflitti sono identificati automaticamente usando un database.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>Creare un backup specchio della cartella di sinistra, che corrisponda esattamente alla cartella destra dopo la sincronizzazione.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>Creare un backup specchio della cartella di sinistra aggiornando la cartella giusta.</target> <source>Copy new and updated files to the right folder.</source> <target>Copiare i file nuovi e aggiornati nella cartella destra.</target> @@ -816,8 +816,16 @@ Il comando è attivato se: <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> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Richiede e crea file di database +- Rilevamento attivo dopo la sincronizzazione iniziale +- Non supportato da tutti i sistemi +</target> <source>Delete files:</source> <target>Eliminare i file:</target> @@ -1053,6 +1061,9 @@ Questo garantisce uno stato consistente anche in caso di errore grave. <source>Find</source> <target>Trova</target> +<source>Select View</source> +<target>Selezionare Visualizza</target> + <source>Overview</source> <target>Anteprima</target> @@ -1062,12 +1073,6 @@ Questo garantisce uno stato consistente anche in caso di errore grave. <source>Main Bar</source> <target>Barra Principale</target> -<source>Filter Files</source> -<target>Filtrare i file</target> - -<source>Select View</source> -<target>Selezionare Visualizza</target> - <source>Open...</source> <target>Apri...</target> @@ -1120,12 +1125,12 @@ Questo garantisce uno stato consistente anche in caso di errore grave. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>%y di 1 riga nella vista</pluralform> -<pluralform>%y di %x righe nella vista</pluralform> +<pluralform>Risultati %y di 1 riga</pluralform> +<pluralform>Risultati %y di %x righe</pluralform> </target> <source>Set direction:</source> @@ -1242,6 +1247,9 @@ Questo garantisce uno stato consistente anche in caso di errore grave. <source>Show files that won't be copied</source> <target>Mostra i file che non saranno copiati</target> +<source>Show filtered or temporarily excluded files</source> +<target>Mostra file filtrati o temporaneamente esclusi</target> + <source>Set as default</source> <target>Imposta come predefinito</target> @@ -1278,6 +1286,9 @@ Questo garantisce uno stato consistente anche in caso di errore grave. <source>Warning</source> <target>Attenzione</target> +<source>Select all</source> +<target>Seleziona tutto</target> + <source>Paused</source> <target>In pausa</target> @@ -1402,7 +1413,7 @@ Questo garantisce uno stato consistente anche in caso di errore grave. <target>Percentuale</target> <source>Cannot monitor directory %x.</source> -<target>Impossibile monitorare la cartella %x.</target> +<target>Impossibile monitorare la directory %x.</target> <source>Conversion error:</source> <target>Errore di conversione:</target> @@ -1417,7 +1428,7 @@ Questo garantisce uno stato consistente anche in caso di errore grave. <target>Impossibile spostare il file %x in %y.</target> <source>Cannot delete directory %x.</source> -<target>Impossibile eliminare la cartella %x.</target> +<target>Impossibile eliminare la directory %x.</target> <source>Cannot write file attributes of %x.</source> <target>Impossibile scrivere gli attributi del file %x.</target> diff --git a/FreeFileSync/Build/Languages/japanese.lng b/FreeFileSync/Build/Languages/japanese.lng index f32e722b..986db701 100644 --- a/FreeFileSync/Build/Languages/japanese.lng +++ b/FreeFileSync/Build/Languages/japanese.lng @@ -88,18 +88,18 @@ <source>Any number of alternative directories for at most one config file.</source> <target>ひとつの構成設定ファイルに対して任意の数の代替ディレクトリ.</target> -<source>A folder input field is empty.</source> -<target>フォルダ入力欄が空白です.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>対応するフォルダは空であるとみなされます</target> - <source>Cannot find the following folders:</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>A folder input field is empty.</source> +<target>フォルダ入力欄が空白です.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>対応するフォルダは空であるとみなされます</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>以下のフォルダには、依存関係にあるパスが存在します。同期規則を設定する時は慎重に行ってください:</target> @@ -220,17 +220,23 @@ <source>Cannot get process information.</source> <target>プロセス情報を取得できません.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>待機時間中ディレクトリはロックされます(%x)...</target> +<source>Waiting while directory is locked:</source> +<target>ディレクトリのロックを待機中:</target> + +<source>Lock owner:</source> +<target>ロック所有者:</target> <source> <pluralform>1 sec</pluralform> <pluralform>%x sec</pluralform> </source> <target> -<pluralform>%x 秒.</pluralform> +<pluralform>%x 秒</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>放棄されたロックを検出中...</target> + <source>Creating file %x</source> <target>ファイル %x を作成中</target> @@ -483,6 +489,12 @@ The command is triggered if: <source>Updating attributes of %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>Cannot find %x.</source> <target>%x が見つかりません</target> @@ -522,12 +534,6 @@ The command is triggered if: <source>Generating database...</source> <target>データベースを作成中...</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> @@ -569,13 +575,14 @@ The command is triggered if: <pluralform>Automatic retry in %x seconds...</pluralform> </source> <target> +<pluralform>%x 秒後に自動的に再試行...</pluralform> </target> <source>&Ignore subsequent errors</source> <target>以降のエラーは無視する(&I)</target> <source>Retrying operation...</source> -<target></target> +<target>処理を再試行中...</target> <source>Serious Error</source> <target>重大なエラー</target> @@ -602,7 +609,7 @@ The command is triggered if: <target>現在の FreeFileSync バージョン番号を確認できませんでした、手動で確認しますか?</target> <source>&Check</source> -<target></target> +<target>チェック(&C)</target> <source>Symlink</source> <target>シンボリックリンク</target> @@ -760,12 +767,6 @@ The command is triggered if: <source>Save as batch job</source> <target>一括ジョブで保存</target> -<source>Hide excluded items</source> -<target>除外対象項目を隠す</target> - -<source>Show filtered or temporarily excluded files</source> -<target>フィルター済、または一時除外ファイルを表示</target> - <source>Number of files and folders that will be created</source> <target>作成されたファイル、およびフォルダの数</target> @@ -776,7 +777,7 @@ The command is triggered if: <target>削除されたファイル、およびフォルダの数</target> <source>Total bytes to copy</source> -<target>コピーする合計バイト</target> +<target>コピーの合計バイト</target> <source>Select a variant:</source> <target>メソッドを選択:</target> @@ -797,13 +798,13 @@ The command is triggered if: <target>OK</target> <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> -<target>変更箇所を識別して両側に変更を反映します。データベースを使用することで、削除、移動および競合などが自動的に検出されます。</target> +<target>変更箇所を識別して両側に変更を反映します。データベースを使用することで、削除/移動/競合などは自動的に検出されます。</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>同意処理後、右側フォルダと厳密に合致する左側フォルダのミラーバックアップを作成</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>右側フォルダにマッチングを適合することで、左側フォルダのミラーリングバックアップを作成します。</target> <source>Copy new and updated files to the right folder.</source> -<target>新しい、または更新されたファイルを右フォルダにコピー</target> +<target>新しい、または更新されたファイルを右側フォルダにコピーします。</target> <source>Configure your own synchronization rules.</source> <target>あなたの設定した同期規則を使用します。</target> @@ -811,8 +812,16 @@ The command is triggered if: <source>Detect moved files</source> <target>移動済みのファイルを検出する</target> -<source>Requires database files. Not supported by all file systems.</source> -<target>データベースファイルが必要です(すべてのシステムには未対応).</target> +<source> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- データベースファイルの作成と要求 +- 初期同期後にアクティブを検出 +- すべてのファイルシステムには非対応 +</target> <source>Delete files:</source> <target>ファイルの削除:</target> @@ -830,7 +839,7 @@ The command is triggered if: <target>ファイルを削除/上書きする時、ゴミ箱にバックアップをとる</target> <source>Versioning</source> -<target>バージョン付け</target> +<target>バージョン管理</target> <source>Move files to a user-defined folder</source> <target>ユーザ定義のフォルダにファイルを移動</target> @@ -1048,6 +1057,9 @@ This guarantees a consistent state even in case of a serious error. <source>Find</source> <target>検索</target> +<source>Select View</source> +<target>表示を選択</target> + <source>Overview</source> <target>概要</target> @@ -1057,12 +1069,6 @@ This guarantees a consistent state even in case of a serious error. <source>Main Bar</source> <target>メインバー</target> -<source>Filter Files</source> -<target>ファイルフィルター</target> - -<source>Select View</source> -<target>表示を選択</target> - <source>Open...</source> <target>開く...</target> @@ -1089,6 +1095,7 @@ This guarantees a consistent state even in case of a serious error. <pluralform>Do you really want to execute the command %y for %x items?</pluralform> </source> <target> +<pluralform>本当にコマンド %y を項目 %x に対して実行しますか?</pluralform> </target> <source>&Execute</source> @@ -1111,11 +1118,11 @@ This guarantees a consistent state even in case of a serious error. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>%y / %x 行(表示内)</pluralform> +<pluralform>%x 行の内 %y 行を表示</pluralform> </target> <source>Set direction:</source> @@ -1232,6 +1239,9 @@ This guarantees a consistent state even in case of a serious error. <source>Show files that won't be copied</source> <target>コピーされなかったファイルを表示</target> +<source>Show filtered or temporarily excluded files</source> +<target>フィルター済、または一時除外ファイルを表示</target> + <source>Set as default</source> <target>デフォルトにセット</target> @@ -1268,6 +1278,9 @@ This guarantees a consistent state even in case of a serious error. <source>Warning</source> <target>警告</target> +<source>Select all</source> +<target>すべて選択</target> + <source>Paused</source> <target>一時停止中</target> @@ -1460,7 +1473,7 @@ This guarantees a consistent state even in case of a serious error. <pluralform>%x min</pluralform> </source> <target> -<pluralform>%x 分.</pluralform> +<pluralform>%x 分</pluralform> </target> <source> diff --git a/FreeFileSync/Build/Languages/korean.lng b/FreeFileSync/Build/Languages/korean.lng index 999dc5b1..81717d0b 100644 --- a/FreeFileSync/Build/Languages/korean.lng +++ b/FreeFileSync/Build/Languages/korean.lng @@ -7,6 +7,9 @@ <plural_definition>0</plural_definition> </header> +<source>MyButton</source> +<target></target> + <source>Both sides have changed since last synchronization.</source> <target>마지막 동기화 작업 이후, 양측 모두 변경 되었습니다.</target> @@ -88,18 +91,18 @@ <source>Any number of alternative directories for at most one config file.</source> <target>최대 한개 설정파일에 대한 대체 디렉토리 개수</target> -<source>A folder input field is empty.</source> -<target>폴더 입력 필드 하나가 비어 있습니다.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>해당 폴더를 비어 있는 상태로 간주합니다.</target> - <source>Cannot find the following folders:</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>A folder input field is empty.</source> +<target>폴더 입력 필드 하나가 비어 있습니다.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>해당 폴더를 비어 있는 상태로 간주합니다.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>다음 폴더들에는 종속 경로가 있습니다. 동기화 규칙을 설정 시 주의하시기 바랍니다:</target> @@ -220,8 +223,11 @@ <source>Cannot get process information.</source> <target>프로세스 정보를 얻을 수 없습니다.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>디렉토리 잠금 대기 중 (%x)...</target> +<source>Waiting while directory is locked:</source> +<target>디렉토리 잠금 대기 중:</target> + +<source>Lock owner:</source> +<target>잠금 권한자:</target> <source> <pluralform>1 sec</pluralform> @@ -231,6 +237,9 @@ <pluralform>%x초</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>방치된 잠금 탐색 중...</target> + <source>Creating file %x</source> <target>파일 %x 생성 중</target> @@ -483,6 +492,12 @@ The command is triggered if: <source>Updating attributes of %x</source> <target>%x 속성 업데이트 중</target> +<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> + <source>Cannot find %x.</source> <target>%x을(를) 찾을 수 없습니다.</target> @@ -522,12 +537,6 @@ The command is triggered if: <source>Generating database...</source> <target>데이터베이스 생성 중...</target> -<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> - <source>job name</source> <target>작업 이름</target> @@ -576,7 +585,7 @@ The command is triggered if: <target>이후 오류 무시(&I)</target> <source>Retrying operation...</source> -<target></target> +<target>작업 재시도 중...</target> <source>Serious Error</source> <target>심각한 오류</target> @@ -603,7 +612,7 @@ The command is triggered if: <target>현재 사용 중인 FreeFileSync 버전 번호를 온라인에서 찾을 수 없습니다. 수동으로 확인해 보시겠습니까?</target> <source>&Check</source> -<target></target> +<target>체크(&C)</target> <source>Symlink</source> <target>심링크</target> @@ -761,12 +770,6 @@ The command is triggered if: <source>Save as batch job</source> <target>일괄 작업으로 저장</target> -<source>Hide excluded items</source> -<target>제외 항목 숨기기</target> - -<source>Show filtered or temporarily excluded files</source> -<target>필터링 또는 일시적으로 제외된 파일 보이기</target> - <source>Number of files and folders that will be created</source> <target>생성될 파일 및 폴더 개수</target> @@ -800,8 +803,8 @@ The command is triggered if: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>양측 변경사항을 확인하고 전달. 삭제, 이동 및 충돌은 데이터베이스를 통해 자동으로 감지됩니다.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>좌측 폴더 백업 미러 생성: 동기화 이후 좌측 및 우측 폴더는 완전히 똑같이 매치 됩니다.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>좌측 폴더의 미러 백업을 만듭니다. 우측 폴더는 좌측 폴더와 완전히 일치하게 됩니다.</target> <source>Copy new and updated files to the right folder.</source> <target>신규 또는 업데이트 된 파일을 우측 폴더로 복사</target> @@ -812,8 +815,16 @@ The command is triggered if: <source>Detect moved files</source> <target>이동 파일 탐지</target> -<source>Requires database files. Not supported by all file systems.</source> -<target>데이터베이스 파일이 필요합니다. 모든 파일 시스템에서 지원되지는 않습니다.</target> +<source> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- 데이터베이스 파일 필요 및 생성 +- 초기 동기화 이후 탐지기능 활성화 +- 모든 파일 시스템에서 지원되지 않음 +</target> <source>Delete files:</source> <target>파일 삭제:</target> @@ -825,7 +836,7 @@ The command is triggered if: <target>파일 영구 삭제 또는 덮어쓰기</target> <source>Recycle bin</source> -<target></target> +<target>휴지통</target> <source>Back up deleted and overwritten files in the recycle bin</source> <target>휴지통에 삭제되고 덮어 씌어진 파일 백업</target> @@ -1049,6 +1060,9 @@ This guarantees a consistent state even in case of a serious error. <source>Find</source> <target>검색</target> +<source>Select View</source> +<target>보기 선택</target> + <source>Overview</source> <target>개요</target> @@ -1058,12 +1072,6 @@ This guarantees a consistent state even in case of a serious error. <source>Main Bar</source> <target>메인 바</target> -<source>Filter Files</source> -<target>파일 필터</target> - -<source>Select View</source> -<target>보기 선택</target> - <source>Open...</source> <target>열기</target> @@ -1113,11 +1121,11 @@ This guarantees a consistent state even in case of a serious error. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>보기에 나타난 %x 행의 %y</pluralform> +<pluralform>%x 행의 %y 표시</pluralform> </target> <source>Set direction:</source> @@ -1184,10 +1192,10 @@ This guarantees a consistent state even in case of a serious error. <target>%x의 변경사항을 저장하시겠습니까?</target> <source>Never save &changes</source> -<target>변경사항을 절대 저장하기 않기(&c)</target> +<target>변경사항 저장 안 함(&c)</target> <source>Do&n't save</source> -<target>저장하기 않기(&n)</target> +<target>저장 안 함(&n)</target> <source>Filter</source> <target>필터</target> @@ -1234,6 +1242,9 @@ This guarantees a consistent state even in case of a serious error. <source>Show files that won't be copied</source> <target>복사되지 않을 파일 표시</target> +<source>Show filtered or temporarily excluded files</source> +<target>필터링 또는 일시적으로 제외된 파일 보이기</target> + <source>Set as default</source> <target>기본 값으로 설정</target> @@ -1270,6 +1281,9 @@ This guarantees a consistent state even in case of a serious error. <source>Warning</source> <target>경고</target> +<source>Select all</source> +<target>모두 선택</target> + <source>Paused</source> <target>일시정지 중</target> diff --git a/FreeFileSync/Build/Languages/outdated/lithuanian.lng b/FreeFileSync/Build/Languages/outdated/lithuanian.lng index f4c49c2a..19977128 100644 --- a/FreeFileSync/Build/Languages/outdated/lithuanian.lng +++ b/FreeFileSync/Build/Languages/outdated/lithuanian.lng @@ -88,18 +88,18 @@ <source>Any number of alternative directories for at most one config file.</source> <target>Daugiausia vienam config failui, n alternatyvių katalogų</target> -<source>A folder input field is empty.</source> -<target>Aplanko įvesties laukas yra tuščias.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>Atitinkamas aplankas bus laikomas tuščiu.</target> - <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>A folder input field is empty.</source> +<target>Aplanko įvesties laukas yra tuščias.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>Atitinkamas aplankas bus laikomas tuščiu.</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> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>Nepavyksta gauti eigos informacijos.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Laikiama kol katalogas bus užrakintas (%x)...</target> +<source>Waiting while directory is locked:</source> +<target></target> + +<source>Lock owner:</source> +<target></target> <source> <pluralform>1 sec</pluralform> @@ -234,6 +237,9 @@ <pluralform>%x sek</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target></target> + <source>Creating file %x</source> <target>Kuriamas failas %x</target> @@ -250,8 +256,7 @@ <pluralform>1 byte</pluralform> <pluralform>%x bytes</pluralform> </source> -<target> -</target> +<target></target> <source>%x MB</source> <target>%x MB</target> @@ -275,8 +280,7 @@ <pluralform>1 thread</pluralform> <pluralform>%x threads</pluralform> </source> -<target> -</target> +<target></target> <source>Encoding extended time information: %x</source> <target>Koduojama išplėstinė laiko informacija: %x</target> @@ -484,6 +488,12 @@ Komanda inicijuojama jei: <source>Updating attributes of %x</source> <target>Atnaujinami atributai %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>Cannot find %x.</source> <target>Nepavyksta rasti %x.</target> @@ -523,12 +533,6 @@ Komanda inicijuojama jei: <source>Generating database...</source> <target>Generuojama duomenų bazė...</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> @@ -569,8 +573,7 @@ Komanda inicijuojama jei: <pluralform>Automatic retry in 1 second...</pluralform> <pluralform>Automatic retry in %x seconds...</pluralform> </source> -<target> -</target> +<target></target> <source>&Ignore subsequent errors</source> <target></target> @@ -761,12 +764,6 @@ Komanda inicijuojama jei: <source>Save as batch job</source> <target>Išsaugoti kaip paketinį darbą</target> -<source>Hide excluded items</source> -<target>Slėpti išskirtus elementus</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Rodyti išfiltruotus ar laikinai išskirtus failus</target> - <source>Number of files and folders that will be created</source> <target>Failų ir aplankų, kurie bus sukurti, skaičius</target> @@ -800,7 +797,7 @@ Komanda inicijuojama jei: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Nustatyti ir skatinti pokyčius apbiejose pusėse. Trinimai, perkėlimai ir konfliktai yra aptinkami automatiškai naudojant duomenų bazę.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> <target></target> <source>Copy new and updated files to the right folder.</source> @@ -812,8 +809,12 @@ Komanda inicijuojama jei: <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> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target></target> <source>Delete files:</source> <target></target> @@ -1046,6 +1047,9 @@ This guarantees a consistent state even in case of a serious error. <source>Find</source> <target>Rasti</target> +<source>Select View</source> +<target></target> + <source>Overview</source> <target>Apžvalga</target> @@ -1055,12 +1059,6 @@ This guarantees a consistent state even in case of a serious error. <source>Main Bar</source> <target></target> -<source>Filter Files</source> -<target></target> - -<source>Select View</source> -<target></target> - <source>Open...</source> <target>Atverti...</target> @@ -1086,8 +1084,7 @@ This guarantees a consistent state even in case of a serious error. <pluralform>Do you really want to execute the command %y for one item?</pluralform> <pluralform>Do you really want to execute the command %y for %x items?</pluralform> </source> -<target> -</target> +<target></target> <source>&Execute</source> <target></target> @@ -1115,11 +1112,10 @@ This guarantees a consistent state even in case of a serious error. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> -<target> -</target> +<target></target> <source>Set direction:</source> <target>Nustatyti kryptį:</target> @@ -1235,6 +1231,9 @@ This guarantees a consistent state even in case of a serious error. <source>Show files that won't be copied</source> <target>Rodyti failus, kurie ne bus kopijuojami</target> +<source>Show filtered or temporarily excluded files</source> +<target>Rodyti išfiltruotus ar laikinai išskirtus failus</target> + <source>Set as default</source> <target>Nustatyti kaip numatytą</target> @@ -1271,6 +1270,9 @@ This guarantees a consistent state even in case of a serious error. <source>Warning</source> <target>Perspėjimas</target> +<source>Select all</source> +<target></target> + <source>Paused</source> <target>Pristabdyta</target> diff --git a/FreeFileSync/Build/Languages/outdated/norwegian.lng b/FreeFileSync/Build/Languages/outdated/norwegian.lng index 86192770..6d1fe635 100644 --- a/FreeFileSync/Build/Languages/outdated/norwegian.lng +++ b/FreeFileSync/Build/Languages/outdated/norwegian.lng @@ -88,18 +88,18 @@ <source>Any number of alternative directories for at most one config file.</source> <target></target> -<source>A folder input field is empty.</source> -<target>Et mappefelt er tomt.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target></target> - <source>Cannot find the following folders:</source> <target>Kan ikke finne følgende mapper:</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>A folder input field is empty.</source> +<target>Et mappefelt er tomt.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target></target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target></target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>Kan ikke hente prosessinformasjon.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Venter mens mappe er låst (%x)...</target> +<source>Waiting while directory is locked:</source> +<target></target> + +<source>Lock owner:</source> +<target></target> <source> <pluralform>1 sec</pluralform> @@ -232,6 +235,9 @@ <pluralform>%x sekunder</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target></target> + <source>Creating file %x</source> <target>Oppretter fil %x</target> @@ -248,8 +254,7 @@ <pluralform>1 byte</pluralform> <pluralform>%x bytes</pluralform> </source> -<target> -</target> +<target></target> <source>%x MB</source> <target>%x MB</target> @@ -273,8 +278,7 @@ <pluralform>1 thread</pluralform> <pluralform>%x threads</pluralform> </source> -<target> -</target> +<target></target> <source>Encoding extended time information: %x</source> <target>Koder utvided tidsinformasjon: %x</target> @@ -482,6 +486,12 @@ Kommandoen utløses hvis: <source>Updating attributes of %x</source> <target>Oppdaterer attributter til %x</target> +<source>Creating a Volume Shadow Copy for %x...</source> +<target></target> + +<source>Data verification error: %x and %y have different content.</source> +<target></target> + <source>Cannot find %x.</source> <target>Kan ikke finne %x.</target> @@ -521,12 +531,6 @@ Kommandoen utløses hvis: <source>Generating database...</source> <target>Oppretter database...</target> -<source>Creating a Volume Shadow Copy for %x...</source> -<target></target> - -<source>Data verification error: %x and %y have different content.</source> -<target></target> - <source>job name</source> <target></target> @@ -567,8 +571,7 @@ Kommandoen utløses hvis: <pluralform>Automatic retry in 1 second...</pluralform> <pluralform>Automatic retry in %x seconds...</pluralform> </source> -<target> -</target> +<target></target> <source>&Ignore subsequent errors</source> <target></target> @@ -759,12 +762,6 @@ Kommandoen utløses hvis: <source>Save as batch job</source> <target>Lagre som sammensatt oppgave</target> -<source>Hide excluded items</source> -<target>Skjul ekskluderte elementer</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Vis filtrerte eller midlertidig ekskluderte filer</target> - <source>Number of files and folders that will be created</source> <target>Antall filer og mapper som vil opprettes</target> @@ -798,7 +795,7 @@ Kommandoen utløses hvis: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target></target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> <target></target> <source>Copy new and updated files to the right folder.</source> @@ -810,7 +807,11 @@ Kommandoen utløses hvis: <source>Detect moved files</source> <target></target> -<source>Requires database files. Not supported by all file systems.</source> +<source> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> <target></target> <source>Delete files:</source> @@ -1044,6 +1045,9 @@ This guarantees a consistent state even in case of a serious error. <source>Find</source> <target>Søk</target> +<source>Select View</source> +<target></target> + <source>Overview</source> <target>Oversikt</target> @@ -1053,12 +1057,6 @@ This guarantees a consistent state even in case of a serious error. <source>Main Bar</source> <target></target> -<source>Filter Files</source> -<target></target> - -<source>Select View</source> -<target></target> - <source>Open...</source> <target>Åpne...</target> @@ -1084,8 +1082,7 @@ This guarantees a consistent state even in case of a serious error. <pluralform>Do you really want to execute the command %y for one item?</pluralform> <pluralform>Do you really want to execute the command %y for %x items?</pluralform> </source> -<target> -</target> +<target></target> <source>&Execute</source> <target></target> @@ -1109,11 +1106,10 @@ This guarantees a consistent state even in case of a serious error. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> -<target> -</target> +<target></target> <source>Set direction:</source> <target>Still inn retningen:</target> @@ -1229,6 +1225,9 @@ This guarantees a consistent state even in case of a serious error. <source>Show files that won't be copied</source> <target>Vis filer som ikke blir kopiert</target> +<source>Show filtered or temporarily excluded files</source> +<target>Vis filtrerte eller midlertidig ekskluderte filer</target> + <source>Set as default</source> <target>Set som standard</target> @@ -1265,6 +1264,9 @@ This guarantees a consistent state even in case of a serious error. <source>Warning</source> <target>Advarsel</target> +<source>Select all</source> +<target></target> + <source>Paused</source> <target>Pauset</target> @@ -1311,8 +1313,7 @@ This guarantees a consistent state even in case of a serious error. <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> +<target></target> <source>Move</source> <target></target> @@ -1321,8 +1322,7 @@ This guarantees a consistent state even in case of a serious error. <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>Exclude</source> <target>Ekskluder</target> diff --git a/FreeFileSync/Build/Languages/polish.lng b/FreeFileSync/Build/Languages/polish.lng index 63fff3f2..e4f5b3ac 100644 --- a/FreeFileSync/Build/Languages/polish.lng +++ b/FreeFileSync/Build/Languages/polish.lng @@ -88,18 +88,18 @@ <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>A folder input field is empty.</source> -<target>Pole katalog źródłowy jest puste.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>Katalog będzie oznaczony jako pusty.</target> - <source>Cannot find the following folders:</source> <target>Nie można znaleźć następujących katalogów:</target> <source>You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.</source> <target>Możesz zignorować ten błąd aby uznając katalogi jako puste. Katalog zostanie utworzony automatycznie podczas synchronizacji.</target> +<source>A folder input field is empty.</source> +<target>Pole katalog źródłowy jest puste.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>Katalog będzie oznaczony jako pusty.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>Podane katalogi mają zależne ścieżki. Bądź ostrożny podczas ustawiania reguł synchronizacji:</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>Nie można uzyskać informacji dla procesu.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Blokada katalogu (%x), oczekiwanie...</target> +<source>Waiting while directory is locked:</source> +<target>Oczekiwanie przez blokadę katalogu:</target> + +<source>Lock owner:</source> +<target>Właściciel blokady:</target> <source> <pluralform>1 sec</pluralform> @@ -233,6 +236,9 @@ <pluralform>%x sekund</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>Wykrywanie nieaktywnej blokady...</target> + <source>Creating file %x</source> <target>Tworzenie pliku %x</target> @@ -386,7 +392,7 @@ <target>Czas pomiędzy ostatnią wykrytą zmianą, a uruchomieniem komendy</target> <source>Command line:</source> -<target>Linia komend:</target> +<target>Polecenie:</target> <source> The command is triggered if: @@ -489,6 +495,12 @@ Komenda jest wykonywana gdy: <source>Updating attributes of %x</source> <target>Aktualizowanie atrybutów %x</target> +<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>Cannot find %x.</source> <target>Nie można znaleźć %x.</target> @@ -528,12 +540,6 @@ Komenda jest wykonywana gdy: <source>Generating database...</source> <target>Generowanie bazy danych...</target> -<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> @@ -575,13 +581,16 @@ Komenda jest wykonywana gdy: <pluralform>Automatic retry in %x seconds...</pluralform> </source> <target> +<pluralform>Automatyczne ponowienie za 1 sekundę...</pluralform> +<pluralform>Automatyczne ponowienie za %x sekundy...</pluralform> +<pluralform>Automatyczne ponowienie za %x sekund...</pluralform> </target> <source>&Ignore subsequent errors</source> <target>&Ignoruj kolejne błędy</target> <source>Retrying operation...</source> -<target></target> +<target>Ponawianie operacji...</target> <source>Serious Error</source> <target>Poważny błąd</target> @@ -608,7 +617,7 @@ Komenda jest wykonywana gdy: <target>Nie można znaleźć obecnej wersji FreeFileSync. Czy chcesz sprawdzić ręcznie?</target> <source>&Check</source> -<target></target> +<target>S&prawdź</target> <source>Symlink</source> <target>Dowiązanie symboliczne</target> @@ -766,12 +775,6 @@ Komenda jest wykonywana gdy: <source>Save as batch job</source> <target>Zapisz w trybie wsadowym</target> -<source>Hide excluded items</source> -<target>Ukryj wykluczone elementy</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Pokaż pliki wykluczone tymczasowo lub pliki wykluczone tymczasowo</target> - <source>Number of files and folders that will be created</source> <target>Liczba plików i katalogów, które zostaną utworzone</target> @@ -805,8 +808,8 @@ Komenda jest wykonywana gdy: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Wyszukaj oraz zastosuj zmiany po obu stronach. Wszystkie operacje na plikach takie jak usunięcia, zmiany oraz konflikty wykrywane są automatycznie przy użyciu bazy danych.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>Kopia lustrzana lewego katalogu. Po synchronizacji, zawartość prawego katalogu będzie będzie identyczna jak w lewym katalogu.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>Utwórz lustrzaną kopię lewego katalogu. Cała zawartość prawego katalogu będzie usunięta bądź nadpisana zawartością lewego katalogu.</target> <source>Copy new and updated files to the right folder.</source> <target>Kopiuj nowe i zmodyfikowane pliki do prawego katalogu.</target> @@ -817,8 +820,16 @@ Komenda jest wykonywana gdy: <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> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Wymagane utworzenie pliku bazy danych +- Funkcja aktywna po pierwszej synchronizacji +- Niewspierany przez wszystkie systemy plików +</target> <source>Delete files:</source> <target>Usuwanie plików:</target> @@ -887,7 +898,7 @@ Komenda jest wykonywana gdy: <target>Do ukończenia:</target> <source>Time elapsed:</source> -<target>Szacowany czas:</target> +<target>Upłynęło:</target> <source>Synchronizing...</source> <target>Synchronizuję...</target> @@ -905,7 +916,7 @@ Komenda jest wykonywana gdy: <target>Przerwij</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> +<target>Utwórz plik wsadowy do zautomatyzowania procesu synchronizacji. Aby rozpocząć, klknij dwa razy plik lub zaplanuj zadanie w harmonogramie zadań: %x</target> <source>Stop synchronization at first error</source> <target>Przerwij synchronizację przy pierwszym błędzie</target> @@ -1054,6 +1065,9 @@ program kopiuje zawartość do pliku tymczasowego (*.ffs_tmp), a następnie nadp <source>Find</source> <target>Znajdź</target> +<source>Select View</source> +<target>Widok</target> + <source>Overview</source> <target>Przegląd</target> @@ -1063,12 +1077,6 @@ program kopiuje zawartość do pliku tymczasowego (*.ffs_tmp), a następnie nadp <source>Main Bar</source> <target>Główny pasek</target> -<source>Filter Files</source> -<target>Filtr</target> - -<source>Select View</source> -<target>Widok</target> - <source>Open...</source> <target>Otwórz...</target> @@ -1095,6 +1103,9 @@ program kopiuje zawartość do pliku tymczasowego (*.ffs_tmp), a następnie nadp <pluralform>Do you really want to execute the command %y for %x items?</pluralform> </source> <target> +<pluralform>Czy na pewno wykonać polecenie %y dla jednego elementu?</pluralform> +<pluralform>Czy na pewno wykonać polecenie %y dla jednego %x elementów?</pluralform> +<pluralform>Czy na pewno wykonać polecenie %y dla jednego %x elementów?</pluralform> </target> <source>&Execute</source> @@ -1121,13 +1132,13 @@ program kopiuje zawartość do pliku tymczasowego (*.ffs_tmp), a następnie nadp </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>Widok %y z 1 lini</pluralform> -<pluralform>Widok %y z %x lini</pluralform> -<pluralform>Widok %y z %x lini</pluralform> +<pluralform>Widok %y z 1 wiersza</pluralform> +<pluralform>Widok %y z %x wierszy</pluralform> +<pluralform>Widok %y z %x wierszy</pluralform> </target> <source>Set direction:</source> @@ -1244,6 +1255,9 @@ program kopiuje zawartość do pliku tymczasowego (*.ffs_tmp), a następnie nadp <source>Show files that won't be copied</source> <target>Pokaż pliki, które nie będą kopiowane</target> +<source>Show filtered or temporarily excluded files</source> +<target>Pokaż pliki wykluczone tymczasowo lub pliki wykluczone tymczasowo</target> + <source>Set as default</source> <target>Zapisz jako domyślne</target> @@ -1280,6 +1294,9 @@ program kopiuje zawartość do pliku tymczasowego (*.ffs_tmp), a następnie nadp <source>Warning</source> <target>Ostrzeżenie</target> +<source>Select all</source> +<target>Zaznacz wszystko</target> + <source>Paused</source> <target>Pauza</target> diff --git a/FreeFileSync/Build/Languages/portuguese.lng b/FreeFileSync/Build/Languages/portuguese.lng index 0c26ef2f..cb53257b 100644 --- a/FreeFileSync/Build/Languages/portuguese.lng +++ b/FreeFileSync/Build/Languages/portuguese.lng @@ -88,18 +88,18 @@ <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>A folder input field is empty.</source> -<target>Um dos campos de directório para comparar está vazio.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>A pasta correspondente será considerada como vazia.</target> - <source>Cannot find the following folders:</source> <target>Não é possível encontrar as seguintes pastas:</target> <source>You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.</source> <target>Pode ignorar este erro para considerar cada pasta como vazia. As pastas necessárias serão criadas automaticamente durante a sincronização.</target> +<source>A folder input field is empty.</source> +<target>Um dos campos de directório para comparar está vazio.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>A pasta correspondente será considerada como vazia.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>As seguintes pastas têm caminhos dependentes. Tenha atenção ao definir as regras de sincronizaçção:</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>Não é possível obter informação sobre o processo.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Aguardar enquanto o directório é bloqueado (%x)...</target> +<source>Waiting while directory is locked:</source> +<target>À espera do bloqueio do directório:</target> + +<source>Lock owner:</source> +<target>Dono do bloqueio:</target> <source> <pluralform>1 sec</pluralform> @@ -232,6 +235,9 @@ <pluralform>%x segs</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>Detectado bloqueio abandonado...</target> + <source>Creating file %x</source> <target>Criar ficheiro %x</target> @@ -486,6 +492,12 @@ O comando é executado se: <source>Updating attributes of %x</source> <target>Actualizar atributos de %x</target> +<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>Cannot find %x.</source> <target>Não é possível encontrar %x.</target> @@ -525,12 +537,6 @@ O comando é executado se: <source>Generating database...</source> <target>A gerar base de dados...</target> -<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> @@ -580,7 +586,7 @@ O comando é executado se: <target>&Ignorar erros subsequentes</target> <source>Retrying operation...</source> -<target></target> +<target>A repetir a operação...</target> <source>Serious Error</source> <target>Erro Grave</target> @@ -607,7 +613,7 @@ O comando é executado se: <target>Não é possível encontrar a última versão do FreeFileSync online. Deseja verificar manualmente?</target> <source>&Check</source> -<target></target> +<target>&Verificar</target> <source>Symlink</source> <target>Link Simbólico</target> @@ -765,12 +771,6 @@ O comando é executado se: <source>Save as batch job</source> <target>Guardar como batch</target> -<source>Hide excluded items</source> -<target>Esconder itens excluídos</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Mostrar ficheiros filtrados ou temporariamente excluidos</target> - <source>Number of files and folders that will be created</source> <target>Número de ficheiros e pastas a ser criados</target> @@ -804,8 +804,8 @@ O comando é executado se: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Identificar e propagar mudanças nos dois lados. Eliminações, cópias e conflitos são detectados automaticamente usando base de dados.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>Criar uma cópia exacta da pasta à esquerda, que vai corresponder à pasta da direita após a sincronização.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>Criar uma cópia exacta da pasta à esquerda, adaptando a da direita para coincidir.</target> <source>Copy new and updated files to the right folder.</source> <target>Copiar ficheiros novos e actualizados para a pasta à direita.</target> @@ -816,8 +816,16 @@ O comando é executado se: <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> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Requer o uso de base de dados (cria ficheiro) +- Detecção activa após sincronização inicial +- Não é suportado por todos os sistemas de ficheiros +</target> <source>Delete files:</source> <target>Eliminar ficheiros:</target> @@ -1053,6 +1061,9 @@ Isto garante um estado consistente mesmo em caso de falha grave. <source>Find</source> <target>Procurar</target> +<source>Select View</source> +<target>Seleccionar Vista</target> + <source>Overview</source> <target>Vista</target> @@ -1062,12 +1073,6 @@ Isto garante um estado consistente mesmo em caso de falha grave. <source>Main Bar</source> <target>Barra principal</target> -<source>Filter Files</source> -<target>Filtrar Ficheiros</target> - -<source>Select View</source> -<target>Seleccionar Vista</target> - <source>Open...</source> <target>Abrir...</target> @@ -1120,12 +1125,12 @@ Isto garante um estado consistente mesmo em caso de falha grave. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>%y de 1 linha em vista</pluralform> -<pluralform>%y de %x linhas em vista</pluralform> +<pluralform>A mostrar %y de 1 linha</pluralform> +<pluralform>A mostrar %y de %x linhas</pluralform> </target> <source>Set direction:</source> @@ -1242,6 +1247,9 @@ Isto garante um estado consistente mesmo em caso de falha grave. <source>Show files that won't be copied</source> <target>Mostrar ficheiros que não serão copiados</target> +<source>Show filtered or temporarily excluded files</source> +<target>Mostrar ficheiros filtrados ou temporariamente excluidos</target> + <source>Set as default</source> <target>Definir como padrão</target> @@ -1278,6 +1286,9 @@ Isto garante um estado consistente mesmo em caso de falha grave. <source>Warning</source> <target>Atenção</target> +<source>Select all</source> +<target>Seleccionar tudo</target> + <source>Paused</source> <target>Em pausa</target> diff --git a/FreeFileSync/Build/Languages/portuguese_br.lng b/FreeFileSync/Build/Languages/portuguese_br.lng index f58606f8..79795af2 100644 --- a/FreeFileSync/Build/Languages/portuguese_br.lng +++ b/FreeFileSync/Build/Languages/portuguese_br.lng @@ -88,18 +88,18 @@ <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>A folder input field is empty.</source> -<target>Um campo de entrada de pasta está vazio.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>A pasta correspondente será considerada como vazia.</target> - <source>Cannot find the following folders:</source> <target>Não foi possível localizar as seguintes pastas:</target> <source>You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.</source> <target>Você pode ignorar este erro para considerar cada pasta como vazia. As pastas serão criadas automaticamentes durante a sincronização.</target> +<source>A folder input field is empty.</source> +<target>Um campo de entrada de pasta está vazio.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>A pasta correspondente será considerada como vazia.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>As seguintes pastas tem caminhos dependentes. Cuidado na hora de estabelecer as regras de sincronização:</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>Não foi possível obter as informações do processo.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Esperando enquanto o diretório é bloqueado (%x)...</target> +<source>Waiting while directory is locked:</source> +<target>Aguardando enquanto o diretório é travado:</target> + +<source>Lock owner:</source> +<target>Proprietário:</target> <source> <pluralform>1 sec</pluralform> @@ -232,6 +235,9 @@ <pluralform>%x segs</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>Detectando travamento abandonado...</target> + <source>Creating file %x</source> <target>Criando arquivo %x</target> @@ -486,6 +492,12 @@ O comando é disparado se: <source>Updating attributes of %x</source> <target>Atualizando atributos de %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>Cannot find %x.</source> <target>Não foi possível localizar %x.</target> @@ -525,12 +537,6 @@ O comando é disparado se: <source>Generating database...</source> <target>Gerando banco de dados...</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> @@ -580,7 +586,7 @@ O comando é disparado se: <target>&Ignorar erros subsequentes</target> <source>Retrying operation...</source> -<target></target> +<target>Tentando novamente a operação...</target> <source>Serious Error</source> <target>Erro Grave</target> @@ -607,7 +613,7 @@ O comando é disparado se: <target>Não foi possível encontrar a versão atual do FreeFileSync online. Deseja verificar manualmente?</target> <source>&Check</source> -<target></target> +<target>&Verificar</target> <source>Symlink</source> <target>Link Simbólico</target> @@ -765,12 +771,6 @@ O comando é disparado se: <source>Save as batch job</source> <target>Salvar como tarefa em lote</target> -<source>Hide excluded items</source> -<target>Ocultar itens excluídos</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Mostra arquivos que foram filtrados ou excluídos temporariamente</target> - <source>Number of files and folders that will be created</source> <target>Número de arquivos e pastas que serão criados</target> @@ -804,8 +804,8 @@ O comando é disparado se: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Identifica e propaga as mudanças em ambos os lados. Arquivos e pastas apagados e/ou movidos e conflitos são detectados automaticamente usando um banco de dados.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>Cria uma cópia espelho da pasta da esquerda que é exatamente igual à pasta da esquerda após a sincronização.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>Cria uma cópia espelho da pasta da esquerda adaptando a pasta da direita para igualar.</target> <source>Copy new and updated files to the right folder.</source> <target>Copia arquivos novos ou atualizados para a pasta da direita.</target> @@ -816,8 +816,16 @@ O comando é disparado se: <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> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Requer e cria arquivos de banco de dados +- Detecção ativa após sincronismo incial +- Não suportado por todos os sistemas de arquivo +</target> <source>Delete files:</source> <target>Apagar arquivos:</target> @@ -907,7 +915,7 @@ O comando é disparado se: <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>Stop synchronization at first error</source> -<target>Interromper sincronização ao primeiro erro</target> +<target>Interrompe a sincronização ao primeiro erro</target> <source>Show progress dialog</source> <target>Mostrar indicador de progresso</target> @@ -1053,6 +1061,9 @@ Isto garante um estado consistente mesmo em caso de erro grave. <source>Find</source> <target>Localizar</target> +<source>Select View</source> +<target>Selecionar Visualização</target> + <source>Overview</source> <target>Parâmetros</target> @@ -1062,12 +1073,6 @@ Isto garante um estado consistente mesmo em caso de erro grave. <source>Main Bar</source> <target>Barra Principal</target> -<source>Filter Files</source> -<target>Filtrar Arquivos</target> - -<source>Select View</source> -<target>Selecionar Visualização</target> - <source>Open...</source> <target>Abrir...</target> @@ -1120,12 +1125,12 @@ Isto garante um estado consistente mesmo em caso de erro grave. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>%y de 1 linha</pluralform> -<pluralform>%y de %x linhas</pluralform> +<pluralform>Mostrando %y de 1 coluna</pluralform> +<pluralform>Mostrando %y de %x colunas</pluralform> </target> <source>Set direction:</source> @@ -1242,6 +1247,9 @@ Isto garante um estado consistente mesmo em caso de erro grave. <source>Show files that won't be copied</source> <target>Mostrar arquivos que não serão copiados</target> +<source>Show filtered or temporarily excluded files</source> +<target>Mostra arquivos que foram filtrados ou excluídos temporariamente</target> + <source>Set as default</source> <target>Definir como padrão</target> @@ -1278,6 +1286,9 @@ Isto garante um estado consistente mesmo em caso de erro grave. <source>Warning</source> <target>Avisos</target> +<source>Select all</source> +<target>Seleciona todos</target> + <source>Paused</source> <target>Pausado</target> diff --git a/FreeFileSync/Build/Languages/romanian.lng b/FreeFileSync/Build/Languages/romanian.lng index 10ca0b53..a7f6b931 100644 --- a/FreeFileSync/Build/Languages/romanian.lng +++ b/FreeFileSync/Build/Languages/romanian.lng @@ -88,18 +88,18 @@ <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>A folder input field is empty.</source> -<target>Un cîmp de introducere a dosarului este gol.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>Dosarul corespondent va fi considerat ca fiind gol.</target> - <source>Cannot find the following folders:</source> <target>Nu pot găsi dosarele următoare:</target> <source>You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.</source> <target>Poți ignora această eroare dacă vrei ca ambele dosare să fie considerate goale. Dosarele vor fi apoi create automat în timpul sincronizării.</target> +<source>A folder input field is empty.</source> +<target>Un cîmp de introducere a dosarului este gol.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>Dosarul corespondent va fi considerat ca fiind gol.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>Dosarele următoare au căi dependente. Atenție la setarea regulilor de sincronizare:</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>Nu pot obține informații despre proces.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Aștept ca dosarul să fie zăvorît (%x)...</target> +<source>Waiting while directory is locked:</source> +<target>Aștept ca dosarul să fie zăvorît [locked]:</target> + +<source>Lock owner:</source> +<target>Zăvorăște proprietarul:</target> <source> <pluralform>1 sec</pluralform> @@ -233,6 +236,9 @@ <pluralform>%x de sec</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>Detectez zăvorîrea [lock] abandonată...</target> + <source>Creating file %x</source> <target>Creez fila %x</target> @@ -489,6 +495,12 @@ Comanda este declanșată dacă: <source>Updating attributes of %x</source> <target>Actualizez atributele lui %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>Cannot find %x.</source> <target>Nu pot găsi %x.</target> @@ -528,12 +540,6 @@ Comanda este declanșată dacă: <source>Generating database...</source> <target>Generez baza de date...</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> @@ -575,13 +581,16 @@ Comanda este declanșată dacă: <pluralform>Automatic retry in %x seconds...</pluralform> </source> <target> +<pluralform>Reîncercare automată în 1 secundă...</pluralform> +<pluralform>Reîncercare automată în %x secunde...</pluralform> +<pluralform>Reîncercare automată în %x de secunde...</pluralform> </target> <source>&Ignore subsequent errors</source> <target>&Ignoră erorile ulterioare</target> <source>Retrying operation...</source> -<target></target> +<target>Reîncerc operația...</target> <source>Serious Error</source> <target>Eroare Serioasă</target> @@ -608,7 +617,7 @@ Comanda este declanșată dacă: <target>Nu pot afla numărul versiunii FreeFileSync disponibile acum pe internet. Vrei să-l cauți manual?</target> <source>&Check</source> -<target></target> +<target>&Verifică</target> <source>Symlink</source> <target>Simlegătură</target> @@ -766,12 +775,6 @@ Comanda este declanșată dacă: <source>Save as batch job</source> <target>Salvează ca Sarcină Set</target> -<source>Hide excluded items</source> -<target>Ascunde elementele excluse</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Arată filele filtrate sau excluse temporar</target> - <source>Number of files and folders that will be created</source> <target>Numărul de file și dosare care vor fi create</target> @@ -803,10 +806,10 @@ Comanda este declanșată dacă: <target>OK</target> <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> -<target>Identificare și propagare a modificărilor din ambele părți. Ștergerile, renumirile și conflictele sînt detectate automat, folosind o bază de date.</target> +<target>Identifică și propagă modificările din ambele părți. Ștergerile, renumirile și conflictele sînt detectate automat, folosind o bază de date.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>Creează o conservare [backup] în oglindă a dosarului stîng care se potrivește exact cu dosarul drept după sincronizare.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>Creează o conservare [backup] în oglindă a dosarului stîng prin adaptarea dosarului drept pînă la potrivirea exactă cu cel stîng.</target> <source>Copy new and updated files to the right folder.</source> <target>Copiază filele noi și cele actualizate în dosarul drept.</target> @@ -817,8 +820,16 @@ Comanda este declanșată dacă: <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> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Solicită și creează file cu baze de date +- Detectare activă după sincronizarea inițială +- Nesuportat de toate sistemele de file +</target> <source>Delete files:</source> <target>Ștergerea Filelor:</target> @@ -830,7 +841,7 @@ Comanda este declanșată dacă: <target>Filele sînt șterse sau suprascrise în mod definitiv, fără a mai putea fi recuperate</target> <source>Recycle bin</source> -<target></target> +<target>Reciclator</target> <source>Back up deleted and overwritten files in the recycle bin</source> <target>Conservă [back up] în Reciclator filele șterse sau suprascrise</target> @@ -1054,6 +1065,9 @@ Aceasta garantează consecvența stării filelor chiar și în cazul apariției <source>Find</source> <target>Găsește</target> +<source>Select View</source> +<target>Selectează Vederea</target> + <source>Overview</source> <target>Panoramă</target> @@ -1063,12 +1077,6 @@ Aceasta garantează consecvența stării filelor chiar și în cazul apariției <source>Main Bar</source> <target>Bara Principală</target> -<source>Filter Files</source> -<target>Filtrează Filele</target> - -<source>Select View</source> -<target>Selectează Vederea</target> - <source>Open...</source> <target>Deschide...</target> @@ -1095,6 +1103,9 @@ Aceasta garantează consecvența stării filelor chiar și în cazul apariției <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 un item?</pluralform> +<pluralform>Sigur vrei să execuți comanda %y pentru %x itemuri?</pluralform> +<pluralform>Sigur vrei să execuți comanda %y pentru %x de itemuri?</pluralform> </target> <source>&Execute</source> @@ -1121,13 +1132,13 @@ Aceasta garantează consecvența stării filelor chiar și în cazul apariției </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>%y din 1 rînd afișat</pluralform> -<pluralform>%y din %x rînduri afișate</pluralform> -<pluralform>%y din %x de rînduri afișate</pluralform> +<pluralform>Afișate: %y din 1 rînd</pluralform> +<pluralform>Afișate: %y din %x rînduri</pluralform> +<pluralform>Afișate: %y din %x de rînduri</pluralform> </target> <source>Set direction:</source> @@ -1244,6 +1255,9 @@ Aceasta garantează consecvența stării filelor chiar și în cazul apariției <source>Show files that won't be copied</source> <target>Arată elementele (file/dosare) care nu vor fi copiate</target> +<source>Show filtered or temporarily excluded files</source> +<target>Arată filele filtrate sau excluse temporar</target> + <source>Set as default</source> <target>Setează ca implicit</target> @@ -1280,6 +1294,9 @@ Aceasta garantează consecvența stării filelor chiar și în cazul apariției <source>Warning</source> <target>Atenție</target> +<source>Select all</source> +<target>Selectează Tot</target> + <source>Paused</source> <target>Sincronizare Pauzată</target> diff --git a/FreeFileSync/Build/Languages/russian.lng b/FreeFileSync/Build/Languages/russian.lng index 5c138a10..46f04b1f 100644 --- a/FreeFileSync/Build/Languages/russian.lng +++ b/FreeFileSync/Build/Languages/russian.lng @@ -91,18 +91,18 @@ <source>Any number of alternative directories for at most one config file.</source> <target>Любое количество альтернативных папок для одного конфигурационного файла.</target> -<source>A folder input field is empty.</source> -<target>Поле ввода папки пустое.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>Соответствующая папка будет считаться пустой.</target> - <source>Cannot find the following folders:</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>A folder input field is empty.</source> +<target>Поле ввода папки пустое.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>Соответствующая папка будет считаться пустой.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>Следующие папки имеют зависимые пути. Будьте осторожны при настройке правил синхронизации:</target> @@ -223,8 +223,11 @@ <source>Cannot get process information.</source> <target>Невозможно получить информацию о процессе.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Ожидание снятия блокировки с папки %x...</target> +<source>Waiting while directory is locked:</source> +<target>Ожидание снятия блокировки с папки:</target> + +<source>Lock owner:</source> +<target>Источник блокировки:</target> <source> <pluralform>1 sec</pluralform> @@ -236,6 +239,9 @@ <pluralform>%x секунд</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>Обнаружение заброшенной блокировки...</target> + <source>Creating file %x</source> <target>Создание файла %x</target> @@ -492,6 +498,12 @@ The command is triggered if: <source>Updating attributes of %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>Cannot find %x.</source> <target>Невозможно найти %x.</target> @@ -534,12 +546,6 @@ The command is triggered if: <source>Generating database...</source> <target>Создание базы данных...</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> @@ -581,13 +587,16 @@ The command is triggered if: <pluralform>Automatic retry in %x seconds...</pluralform> </source> <target> +<pluralform>Автоматически повторить через %x секунду...</pluralform> +<pluralform>Автоматически повторить через %x секунды...</pluralform> +<pluralform>Автоматически повторить через %x секунд...</pluralform> </target> <source>&Ignore subsequent errors</source> <target>И&гнорировать последующие ошибки</target> <source>Retrying operation...</source> -<target></target> +<target>Повторение операции...</target> <source>Serious Error</source> <target>Серьезная ошибка</target> @@ -614,7 +623,7 @@ The command is triggered if: <target>Невозможно найти номер текущей версии FreeFileSync онлайн! Вы хотите проверить вручную?</target> <source>&Check</source> -<target></target> +<target>&Проверить</target> <source>Symlink</source> <target>Символьная ссылка</target> @@ -772,12 +781,6 @@ The command is triggered if: <source>Save as batch job</source> <target>Сохранить как пакетное задание</target> -<source>Hide excluded items</source> -<target>Скрыть исключенные элементы</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Показать отфильтрованные или временно исключенные файлы</target> - <source>Number of files and folders that will be created</source> <target>Количество файлов и папок, которые будут созданы</target> @@ -811,8 +814,8 @@ The command is triggered if: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Выявять и распространять изменения на обе стороны. Удаленные, перемещенные и конфликтующие файлы определяются автоматически с использованием базы данных.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>Создавать зеркальную копию левой части. После синхронизации правая часть будет полностью соответствовать левой.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>Создавать зеркальную копию левой части, приводя правую часть в полное соответствие.</target> <source>Copy new and updated files to the right folder.</source> <target>Копировать новые или обновленные файлы на правую сторону.</target> @@ -823,8 +826,16 @@ The command is triggered if: <source>Detect moved files</source> <target>Обнаруживать перемещенные файлы</target> -<source>Requires database files. Not supported by all file systems.</source> -<target>Требуются файлы баз данных. Поддерживается не всеми файловыми системами.</target> +<source> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Создает базу данных файлов +- Обнаруживает активность после начальной синхронизации +- Поддерживается не всеми файловыми системами +</target> <source>Delete files:</source> <target>Удаление файлов:</target> @@ -836,7 +847,7 @@ The command is triggered if: <target>Удалять или перезаписывать файлы, не помещая в "Корзину"</target> <source>Recycle bin</source> -<target></target> +<target>Перемещать в "Корзину"</target> <source>Back up deleted and overwritten files in the recycle bin</source> <target>Делать резервную копию удаленных и перезаписанных файлов в "Корзине"</target> @@ -1064,6 +1075,9 @@ This guarantees a consistent state even in case of a serious error. <source>Find</source> <target>Поиск</target> +<source>Select View</source> +<target>Вид списка файлов</target> + <source>Overview</source> <target>Главная</target> @@ -1073,12 +1087,6 @@ This guarantees a consistent state even in case of a serious error. <source>Main Bar</source> <target>Главная панель</target> -<source>Filter Files</source> -<target>Фильтр</target> - -<source>Select View</source> -<target>Вид списка файлов</target> - <source>Open...</source> <target>Открыть...</target> @@ -1105,6 +1113,9 @@ This guarantees a consistent state even in case of a serious error. <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>&Execute</source> @@ -1131,13 +1142,13 @@ This guarantees a consistent state even in case of a serious error. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>%y из %x строки показано</pluralform> -<pluralform>%y из %x строк показано</pluralform> -<pluralform>%y из %x строк показано</pluralform> +<pluralform>Показано %y из %x строки</pluralform> +<pluralform>Показано %y из %x строк</pluralform> +<pluralform>Показано %y из %x строк</pluralform> </target> <source>Set direction:</source> @@ -1254,6 +1265,9 @@ This guarantees a consistent state even in case of a serious error. <source>Show files that won't be copied</source> <target>Показать файлы, которые не будут скопированы</target> +<source>Show filtered or temporarily excluded files</source> +<target>Показать отфильтрованные или временно исключенные файлы</target> + <source>Set as default</source> <target>Установить по умолчанию</target> @@ -1290,6 +1304,9 @@ This guarantees a consistent state even in case of a serious error. <source>Warning</source> <target>Внимание</target> +<source>Select all</source> +<target>Выделить все</target> + <source>Paused</source> <target>Пауза</target> diff --git a/FreeFileSync/Build/Languages/scottish_gaelic.lng b/FreeFileSync/Build/Languages/scottish_gaelic.lng index 906969cb..f7d69d8a 100644 --- a/FreeFileSync/Build/Languages/scottish_gaelic.lng +++ b/FreeFileSync/Build/Languages/scottish_gaelic.lng @@ -88,18 +88,18 @@ <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>A folder input field is empty.</source> -<target>Tha co-dhiù aon raon pasgain ann a tha falamh.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>Thèid am pasgan a leanas a làimhseachadh mar phasgan falamh.</target> - <source>Cannot find the following folders:</source> <target>Chan urrainn dhuinn na pasgain a leanas a lorg:</target> <source>You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.</source> <target>'S urrainn dhut a' mhearachd seo a leigeil seachad ma tha thu airson 's gun dèilig sinn ri gach pasgan mar gum biodh iad falamh. Thèid na pasgain a chruthachadh gu fèin-obrachail an uairsin rè an t-sioncronachaidh</target> +<source>A folder input field is empty.</source> +<target>Tha co-dhiù aon raon pasgain ann a tha falamh.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>Thèid am pasgan a leanas a làimhseachadh mar phasgan falamh.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>Tha slighean eisimeileachdach aig na pasganan a leanas. Bi faiceallach nuair a chruthaicheas tu riaghailtean sioncronachaidh:</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>Chan urrainn dhuinn greim fhaighinn air fiosrachadh a' phròiseis.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>A' feitheamh fhad 's a tha am pasgan glaiste (%x)...</target> +<source>Waiting while directory is locked:</source> +<target>A' feitheamh fhad 's a thèid am pasgan a ghlasadh:</target> + +<source>Lock owner:</source> +<target>Glais an sealbhadair:</target> <source> <pluralform>1 sec</pluralform> @@ -234,6 +237,9 @@ <pluralform>%x diog</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>A' mothachadh ri glasan trèigte...</target> + <source>Creating file %x</source> <target>A' cruthachadh an fhaidhle %x</target> @@ -492,6 +498,12 @@ Thèid an loidhne-àithne a chur gu dol: <source>Updating attributes of %x</source> <target>Ag ùrachadh buadhan %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>Cannot find %x.</source> <target>Cha ghabh %x a lorg.</target> @@ -531,12 +543,6 @@ Thèid an loidhne-àithne a chur gu dol: <source>Generating database...</source> <target>A' gintinn an stòir-dhàta...</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> @@ -588,7 +594,7 @@ Thèid an loidhne-àithne a chur gu dol: <target>Le&ig seachad mearachdan às a dhèidh seo</target> <source>Retrying operation...</source> -<target></target> +<target>A' feuchainn ris a-rithist...</target> <source>Serious Error</source> <target>Mearachd mhòr</target> @@ -615,7 +621,7 @@ Thèid an loidhne-àithne a chur gu dol: <target>Chan urrainn dhuinn àireamh an tionndaidh làithrich aig FreeFileSync a lorg air loidhne. A bheil thu airson sùil a thoirt thu fhèin?</target> <source>&Check</source> -<target></target> +<target>&Sgrùd</target> <source>Symlink</source> <target>Symlink</target> @@ -651,7 +657,7 @@ Thèid an loidhne-àithne a chur gu dol: <target>Gnìomh</target> <source>Drag && drop</source> -<target>Slaod ┐ leig às</target> +<target>Slaod ⁊ leig às</target> <source>Close progress dialog</source> <target>Dùin còmhradh an adhartais</target> @@ -773,12 +779,6 @@ Thèid an loidhne-àithne a chur gu dol: <source>Save as batch job</source> <target>Sàbhail mar obair baidse</target> -<source>Hide excluded items</source> -<target>Falaich nithean a chaidh a dhùnadh às</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Seall faidhlichean a tha 'gan dùnadh a-mach no air an criathradh a-mach an-dràsta fhèin</target> - <source>Number of files and folders that will be created</source> <target>Àireamh nam faidhle 's nam pasgan a thèid a chruthachadh</target> @@ -812,8 +812,8 @@ Thèid an loidhne-àithne a chur gu dol: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Lorg is sìolaich na h-atharraichean air an dà thaobh. Mothaichidh sinn do rudan a chaidh a sguabadh às, a ghluasad no còmhstrithean gu fèin-obrachail le stòr-dàta.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>Cruthaich lethbhreac-glèidhidh sgàthanaichte dhen phasgan air an taobh chlì a bhios gu tur co-ionnann ris a' phasgan air an taobh deas an dèidh sioncronachaidh.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>Cruthaich lethbhreac-glèidhidh sgàthanaichte dhen phasgan air an taobh clì 's am pasgan air an taobh deas 'ga atharrachadh d' a rèir.</target> <source>Copy new and updated files to the right folder.</source> <target>Cuir lethbhreac de dh'fhaidhlichean ùra 's ùraichte dhan phasgan air an taobh deas.</target> @@ -824,8 +824,16 @@ Thèid an loidhne-àithne a chur gu dol: <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> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Feumaidh seo faidhlichean stòir-dhàta 's cruthaichidh seo faidhlichean mar sin +- Bidh am mothachadh an gnìomh an dèidh a' chiad sioncronachaidh +- Chan eil gach siostam fhaidhlichean a' cur taic ris +</target> <source>Delete files:</source> <target>Sguab às na faidhlichean:</target> @@ -1061,6 +1069,9 @@ Nì seo cinnteach gum bi fuasgladh ann ma thachras mearachd mhòr. <source>Find</source> <target>Lorg</target> +<source>Select View</source> +<target>Tagh sealladh</target> + <source>Overview</source> <target>Foir-shealladh</target> @@ -1070,12 +1081,6 @@ Nì seo cinnteach gum bi fuasgladh ann ma thachras mearachd mhòr. <source>Main Bar</source> <target>Am prìomh-bhàr</target> -<source>Filter Files</source> -<target>Criathraich na faidhlichean</target> - -<source>Select View</source> -<target>Tagh sealladh</target> - <source>Open...</source> <target>Fosgail...</target> @@ -1134,14 +1139,14 @@ Nì seo cinnteach gum bi fuasgladh ann ma thachras mearachd mhòr. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>%y de %x ràgh san t-sealladh</pluralform> -<pluralform>%y de %x ràgh san t-sealladh</pluralform> -<pluralform>%y de %x ràghan san t-sealladh</pluralform> -<pluralform>%y de %x ràgh san t-sealladh</pluralform> +<pluralform>A' sealltainn %y à %x ràgh</pluralform> +<pluralform>A' sealltainn %y à %x ràgh</pluralform> +<pluralform>A' sealltainn %y à %x ràghan</pluralform> +<pluralform>A' sealltainn %y à %x ràgh</pluralform> </target> <source>Set direction:</source> @@ -1258,6 +1263,9 @@ Nì seo cinnteach gum bi fuasgladh ann ma thachras mearachd mhòr. <source>Show files that won't be copied</source> <target>Seall faidhlichean nach dèid lethbhreac a dhèanamh dhiubh</target> +<source>Show filtered or temporarily excluded files</source> +<target>Seall faidhlichean a tha 'gan dùnadh a-mach no air an criathradh a-mach an-dràsta fhèin</target> + <source>Set as default</source> <target>Suidhich mar a' bhun-roghainn</target> @@ -1294,6 +1302,9 @@ Nì seo cinnteach gum bi fuasgladh ann ma thachras mearachd mhòr. <source>Warning</source> <target>Rabhadh</target> +<source>Select all</source> +<target>Tagh na h-uile</target> + <source>Paused</source> <target>'Na stad</target> diff --git a/FreeFileSync/Build/Languages/serbian.lng b/FreeFileSync/Build/Languages/serbian.lng index 952cce1c..d4b7680e 100644 --- a/FreeFileSync/Build/Languages/serbian.lng +++ b/FreeFileSync/Build/Languages/serbian.lng @@ -88,18 +88,18 @@ <source>Any number of alternative directories for at most one config file.</source> <target>Било који број алтернативних фолдера за најмање једну конфигурациону датотеку.</target> -<source>A folder input field is empty.</source> -<target>Поље за одабир фолдера је празно.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>Одговарајући фолдер сматраће се празним.</target> - <source>Cannot find the following folders:</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>A folder input field is empty.</source> +<target>Поље за одабир фолдера је празно.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>Одговарајући фолдер сматраће се празним.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>Следећи фолдери имају зависне путање. Будите пажљиви када подешавате синхронизациона правила:</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>Не могу добити информације о процесу.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Чека се док се фолдер не закључа (%x)...</target> +<source>Waiting while directory is locked:</source> +<target>Чека се док је фолдер закључан:</target> + +<source>Lock owner:</source> +<target>Власник закључавања:</target> <source> <pluralform>1 sec</pluralform> @@ -233,6 +236,9 @@ <pluralform>%x сек</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>Детекција обустављеног закључавања...</target> + <source>Creating file %x</source> <target>Правим датотеку %x</target> @@ -489,6 +495,12 @@ The command is triggered if: <source>Updating attributes of %x</source> <target>Обнављам атрибуте од %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>Cannot find %x.</source> <target>Не могу пронаћи %x.</target> @@ -528,12 +540,6 @@ The command is triggered if: <source>Generating database...</source> <target>Генерисање базе података...</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> @@ -584,7 +590,7 @@ The command is triggered if: <target>&Занемари грешке које даље следе</target> <source>Retrying operation...</source> -<target></target> +<target>Поновни покушај операције...</target> <source>Serious Error</source> <target>Озбиљна грешка</target> @@ -611,7 +617,7 @@ The command is triggered if: <target>Не могу на мрежи пронаћи тренутни број верзије FreeFileSync-а. Да ли желите да проверите ручно?</target> <source>&Check</source> -<target></target> +<target>&Провера</target> <source>Symlink</source> <target>Сим-веза</target> @@ -769,12 +775,6 @@ The command is triggered if: <source>Save as batch job</source> <target>Сачувај као беч задатак</target> -<source>Hide excluded items</source> -<target>Сакриј искључене ставке</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Прикажи филтриране или привремено искључене датотеке</target> - <source>Number of files and folders that will be created</source> <target>Број датотека и фолдера који ће бити креирани</target> @@ -808,8 +808,8 @@ The command is triggered if: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Пронађи и изврши промене на обе стране. Брисања, премештања и конфликти се откривају аутоматски употребом базе података.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>Креирај огледални бекап левог фолдера који ће се тачно подударати са десним фолдером након синхронизације.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>Креирај огледални бекап левог фолдера прилагођавајући га потпуно десном фолдеру.</target> <source>Copy new and updated files to the right folder.</source> <target>Копирај нове и ажуриране датотеке у десни фолдер.</target> @@ -820,8 +820,16 @@ The command is triggered if: <source>Detect moved files</source> <target>Уочи премештене датотеке</target> -<source>Requires database files. Not supported by all file systems.</source> -<target>Потребне датотеке базе. Није подржано за све системе датотека.</target> +<source> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Потребује и креира датотеке база +- Детекција активна после иницијалног синка +- Није подржано за све системе датотека +</target> <source>Delete files:</source> <target>Обриши датотеке:</target> @@ -1057,6 +1065,9 @@ This guarantees a consistent state even in case of a serious error. <source>Find</source> <target>Пронађи</target> +<source>Select View</source> +<target>Изаберите приказ</target> + <source>Overview</source> <target>Преглед</target> @@ -1066,12 +1077,6 @@ This guarantees a consistent state even in case of a serious error. <source>Main Bar</source> <target>Главна трака</target> -<source>Filter Files</source> -<target>Филтрирање датотека</target> - -<source>Select View</source> -<target>Изаберите приказ</target> - <source>Open...</source> <target>Отвори...</target> @@ -1127,13 +1132,13 @@ This guarantees a consistent state even in case of a serious error. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>%y од %x реда у приказу</pluralform> -<pluralform>%y од %x реда у приказу</pluralform> -<pluralform>%y од %x редова у приказу</pluralform> +<pluralform>Приказ %y од %x реда</pluralform> +<pluralform>Приказ %y од %x реда</pluralform> +<pluralform>Приказ %y од %x редова</pluralform> </target> <source>Set direction:</source> @@ -1250,6 +1255,9 @@ This guarantees a consistent state even in case of a serious error. <source>Show files that won't be copied</source> <target>Прикажи датотеке које неће бити копиране</target> +<source>Show filtered or temporarily excluded files</source> +<target>Прикажи филтриране или привремено искључене датотеке</target> + <source>Set as default</source> <target>Постави као подразумевано</target> @@ -1286,6 +1294,9 @@ This guarantees a consistent state even in case of a serious error. <source>Warning</source> <target>Упозорење</target> +<source>Select all</source> +<target>Одабери све</target> + <source>Paused</source> <target>Паузирано</target> diff --git a/FreeFileSync/Build/Languages/slovenian.lng b/FreeFileSync/Build/Languages/slovenian.lng index 92f38be4..c8c9f3b3 100644 --- a/FreeFileSync/Build/Languages/slovenian.lng +++ b/FreeFileSync/Build/Languages/slovenian.lng @@ -7,6 +7,18 @@ <plural_definition>n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3</plural_definition> </header> +<source> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> +</source> +<target></target> + +<source> +<pluralform>Do you really want to execute the command %y for one item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target></target> + <source>Both sides have changed since last synchronization.</source> <target>Obe strani sta se spremenili od zadnje sinhronizacije.</target> @@ -88,18 +100,18 @@ <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>A folder input field is empty.</source> -<target>Vnosno polje za mapo je prazno.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>Ustrezajoča mapa bo smatrana kot prazna.</target> - <source>Cannot find the following folders:</source> <target>Ne morem najti naslednjih map:</target> <source>You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.</source> <target>To napako, ki smatra vsako mapo kot prazno, lahko ignorirate. Mape bodo potem samodejno ustvarjene med sinhronizacijo.</target> +<source>A folder input field is empty.</source> +<target>Vnosno polje za mapo je prazno.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>Ustrezajoča mapa bo smatrana kot prazna.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>Naslednje mape imajo odvisne poti. Bodite previdni pri nastavitvi sinhronizacijskih pravil:</target> @@ -220,8 +232,11 @@ <source>Cannot get process information.</source> <target>Ne morem pridobiti informacij o procesu.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Čakam, medtem ko se zaklepa imenik (%x)...</target> +<source>Waiting while directory is locked:</source> +<target>Čakam dokler je imenik zaklenjen:</target> + +<source>Lock owner:</source> +<target>Lastnik zaklepa:</target> <source> <pluralform>1 sec</pluralform> @@ -234,6 +249,9 @@ <pluralform>%x sek</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>Zaznavanje opuščenega zaklepa...</target> + <source>Creating file %x</source> <target>Ustvarjam datoteko %x</target> @@ -492,6 +510,12 @@ Ukaz se sproži če: <source>Updating attributes of %x</source> <target>Posodabljam atribute od %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>Cannot find %x.</source> <target>Ne morem najti %x.</target> @@ -531,12 +555,6 @@ Ukaz se sproži če: <source>Generating database...</source> <target>Ustvarjam podatkovno bazo...</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> @@ -588,7 +606,7 @@ Ukaz se sproži če: <target>&Ignoriraj nadaljnje napake</target> <source>Retrying operation...</source> -<target></target> +<target>Ponovni poizkus operacije...</target> <source>Serious Error</source> <target>Resna napaka</target> @@ -615,7 +633,7 @@ Ukaz se sproži če: <target>Na omrežju ne najdem obstoječe verzije FreeFileSync-a. Ali želite preveriti lastnoročno?</target> <source>&Check</source> -<target></target> +<target>&Preveri</target> <source>Symlink</source> <target>Simbolična povezava</target> @@ -773,12 +791,6 @@ Ukaz se sproži če: <source>Save as batch job</source> <target>Shrani kot serijsko opravilo</target> -<source>Hide excluded items</source> -<target>Skrij izključene elemente</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Pokaži filtrirane ali začasno izključene datoteke</target> - <source>Number of files and folders that will be created</source> <target>Število datotek in map, ki bodo ustvarjene</target> @@ -812,8 +824,8 @@ Ukaz se sproži če: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Identificiraj in razširjaj spremembe na obeh straneh. Izbrisi, premiki in spori so samodejno zaznani z uporabo podatkovne baze.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>Ustvari zrcalno kopijo levega imenika, tako da se bo desni imenik po sinhnorizaciji popolnoma ujemal.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>Ustvari zrcalno kopijo levega imenika s prilagoditvijo desnega imenika, tako da se ujemata.</target> <source>Copy new and updated files to the right folder.</source> <target>Kopiraj nove in posodobljene datoteke v desni imenik.</target> @@ -824,8 +836,16 @@ Ukaz se sproži če: <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> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Zahteva in ustvari datoteke podatkovne baze +- Zaznavane je aktivno po začetnem sinhnoriziranju +- Ni podprto s strani vseh datotečnih sistemov +</target> <source>Delete files:</source> <target>Izbriši datoteke:</target> @@ -1061,6 +1081,9 @@ To zagotavlja konsistenco podatkov v primeru napake. <source>Find</source> <target>Najdi</target> +<source>Select View</source> +<target>Izberi pogled</target> + <source>Overview</source> <target>Pregled</target> @@ -1070,12 +1093,6 @@ To zagotavlja konsistenco podatkov v primeru napake. <source>Main Bar</source> <target>Glavna vrstica</target> -<source>Filter Files</source> -<target>Filtriraj datoteke</target> - -<source>Select View</source> -<target>Izberi pogled</target> - <source>Open...</source> <target>Odpri...</target> @@ -1097,13 +1114,6 @@ To zagotavlja konsistenco podatkov v primeru napake. <source>Confirm</source> <target>Potrdi</target> -<source> -<pluralform>Do you really want to execute the command %y for one item?</pluralform> -<pluralform>Do you really want to execute the command %y for %x items?</pluralform> -</source> -<target> -</target> - <source>&Execute</source> <target>&Izvedi</target> @@ -1129,17 +1139,6 @@ To zagotavlja konsistenco podatkov v primeru napake. <pluralform>%x datotek</pluralform> </target> -<source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> -</source> -<target> -<pluralform>%y od %x vrstice prikazana</pluralform> -<pluralform>%y od %x vrstic prikazanih</pluralform> -<pluralform>%y od %x vrstic prikazanih</pluralform> -<pluralform>%y od %x vrstic prikazanih</pluralform> -</target> - <source>Set direction:</source> <target>Nastavi smer:</target> @@ -1254,6 +1253,9 @@ To zagotavlja konsistenco podatkov v primeru napake. <source>Show files that won't be copied</source> <target>Prikaži datoteke, ki ne bodo kopirane</target> +<source>Show filtered or temporarily excluded files</source> +<target>Pokaži filtrirane ali začasno izključene datoteke</target> + <source>Set as default</source> <target>Nastavi kot privzeto</target> @@ -1290,6 +1292,9 @@ To zagotavlja konsistenco podatkov v primeru napake. <source>Warning</source> <target>Pozor</target> +<source>Select all</source> +<target>Izberi vse</target> + <source>Paused</source> <target>Na premoru</target> diff --git a/FreeFileSync/Build/Languages/spanish.lng b/FreeFileSync/Build/Languages/spanish.lng index 0ad717bf..27af018e 100644 --- a/FreeFileSync/Build/Languages/spanish.lng +++ b/FreeFileSync/Build/Languages/spanish.lng @@ -88,18 +88,18 @@ <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>A folder input field is empty.</source> -<target>Un campo de entrada de la carpeta está vacío.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>La siguiente carpeta será considerada como vacía.</target> - <source>Cannot find the following folders:</source> <target>No se pudieron encontrar las siguiente carpetas:</target> <source>You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.</source> <target>Ignore este error si desea tratar cada carpeta como vacía. En tal caso, se crearán estas carpetas automáticamente durante la sincronización.</target> +<source>A folder input field is empty.</source> +<target>Un campo de entrada de la carpeta está vacío.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>La siguiente carpeta será considerada como vacía.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>Las carpetas siguientes usan rutas dependientes. Tenga cuidado al definir reglas de sincronización:</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>No se puede obtener información del proceso.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Esperando mientras el directorio se encuentre bloqueado (%x)…</target> +<source>Waiting while directory is locked:</source> +<target>Esperando mientras el directorio está bloqueado:</target> + +<source>Lock owner:</source> +<target>Bloquear propietario:</target> <source> <pluralform>1 sec</pluralform> @@ -232,6 +235,9 @@ <pluralform>%x seg.</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>Detección de bloqueo abandonado…</target> + <source>Creating file %x</source> <target>Creando archivo %x</target> @@ -356,7 +362,7 @@ <target>2. Introduzca una línea de comandos.</target> <source>3. Press 'Start'.</source> -<target>3. Presione 'Inicio'.</target> +<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> @@ -486,6 +492,12 @@ El comando es disparado si: <source>Updating attributes of %x</source> <target>Actualizar atributos de %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>Cannot find %x.</source> <target>No se pudo encontrar %x.</target> @@ -525,12 +537,6 @@ El comando es disparado si: <source>Generating database...</source> <target>Generando base de datos…</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> @@ -580,7 +586,7 @@ El comando es disparado si: <target>&Ignorar errores posteriores</target> <source>Retrying operation...</source> -<target></target> +<target>Reintentando la operación…</target> <source>Serious Error</source> <target>Error grave</target> @@ -607,7 +613,7 @@ El comando es disparado si: <target>No se encuentra el número de versión actual de FreeFileSync en línea. ¿Desea comprobarla manualmente?</target> <source>&Check</source> -<target></target> +<target>&Comprobar</target> <source>Symlink</source> <target>Enlace simbólico</target> @@ -733,7 +739,7 @@ El comando es disparado si: <target>Comprobar &automáticamente una vez por semana</target> <source>&Check for new version</source> -<target>&Comprobar si hay una nueva versión</target> +<target>&Comprobar nueva versión</target> <source>Compare</source> <target>Comparar</target> @@ -757,20 +763,14 @@ El comando es disparado si: <target>Cerrar la barra de búsqueda</target> <source>Find:</source> -<target>Find:</target> +<target>Buscar:</target> <source>Match case</source> -<target>Distinción entre mayúsculas y minúsculas</target> +<target>Coincidir mayúsculas y minúsculas</target> <source>Save as batch job</source> <target>Salvar como tarea por lotes</target> -<source>Hide excluded items</source> -<target>Ocultar elementos excluidos</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Mostrar archivos excluidos temporalmente o filtrados</target> - <source>Number of files and folders that will be created</source> <target>Número de archivos y carpetas que serán creados</target> @@ -802,22 +802,30 @@ El comando es disparado si: <target>OK</target> <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> -<target>Identificar y propagar cambios en ambos lados. Eliminaciones, movimientos y conflictos serán detectados automáticamente usando una base de datos.</target> +<target>Identificar y propagar cambios en ambos lados. Archivos eliminados, movidos y conflictos se detectan automáticamente usando una base de datos.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>Crear una copia de respaldo reflejo de la carpeta izquierda que corresponda exactamente a la carpeta derecha después de la sincronización.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>Crear una copia de respaldo espejo de la carpeta izquierda, adaptando y haciendo coincidir la carpeta derecha.</target> <source>Copy new and updated files to the right folder.</source> <target>Copiar archivos nuevos y actualizados a la carpeta de la derecha.</target> <source>Configure your own synchronization rules.</source> -<target>Configuración de sus propias reglas de sincronización.</target> +<target>Configurar reglas de sincronización personalizadas.</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> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Requiere y crea archivos de bases de datos +- Detección activa tras syncronización inicial +- No compatible con todos los sistemas de archivos +</target> <source>Delete files:</source> <target>Eliminar archivos:</target> @@ -826,22 +834,22 @@ El comando es disparado si: <target>Permanente</target> <source>Delete or overwrite files permanently</source> -<target>Borrar o Sobrescribir archivos permanentemente</target> +<target>Borrar o sobrescribir los archivos permanentemente</target> <source>Recycle bin</source> <target>Papelera de reciclaje</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> +<target>Copiar a la papelera de reciclaje los archivos eliminados y reemplazados</target> <source>Versioning</source> <target>Control de versiones</target> <source>Move files to a user-defined folder</source> -<target>Mover archivos a una carpeta del usuario</target> +<target>Mover los archivos a una carpeta del usuario</target> <source>Naming convention:</source> -<target>Convención de nombrado:</target> +<target>Convención de nombre:</target> <source>Show examples</source> <target>Mostrar ejemplos</target> @@ -1053,8 +1061,11 @@ Se garantiza un estado coherente incluso en caso de error grave. <source>Find</source> <target>Buscar</target> +<source>Select View</source> +<target>Seleccione vista</target> + <source>Overview</source> -<target>Visión global</target> +<target>Vista general</target> <source>Configuration</source> <target>Configuración</target> @@ -1062,12 +1073,6 @@ Se garantiza un estado coherente incluso en caso de error grave. <source>Main Bar</source> <target>Barra principal</target> -<source>Filter Files</source> -<target>Filtrar archivos</target> - -<source>Select View</source> -<target>Seleccione vista</target> - <source>Open...</source> <target>Abrir…</target> @@ -1120,12 +1125,12 @@ Se garantiza un estado coherente incluso en caso de error grave. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>%y de 1 fila en la vista</pluralform> -<pluralform>%y de %x filas en vista</pluralform> +<pluralform>Mostrando %y de 1 fila</pluralform> +<pluralform>Mostrando %y de %x filas</pluralform> </target> <source>Set direction:</source> @@ -1242,6 +1247,9 @@ Se garantiza un estado coherente incluso en caso de error grave. <source>Show files that won't be copied</source> <target>Mostrar archivos que no serán copiados</target> +<source>Show filtered or temporarily excluded files</source> +<target>Mostrar archivos excluidos temporalmente o filtrados</target> + <source>Set as default</source> <target>Predeterminado</target> @@ -1278,6 +1286,9 @@ Se garantiza un estado coherente incluso en caso de error grave. <source>Warning</source> <target>Atención</target> +<source>Select all</source> +<target>Seleccionar todo</target> + <source>Paused</source> <target>Pausado</target> diff --git a/FreeFileSync/Build/Languages/swedish.lng b/FreeFileSync/Build/Languages/swedish.lng index f6cebeab..c5fe8bfb 100644 --- a/FreeFileSync/Build/Languages/swedish.lng +++ b/FreeFileSync/Build/Languages/swedish.lng @@ -88,18 +88,18 @@ <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>A folder input field is empty.</source> -<target>Ett inmatningsfält är tomt</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>Motsvarande mapp kommer att betraktas som tom.</target> - <source>Cannot find the following folders:</source> <target>Kan inte hitta följande mappar:</target> <source>You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.</source> <target>Du kan bortse från detta fel, och betrakta varje mapp som tom. Mapparna kommer då att skapas automatiskt, under synkroniseringen</target> +<source>A folder input field is empty.</source> +<target>Ett inmatningsfält är tomt</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>Motsvarande mapp kommer att betraktas som tom.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>Följande mappar har beroende sökvägar. Var försiktig vid konfigurering av synkroniseringsregler:</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>Processinformation kan inte inhämtas</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Väntar medan mappen låses (%x)...</target> +<source>Waiting while directory is locked:</source> +<target>Väntar medan mappen låses:</target> + +<source>Lock owner:</source> +<target>Låsägare:</target> <source> <pluralform>1 sec</pluralform> @@ -232,6 +235,9 @@ <pluralform>%x sek</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>Söker övergivna lås...</target> + <source>Creating file %x</source> <target>Skapar fil %x</target> @@ -486,6 +492,12 @@ Kommandot triggas om: <source>Updating attributes of %x</source> <target>Uppdaterar attribut 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>Cannot find %x.</source> <target>Kan inte hitta %x.</target> @@ -525,12 +537,6 @@ Kommandot triggas om: <source>Generating database...</source> <target>Skapar databas...</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> @@ -572,13 +578,15 @@ Kommandot triggas om: <pluralform>Automatic retry in %x seconds...</pluralform> </source> <target> +<pluralform>Automatiskt återförsök om 1 sekund...</pluralform> +<pluralform>Automatiskt återförsök om %x sekunder...</pluralform> </target> <source>&Ignore subsequent errors</source> <target>&Ignorera efterföljande fel</target> <source>Retrying operation...</source> -<target></target> +<target>Upprepar åtgärden...</target> <source>Serious Error</source> <target>Allvarligt fel</target> @@ -605,7 +613,7 @@ Kommandot triggas om: <target>Kan inte hitta aktuellt versionsnummer online. Vill du kontrollera manuellt?</target> <source>&Check</source> -<target></target> +<target>&Kontrollera</target> <source>Symlink</source> <target>Symboliska länkar</target> @@ -763,12 +771,6 @@ Kommandot triggas om: <source>Save as batch job</source> <target>Spara som batch-fil</target> -<source>Hide excluded items</source> -<target>Dölj undantagna objekt</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Dölj filtrerade eller temporärt undantagna filer</target> - <source>Number of files and folders that will be created</source> <target>Antal filer och mappar som kommer att skapas</target> @@ -802,8 +804,8 @@ Kommandot triggas om: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Identifierar och sprider förändringar på båda sidor. Borttagningar, förflyttningar och konflikter detekteras automatiskt med hjälp av en databas.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>Skapar en speglad kopia av vänster mapp, som exakt matchas av höger mapp efter synkronisering.</target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>Skapar en speglad säkerhetskopia av vänstra mappen genom att anpassa den högra</target> <source>Copy new and updated files to the right folder.</source> <target>Kopierar nya och uppdaterade filer till höger mapp.</target> @@ -814,8 +816,16 @@ Kommandot triggas om: <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> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Kräver och skapar databasfiler +- Övervakning aktiv efter initial synkronisering +- Stöds ej av alla filsystem +</target> <source>Delete files:</source> <target>Ta bort filer:</target> @@ -860,7 +870,7 @@ Kommandot triggas om: <target>Visa popup vid fel och varningar</target> <source>On completion:</source> -<target>Vid slutfört:</target> +<target>Vid slutförd åtgärd:</target> <source>Start synchronization now?</source> <target>Vill du starta synkroniseringen nu?</target> @@ -1051,6 +1061,9 @@ Detta garanterar ett konsekvent tillstånd även vid allvarliga fel. <source>Find</source> <target>Sök</target> +<source>Select View</source> +<target>Välj vy</target> + <source>Overview</source> <target>Översikt</target> @@ -1060,12 +1073,6 @@ Detta garanterar ett konsekvent tillstånd även vid allvarliga fel. <source>Main Bar</source> <target>Primärt verktygsfält</target> -<source>Filter Files</source> -<target>Filtrera filer</target> - -<source>Select View</source> -<target>Välj vy</target> - <source>Open...</source> <target>Öppna...</target> @@ -1092,6 +1099,8 @@ Detta garanterar ett konsekvent tillstånd även vid allvarliga fel. <pluralform>Do you really want to execute the command %y for %x items?</pluralform> </source> <target> +<pluralform>Vill du verkligen verkställa kommandot %y för ett objekt?</pluralform> +<pluralform>Vill du verkligen verkställa kommandot %y för %x objekt?</pluralform> </target> <source>&Execute</source> @@ -1116,12 +1125,12 @@ Detta garanterar ett konsekvent tillstånd även vid allvarliga fel. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> -<pluralform>%y av 1 rad i vyn</pluralform> -<pluralform>%y av %x rader i vyn</pluralform> +<pluralform>Visar %y av 1 rad</pluralform> +<pluralform>Visar %y av %x rader</pluralform> </target> <source>Set direction:</source> @@ -1238,6 +1247,9 @@ Detta garanterar ett konsekvent tillstånd även vid allvarliga fel. <source>Show files that won't be copied</source> <target>Visa filer som inte kommer att kopieras</target> +<source>Show filtered or temporarily excluded files</source> +<target>Dölj filtrerade eller temporärt undantagna filer</target> + <source>Set as default</source> <target>Ange som standard</target> @@ -1274,6 +1286,9 @@ Detta garanterar ett konsekvent tillstånd även vid allvarliga fel. <source>Warning</source> <target>Varning</target> +<source>Select all</source> +<target>Markera alla</target> + <source>Paused</source> <target>Pausad</target> diff --git a/FreeFileSync/Build/Languages/outdated/turkish.lng b/FreeFileSync/Build/Languages/turkish.lng index 99823c18..a0ad9e0f 100644 --- a/FreeFileSync/Build/Languages/outdated/turkish.lng +++ b/FreeFileSync/Build/Languages/turkish.lng @@ -88,18 +88,18 @@ <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>A folder input field is empty.</source> -<target>Bir klasör giriş alanı boş.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>Karşıdaki klasör boş olarak kabul edilecek.</target> - <source>Cannot find the following folders:</source> <target>Aşağıdaki klasörler bulunamadı:</target> <source>You can ignore this error to consider each folder as empty. The folders then will be created automatically during synchronization.</source> <target>Bu hatayı yok sayarak karşıdaki klasörleri boş kabul edebilirsiniz. Bu klasörler eşleştirme sırasında kendiliğinden oluşturulur.</target> +<source>A folder input field is empty.</source> +<target>Bir klasör giriş alanı boş.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>Karşıdaki klasör boş olarak kabul edilecek.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>Şu klasörlerin bağlı yolları var. Eşleştirme kurallarını ayarlarken dikkatli olun:</target> @@ -220,8 +220,11 @@ <source>Cannot get process information.</source> <target>İşlem bilgisi alınamadı.</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Klasör kilitli olduğundan bekleniyor (%x)...</target> +<source>Waiting while directory is locked:</source> +<target>Klasör kilitli olduğundan bekleniyor:</target> + +<source>Lock owner:</source> +<target>Kilitleyen:</target> <source> <pluralform>1 sec</pluralform> @@ -232,6 +235,9 @@ <pluralform>%x saniye</pluralform> </target> +<source>Detecting abandoned lock...</source> +<target>Kaldırılmış kilit algılanıyor...</target> + <source>Creating file %x</source> <target>%x dosyası ekleniyor</target> @@ -287,7 +293,7 @@ <target>/saniye</target> <source>%x items/sec</source> -<target></target> +<target>%x öge/saniye</target> <source>Configuration file %x loaded partially only.</source> <target>%x ayarlar dosyası kısmen yüklendi.</target> @@ -317,10 +323,10 @@ <target>%x birim adı %y dosya yolunun bir parçası değil.</target> <source>Stop requested: Waiting for current operation to finish...</source> -<target></target> +<target>Durdurulması istendi: Yürürlükteki işlemin bitmesi bekleniyor...</target> <source>Unable to create timestamp for versioning:</source> -<target></target> +<target>Sürüm için zaman damgası oluşturulamadı:</target> <source>Cannot read the following XML elements:</source> <target>Şu XML elemanları okunamadı:</target> @@ -338,7 +344,7 @@ <target>&Dosya</target> <source>&View help</source> -<target></target> +<target>&Yardıma bakın</target> <source>&About</source> <target>H&akkında</target> @@ -362,7 +368,7 @@ <target>.ffs_batch dosyasını yükleyerek başlayabilirsiniz.</target> <source>Folders to watch:</source> -<target></target> +<target>İzlenecek klasörler:</target> <source>Add folder</source> <target>Klasör ekleyin</target> @@ -377,13 +383,13 @@ <target>Bir klasör seçin</target> <source>Idle time (in seconds):</source> -<target></target> +<target>Boşta bekleme süresi (saniye):</target> <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></target> +<target>Komut satırı:</target> <source> The command is triggered if: @@ -397,7 +403,7 @@ Komut şu durumlarda yürütülür: </target> <source>&Start</source> -<target></target> +<target>&Başlayın</target> <source>About</source> <target>Hakkında</target> @@ -409,7 +415,7 @@ Komut şu durumlarda yürütülür: <target>Tüm dosyalar</target> <source>Automated Synchronization</source> -<target></target> +<target>Kendiliğinden Eşleştirme</target> <source>Directory monitoring active</source> <target>Klasör izleme kullanılıyor</target> @@ -430,7 +436,7 @@ Komut şu durumlarda yürütülür: <target>Çı&kın</target> <source>Incorrect command line:</source> -<target></target> +<target>Geçersiz komut satırı:</target> <source>&Retry</source> <target>&Yeniden deneyin</target> @@ -486,6 +492,12 @@ Komut şu durumlarda yürütülür: <source>Updating attributes of %x</source> <target>%x öznitelikleri güncelleniyor</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>Cannot find %x.</source> <target>%x bulunamadı.</target> @@ -496,7 +508,7 @@ Komut şu durumlarda yürütülür: <target>Hedef klasör giriş alanı boş olmamalı.</target> <source>Please enter a target folder for versioning.</source> -<target></target> +<target>Sürüm izlemesinde kullanılacak bir hedef klasör yazın.</target> <source>Source folder %x not found.</source> <target>%x kaynak klasörü bulunamadı.</target> @@ -525,17 +537,11 @@ Komut şu durumlarda yürütülür: <source>Generating database...</source> <target>Veri tabanı 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 stopped</source> -<target></target> +<target>Eşleştirme durduruldu</target> <source>Synchronization completed with errors</source> <target>Eşleştirme bazı hatalarla tamamlandı</target> @@ -553,10 +559,10 @@ Komut şu durumlarda yürütülür: <target>%x günlük dosyası kaydediliyor...</target> <source>You can switch to FreeFileSync's main window to resolve this issue.</source> -<target></target> +<target>Bu sorunu çözmek için FreeFileSync ana penceresine geçebilirsiniz.</target> <source>&Don't show this warning again</source> -<target>Bu uyarı bir daha &görüntülenmesin</target> +<target>Bu &uyarı bir daha görüntülenmesin</target> <source>&Ignore</source> <target>&Yoksayın</target> @@ -565,32 +571,34 @@ Komut şu durumlarda yürütülür: <target>&Değiştirin</target> <source>Switching to FreeFileSync's main window</source> -<target></target> +<target>FreeFileSync ana penceresine geçiliyor</target> <source> <pluralform>Automatic retry in 1 second...</pluralform> <pluralform>Automatic retry in %x seconds...</pluralform> </source> <target> +<pluralform>1 saniye içinde yeniden denenecek...</pluralform> +<pluralform>%x saniye içinde yeniden denenecek...</pluralform> </target> <source>&Ignore subsequent errors</source> <target>Sonraki &hatalar yoksayılsın</target> <source>Retrying operation...</source> -<target></target> +<target>İşlem yeniden deneniyor...</target> <source>Serious Error</source> -<target></target> +<target>Ciddi Hata</target> <source>Check for Program Updates</source> -<target></target> +<target>Güncellemeleri Denetleyin</target> <source>A new version of FreeFileSync is available:</source> <target>Yeni bir FreeFileSync sürümü yayınlanmış:</target> <source>Download now?</source> -<target>İndirilsin mi?</target> +<target>İndirmek ister misiniz?</target> <source>&Download</source> <target>İn&dirin</target> @@ -605,7 +613,7 @@ Komut şu durumlarda yürütülür: <target>Geçerli FreeFileSync sürüm numarası çevrimiçi olarak bulunamıyor. El ile denetlemek ister misiniz?</target> <source>&Check</source> -<target></target> +<target>&Denetleyin</target> <source>Symlink</source> <target>Smblkbağlantı</target> @@ -641,7 +649,7 @@ Komut şu durumlarda yürütülür: <target>İşlem</target> <source>Drag && drop</source> -<target>Klasör ya da dosyaları sürükleyip buraya bırakabilirsiniz</target> +<target>Dosyaları sürükleyip buraya bırakabilirsiniz</target> <source>Close progress dialog</source> <target>İşlem penceresi kapatılsın</target> @@ -659,19 +667,19 @@ Komut şu durumlarda yürütülür: <target>Hazırda bekletilsin</target> <source>Alternate comparison settings</source> -<target></target> +<target>Alternatif karşılaştırma ayarları</target> <source>Alternate synchronization settings</source> -<target></target> +<target>Alternatif eşleştirme ayarları</target> <source>Local filter</source> -<target></target> +<target>Yerel süzgeç</target> <source>Active</source> -<target></target> +<target>Etkin</target> <source>None</source> -<target></target> +<target>Yok</target> <source>Remove alternate settings</source> <target>Alternatif ayarları silin</target> @@ -686,13 +694,13 @@ Komut şu durumlarda yürütülür: <target>Yapıştırın</target> <source>Alternate Comparison Settings</source> -<target></target> +<target>Alternatif Karşılaştırma Ayarları</target> <source>Alternate Synchronization Settings</source> -<target></target> +<target>Alternatif Eşleştirme Ayarları</target> <source>Local Filter</source> -<target></target> +<target>Yerel Süzgeç</target> <source>&New</source> <target>Ye&ni</target> @@ -716,7 +724,7 @@ Komut şu durumlarda yürütülür: <target>Di&l</target> <source>&Find...</source> -<target></target> +<target>A&rayın...</target> <source>&Export file list...</source> <target>Dosya list&esini verin...</target> @@ -731,7 +739,7 @@ Komut şu durumlarda yürütülür: <target>&Haftada bir kendiliğinden denetlensin</target> <source>&Check for new version</source> -<target></target> +<target>Yeni &sürümü denetleyin</target> <source>Compare</source> <target>Karşılaştırın</target> @@ -752,23 +760,17 @@ Komut şu durumlarda yürütülür: <target>Sağ ve sol tarafları değiştirin</target> <source>Close search bar</source> -<target></target> +<target>Arama çubuğunu kapatın</target> <source>Find:</source> -<target></target> +<target>Bulun:</target> <source>Match case</source> -<target>Büyük/küçük harfe uyulsun</target> +<target>Büyük-küçük harf uysun</target> <source>Save as batch job</source> <target>Toplu iş olarak kaydedin</target> -<source>Hide excluded items</source> -<target>Katılmayan ögeler görüntülensin</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Süzülmüş ya da geçici olarak katılmayan dosyalar görüntülenir</target> - <source>Number of files and folders that will be created</source> <target>Eklenecek dosya ve klasör sayısı</target> @@ -782,46 +784,54 @@ Komut şu durumlarda yürütülür: <target>Toplam kopyalanacak bayt</target> <source>Select a variant:</source> -<target></target> +<target>İşlem tipini seçin:</target> <source>Identify equal files by comparing modification time and size.</source> -<target></target> +<target>Dosyaların aynı olup olmadığı, son değişiklik zamanı ve boyuta göre belirlensin.</target> <source>Identify equal files by comparing the file content.</source> -<target></target> +<target>Dosyaların aynı olup olmadığı, içeriklerine göre belirlensin.</target> <source>Symbolic links:</source> -<target></target> +<target>Sembolik bağlantılar:</target> <source>More information</source> -<target></target> +<target>Ek bilgilere bakın</target> <source>OK</source> <target>Tamam</target> <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> -<target>İki taraftaki değişiklikler belirlenir ve kopyalanır. Silme, taşıma ve çakışmalar, veritabanı kullanılarak kendiliğinden algılanır.</target> +<target>İki taraftaki değişiklikler belirlenir ve kopyalanır. Silinme, taşınma ve çakışmalar, veritabanı kullanılarak kendiliğinden algılanır.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target></target> +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target>Sağ klasör, sola uyacak şekilde değiştirilerek, sol klasörün yansı yedeği oluşturulur.</target> <source>Copy new and updated files to the right folder.</source> -<target></target> +<target>Sol taraftaki yeni ya da güncellenmiş dosyalar sağ tarafa kopyalanır.</target> <source>Configure your own synchronization rules.</source> -<target>Eşleştirme kurallarını istediğiniz şekilde ayarlayabilirsiniz.</target> +<target>Eşleştirme kuralları kullanıcının isteğine göre belirlenir.</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> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target> +- Veritabanı dosyalarını kullanılır ve oluşturulur +- Algılama, ilk eşleştirmeden sonra kullanılabilir +- Tüm dosya sistemleri tarafından desteklenmez +</target> <source>Delete files:</source> -<target></target> +<target>Dosya silme işlemi:</target> <source>Permanent</source> -<target>Kalıcı olarak silinsin</target> +<target>Kalıcı olarak</target> <source>Delete or overwrite files permanently</source> <target>Dosyalar kalıcı olarak silinir ya da üzerine yazılır</target> @@ -830,28 +840,28 @@ Komut şu durumlarda yürütülür: <target>Geri Dönüşüm Kutusuna atılsın</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> +<target>Silinen ya da üzerine yazılan dosyalar geri dönüşüm kutusuna gönderilir</target> <source>Versioning</source> <target>Eski sürüm olarak saklansı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> +<target>Dosyalar kullanıcı tarafından belirtilen bir klasöre taşınır</target> <source>Naming convention:</source> <target>Adlandırma kuralı:</target> <source>Show examples</source> -<target></target> +<target>Örneklere bakın</target> <source>Handle errors:</source> -<target></target> +<target>Hata olursa:</target> <source>Ignore</source> <target>Yoksayılsın</target> <source>Hide all error and warning messages</source> -<target>Tüm hata ve uyarı iletileri gizlenir</target> +<target>Hiçbir hata ve uyarı iletisi görüntülenmez</target> <source>Pop-up</source> <target>Görüntülensin</target> @@ -860,19 +870,19 @@ Komut şu durumlarda yürütülür: <target>Hata ya da uyarılar açılır pencerede görüntülenir</target> <source>On completion:</source> -<target></target> +<target>Tamamlandığında:</target> <source>Start synchronization now?</source> -<target></target> +<target>Eşleştirme başlatılsın mı?</target> <source>Variant:</source> -<target></target> +<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> +<target>Bu pencere bir daha &görüntülenmesin</target> <source>Items found:</source> <target>Bulunan öge:</target> @@ -899,64 +909,64 @@ Komut şu durumlarda yürütülür: <target>&Duraklatılsın</target> <source>Stop</source> -<target></target> +<target>Durdurulsun</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> +<target>Hiç bir soru sorulmadan eşleştirme yapılması için bir toplu iş dosyası oluşturun. İşlemi başlatmak için bu dosyaya çift tıklayın ya da bir görev zamanlayıcıya şu şekilde ekleyin: %x</target> <source>Stop synchronization at first error</source> -<target></target> +<target>Oluşacak ilk hatada eşleştirme durdurulur</target> <source>Show progress dialog</source> <target>İşlem penceresi görüntülensin</target> <source>Save log:</source> -<target></target> +<target>Günlüğe kaydedilsin:</target> <source>Limit:</source> -<target></target> +<target>Sınır:</target> <source>Limit maximum number of log files</source> <target>Tutulacak en fazla günlük dosyası sayısı</target> <source>How can I schedule a batch job?</source> -<target></target> +<target>Bir toplu işlem nasıl zamanlanır?</target> <source>&Recycle bin</source> -<target></target> +<target>Ge&ri Dönüşüm Kutusu</target> <source>Delete on both sides</source> <target>Her iki taraftaki de silinsin</target> <source>Delete on both sides even if the file is selected on one side only</source> -<target>Dosya yalnız bir tarafta seçili olsa bile her iki taraftaki de silinir</target> +<target>Dosya yalnız bir tarafta seçili olsa bile her iki taraftan da silinir</target> <source>Select filter rules to exclude certain files from synchronization. Enter file paths relative to their corresponding folder pair.</source> -<target></target> +<target>Eşleştirmeye katılmayacak dosyaların süzülme kurallarını belirleyin. Dosya yollarını bulundukları klasör çiftine göre yazın.</target> <source>Include:</source> -<target></target> +<target>Katılacak ögeler:</target> <source>Exclude:</source> -<target></target> +<target>Katılmayacak ögeler</target> <source>Time span:</source> -<target></target> +<target>Zaman aralığı:</target> <source>File size:</source> -<target></target> +<target>Dosya boyutu:</target> <source>Minimum:</source> -<target></target> +<target>En küçük:</target> <source>Maximum:</source> -<target></target> +<target>En büyük:</target> <source>&Clear</source> <target>&Temizleyin</target> <source>The following settings are used for all synchronization jobs.</source> -<target></target> +<target>Aşağıdaki ayarlar tüm eşleştirme işlemleri için geçerlidir.</target> <source>Fail-safe file copy</source> <target>Dosyalar hatasız kopyalansın</target> @@ -965,43 +975,46 @@ Komut şu durumlarda yürütülür: Copy to a temporary file (*.ffs_tmp) before overwriting target. This guarantees a consistent state even in case of a serious error. </source> -<target></target> +<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ı olarak yapılmasını sağlar. +</target> <source>(recommended)</source> -<target></target> +<target>(önerilir)</target> <source>Copy locked files</source> <target>Kilitli dosyalar da kopyalansın</target> <source>Copy shared or locked files using the Volume Shadow Copy Service.</source> -<target></target> +<target>Paylaşılan ya da kilitlenmiş dosyalar Birim Gölge Hizmetini kullanılarak kopyalanır.</target> <source>(requires administrator rights)</source> -<target></target> +<target>(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.</source> -<target></target> +<target>Dosya ve klasör izinleri de aktarılır.</target> <source>Automatic retry on error:</source> -<target></target> +<target>Hata oluşursa yeniden denensin:</target> <source>Retry count:</source> -<target></target> +<target>Deneme sayısı:</target> <source>Delay (in seconds):</source> -<target></target> +<target>Bekleme (saniye):</target> <source>Customize context menu:</source> -<target></target> +<target>Sağ tık menüsünü özelleştirin:</target> <source>Description</source> <target>Açıklama</target> <source>Restore hidden windows</source> -<target></target> +<target>Gizlenmiş pencereler yeniden görüntülensin</target> <source>&Default</source> <target>&Varsayılan</target> @@ -1031,23 +1044,26 @@ This guarantees a consistent state even in case of a serious error. <target>Çeviriler için çok teşekkürler:</target> <source>Save as Batch Job</source> -<target></target> +<target>Toplu İş Olarak Kaydedin</target> <source>Delete Items</source> -<target></target> +<target>Ögeleri Silin</target> <source>Global Settings</source> -<target></target> +<target>Genel Ayarlar</target> <source>Select Time Span</source> -<target></target> +<target>Zaman Aralığı</target> <source>Folder Pairs</source> -<target></target> +<target>Klasör Çiftleri</target> <source>Find</source> <target>Arayın</target> +<source>Select View</source> +<target>Görünümü Seçin</target> + <source>Overview</source> <target>Genel</target> @@ -1055,13 +1071,7 @@ This guarantees a consistent state even in case of a serious error. <target>İşlemler</target> <source>Main Bar</source> -<target></target> - -<source>Filter Files</source> -<target></target> - -<source>Select View</source> -<target></target> +<target>Ana Çubuk</target> <source>Open...</source> <target>Açın...</target> @@ -1070,7 +1080,7 @@ This guarantees a consistent state even in case of a serious error. <target>Kaydedin</target> <source>Compare both sides</source> -<target>İki tarafı karşılaştırır</target> +<target>İki tarafı karşılaştırın</target> <source>Comparison settings</source> <target>Karşılaştırma ayarları</target> @@ -1089,6 +1099,8 @@ This guarantees a consistent state even in case of a serious error. <pluralform>Do you really want to execute the command %y for %x items?</pluralform> </source> <target> +<pluralform>Bir ö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>&Execute</source> @@ -1113,8 +1125,8 @@ This guarantees a consistent state even in case of a serious error. </target> <source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> </source> <target> <pluralform>%y / 1 satır görüntüleniyor</pluralform> @@ -1131,7 +1143,7 @@ This guarantees a consistent state even in case of a serious error. <target>Şu süzgeçle katılsın:</target> <source>Exclude via filter:</source> -<target>Süzerek dışarda bırakılsın:</target> +<target>Şu süzgeçle katılmasın:</target> <source>Exclude temporarily</source> <target>Geçici olarak katılmasın</target> @@ -1167,7 +1179,7 @@ This guarantees a consistent state even in case of a serious error. <target>Varsayılan görünüm</target> <source>Show "%x"</source> -<target>"%x" panelini görüntülensin</target> +<target>"%x" paneli görüntülensin</target> <source>Last session</source> <target>Önceki oturum</target> @@ -1235,6 +1247,9 @@ This guarantees a consistent state even in case of a serious error. <source>Show files that won't be copied</source> <target>Kopyalanmayacak dosyalar görüntülensin</target> +<source>Show filtered or temporarily excluded files</source> +<target>Süzülmüş ya da geçici olarak katılmayan dosyalar görüntülensin</target> + <source>Set as default</source> <target>Varsayılan olarak belirleyin</target> @@ -1242,10 +1257,10 @@ This guarantees a consistent state even in case of a serious error. <target>Tüm klasörler eşleştirildi</target> <source>Synchronization Settings</source> -<target></target> +<target>Eşleştirme Ayarları</target> <source>Comparison Settings</source> -<target></target> +<target>Karşılaştırma Ayarları</target> <source>Cannot find %x</source> <target>%x bulunamadı</target> @@ -1271,6 +1286,9 @@ This guarantees a consistent state even in case of a serious error. <source>Warning</source> <target>Uyarı</target> +<source>Select all</source> +<target>Tümünü seçin</target> + <source>Paused</source> <target>Duraklatıldı</target> @@ -1278,7 +1296,7 @@ This guarantees a consistent state even in case of a serious error. <target>Başlatılıyor...</target> <source>Stopped</source> -<target></target> +<target>Durduruldu</target> <source>Completed</source> <target>Tamamlandı</target> @@ -1323,31 +1341,31 @@ This guarantees a consistent state even in case of a serious error. </target> <source>Move</source> -<target></target> +<target>Atılsın</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> <target> -<pluralform>Aşağıdaki 1 ögeyi silmek istediğinize emin misiniz?</pluralform> +<pluralform>Aşağıdaki ögeyi silmek istediğinize emin misiniz?</pluralform> <pluralform>Aşağıdaki %x ögeyi silmek istediğinize emin misiniz?</pluralform> </target> <source>Exclude</source> -<target>Katılmayacak ögeler</target> +<target>Katılmasın</target> <source>Direct</source> -<target>Doğrudan katılsın</target> +<target>Doğrudan</target> <source>Follow</source> -<target>Hedefleri katılsın</target> +<target>Hedefler</target> <source>Copy NTFS permissions</source> <target>NTFS izinleri de kopyalansın</target> <source>Integrate external applications into context menu. The following macros are available:</source> -<target>Sağ tık menüsüne dış uygulamalar ekler. Şu etiketler kullanılabilir:</target> +<target>Sağ tık menüsüne dış uygulamalar eklenebilir. Şu etiketler kullanılabilir:</target> <source>- full file or folder name</source> <target>- tam dosya ya da klasör adı</target> @@ -1362,7 +1380,7 @@ This guarantees a consistent state even in case of a serious error. <target>%item_folder% ögesinin diğer taraftaki karşılığı</target> <source>Restore all hidden windows and warnings?</source> -<target></target> +<target>Gizlenmiş tüm pencere ve uyarılar yeniden görüntülensin mi?</target> <source>Leave as unresolved conflict</source> <target>Uyuşmazlık çözülmeden bırakılsın</target> @@ -1374,7 +1392,7 @@ This guarantees a consistent state even in case of a serious error. <target>Dosyalar taşınsın ve varsa üzerine yazılsın</target> <source>Time stamp</source> -<target>Zaman Damgası</target> +<target>Zaman damgası</target> <source>Append a timestamp to each file name</source> <target>Dosya adlarına zaman damgası eklensin</target> @@ -1407,7 +1425,7 @@ This guarantees a consistent state even in case of a serious error. <target>Dosya başka bir işlem tarafından kilitlenmiş:</target> <source>Cannot move file %x to %y.</source> -<target>%x dosyası %y olarak taşınamadı.</target> +<target>%x dosyası %y üzerine taşınamadı.</target> <source>Cannot delete directory %x.</source> <target>%x klasörü silinemedi.</target> @@ -1488,13 +1506,13 @@ This guarantees a consistent state even in case of a serious error. </target> <source>Unable to register to receive system messages.</source> -<target></target> +<target>Sistem iletilerini alabilmek için gerekli kayıt eklenemedi.</target> <source>Cannot set privilege %x.</source> <target>%x izni verilemedi.</target> <source>Unable to suspend system sleep mode.</source> -<target></target> +<target>Sistem uyku kipine geçirilemedi.</target> <source>Cannot change process I/O priorities.</source> <target>Giriş/Çıkış işlemi öncelikleri değiştirilemedi</target> diff --git a/FreeFileSync/Build/Languages/ukrainian.lng b/FreeFileSync/Build/Languages/ukrainian.lng index af819d76..47246650 100644 --- a/FreeFileSync/Build/Languages/ukrainian.lng +++ b/FreeFileSync/Build/Languages/ukrainian.lng @@ -7,6 +7,52 @@ <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>Select all</source> +<target></target> + +<source> +<pluralform>Showing %y of 1 row</pluralform> +<pluralform>Showing %y of %x rows</pluralform> +</source> +<target></target> + +<source> +<pluralform>Do you really want to execute the command %y for one item?</pluralform> +<pluralform>Do you really want to execute the command %y for %x items?</pluralform> +</source> +<target></target> + +<source> +- Requires and creates database files +- Detection active after initial sync +- Not supported by all file systems +</source> +<target></target> + +<source>Create a mirror backup of the left folder by adapting the right folder to match.</source> +<target></target> + +<source>&Check</source> +<target></target> + +<source>Retrying operation...</source> +<target></target> + +<source> +<pluralform>Automatic retry in 1 second...</pluralform> +<pluralform>Automatic retry in %x seconds...</pluralform> +</source> +<target></target> + +<source>Detecting abandoned lock...</source> +<target></target> + +<source>Lock owner:</source> +<target></target> + +<source>Waiting while directory is locked:</source> +<target></target> + <source>Both sides have changed since last synchronization.</source> <target>З моменту останньої синхронізації з обох сторін відбулися зміни.</target> @@ -91,18 +137,18 @@ <source>Any number of alternative directories for at most one config file.</source> <target>Будь-яка кількість альтернативних каталогів для щонайбільше одного конфігураційного файлу.</target> -<source>A folder input field is empty.</source> -<target>Порожнє поле папки.</target> - -<source>The corresponding folder will be considered as empty.</source> -<target>Відповідна папка буде вважатися порожньою.</target> - <source>Cannot find the following folders:</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>A folder input field is empty.</source> +<target>Порожнє поле папки.</target> + +<source>The corresponding folder will be considered as empty.</source> +<target>Відповідна папка буде вважатися порожньою.</target> + <source>The following folders have dependent paths. Be careful when setting up synchronization rules:</source> <target>Наступні папки мають залежні шляхи. Будьте обережні при налаштуванні правил синхронізації:</target> @@ -223,9 +269,6 @@ <source>Cannot get process information.</source> <target>Не вдається отримати інформацію процесу</target> -<source>Waiting while directory is locked (%x)...</source> -<target>Очікування зняття блокування з каталогу (%x)...</target> - <source> <pluralform>1 sec</pluralform> <pluralform>%x sec</pluralform> @@ -492,6 +535,12 @@ The command is triggered if: <source>Updating attributes of %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>Cannot find %x.</source> <target>Не вдається знайти %x.</target> @@ -531,12 +580,6 @@ The command is triggered if: <source>Generating database...</source> <target>Створення бази даних...</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> @@ -573,19 +616,9 @@ The command is triggered if: <source>Switching to FreeFileSync's main window</source> <target>Перехід до головного вікна FreeFileSync</target> -<source> -<pluralform>Automatic retry in 1 second...</pluralform> -<pluralform>Automatic retry in %x seconds...</pluralform> -</source> -<target> -</target> - <source>&Ignore subsequent errors</source> <target>&Ігнорувати наступні помилки</target> -<source>Retrying operation...</source> -<target></target> - <source>Serious Error</source> <target>Серйозна помилка</target> @@ -610,9 +643,6 @@ The command is triggered if: <source>Cannot find current FreeFileSync version number online. Do you want to check manually?</source> <target>Не вдається знайти номер поточної версії FreeFileSync онлайн. Бажаєте перевірити вручну?</target> -<source>&Check</source> -<target></target> - <source>Symlink</source> <target>Символьне посилання</target> @@ -769,12 +799,6 @@ The command is triggered if: <source>Save as batch job</source> <target>Зберегти як пакетне завдання</target> -<source>Hide excluded items</source> -<target>Приховати виключені елементи</target> - -<source>Show filtered or temporarily excluded files</source> -<target>Показати відфільтровані чи тимчасово виключені елементи</target> - <source>Number of files and folders that will be created</source> <target>Кількість файлів і папок, які будуть створені</target> @@ -808,9 +832,6 @@ The command is triggered if: <source>Identify and propagate changes on both sides. Deletions, moves and conflicts are detected automatically using a database.</source> <target>Виявити та поширити зміни на обидві сторони. Видалення, перейменування та конфлікти визначаються автоматично використовуючи базу даних.</target> -<source>Create a mirror backup of the left folder which exactly matches the right folder after synchronization.</source> -<target>Створити дзеркальну копію лівої частини, після синхронізації права папка повністю дорівнюватиме лівій.</target> - <source>Copy new and updated files to the right folder.</source> <target>Скопіювати нові та оновлені файли в праву папку.</target> @@ -820,9 +841,6 @@ The command is triggered if: <source>Detect moved files</source> <target>Виявляти переміщені файли</target> -<source>Requires database files. Not supported by all file systems.</source> -<target>Потрібні файли бази даних. Підтримується не всіма файловими системами.</target> - <source>Delete files:</source> <target>Вилучити файли:</target> @@ -1057,6 +1075,9 @@ This guarantees a consistent state even in case of a serious error. <source>Find</source> <target>Знайти</target> +<source>Select View</source> +<target>Вибрати перегляд</target> + <source>Overview</source> <target>Головна</target> @@ -1066,12 +1087,6 @@ This guarantees a consistent state even in case of a serious error. <source>Main Bar</source> <target>Головна панель</target> -<source>Filter Files</source> -<target>Фільтрування файлів</target> - -<source>Select View</source> -<target>Вибрати перегляд</target> - <source>Open...</source> <target>Відкрити...</target> @@ -1093,13 +1108,6 @@ This guarantees a consistent state even in case of a serious error. <source>Confirm</source> <target>Підтвердити</target> -<source> -<pluralform>Do you really want to execute the command %y for one item?</pluralform> -<pluralform>Do you really want to execute the command %y for %x items?</pluralform> -</source> -<target> -</target> - <source>&Execute</source> <target>&Виконати</target> @@ -1123,16 +1131,6 @@ This guarantees a consistent state even in case of a serious error. <pluralform>%x файлів</pluralform> </target> -<source> -<pluralform>%y of 1 row in view</pluralform> -<pluralform>%y of %x rows in view</pluralform> -</source> -<target> -<pluralform>%y of %x рядка</pluralform> -<pluralform>%y of %x рядків</pluralform> -<pluralform>%y of %x рядків</pluralform> -</target> - <source>Set direction:</source> <target>Виберіть напрям:</target> @@ -1247,6 +1245,9 @@ This guarantees a consistent state even in case of a serious error. <source>Show files that won't be copied</source> <target>Показати файли, які не будуть зкопійовані</target> +<source>Show filtered or temporarily excluded files</source> +<target>Показати відфільтровані чи тимчасово виключені елементи</target> + <source>Set as default</source> <target>Встановити за замовчуванням</target> diff --git a/FreeFileSync/Build/Resources.zip b/FreeFileSync/Build/Resources.zip Binary files differindex ee52f047..847beb78 100644 --- a/FreeFileSync/Build/Resources.zip +++ b/FreeFileSync/Build/Resources.zip diff --git a/FreeFileSync/Source/FreeFileSync.vcxproj b/FreeFileSync/Source/FreeFileSync.vcxproj index cba18010..2417efc1 100644 --- a/FreeFileSync/Source/FreeFileSync.vcxproj +++ b/FreeFileSync/Source/FreeFileSync.vcxproj @@ -110,7 +110,7 @@ <SubSystem>Windows</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <AdditionalDependencies>Rpcrt4.lib;winmm.lib;comctl32.lib;Wininet.lib;wxmsw29ud_aui.lib;wxmsw29ud_adv.lib;wxmsw29ud_core.lib;wxbase29ud_net.lib;wxbase29ud.lib;wxpngd.lib;wxzlibd.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>Rpcrt4.lib;winmm.lib;comctl32.lib;Wininet.lib;wxmsw30ud_aui.lib;wxmsw30ud_adv.lib;wxmsw30ud_core.lib;wxbase30ud_net.lib;wxbase30ud.lib;wxpngd.lib;wxzlibd.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>C:\Data\C++\Boost\stage\lib;C:\Data\C++\wxWidgets\lib\vc12_x86_debug_dll</AdditionalLibraryDirectories> </Link> <ResourceCompile> @@ -137,7 +137,7 @@ <SubSystem>Windows</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <AdditionalDependencies>Rpcrt4.lib;winmm.lib;comctl32.lib;Wininet.lib;wxmsw29ud_aui.lib;wxmsw29ud_adv.lib;wxmsw29ud_core.lib;wxbase29ud_net.lib;wxbase29ud.lib;wxpngd.lib;wxzlibd.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>Rpcrt4.lib;winmm.lib;comctl32.lib;Wininet.lib;wxmsw30ud_aui.lib;wxmsw30ud_adv.lib;wxmsw30ud_core.lib;wxbase30ud_net.lib;wxbase30ud.lib;wxpngd.lib;wxzlibd.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>C:\Data\C++\Boost\stage_x64\lib;C:\Data\C++\wxWidgets\lib\vc12_x64_debug_dll</AdditionalLibraryDirectories> </Link> <ResourceCompile> @@ -160,7 +160,7 @@ </ClCompile> <Link> <SubSystem>Windows</SubSystem> - <AdditionalDependencies>Rpcrt4.lib;winmm.lib;comctl32.lib;Wininet.lib;wxmsw29u_aui.lib;wxmsw29u_adv.lib;wxmsw29u_core.lib;wxbase29u.lib;wxpng.lib;wxzlib.lib;wxbase29u_net.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>Rpcrt4.lib;winmm.lib;comctl32.lib;Wininet.lib;wxmsw30u_aui.lib;wxmsw30u_adv.lib;wxmsw30u_core.lib;wxbase30u.lib;wxpng.lib;wxzlib.lib;wxbase30u_net.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <AdditionalLibraryDirectories>C:\Data\C++\Boost\stage\lib;C:\Data\C++\wxWidgets\lib\vc12_x86_release_lib</AdditionalLibraryDirectories> </Link> @@ -187,7 +187,7 @@ <Link> <SubSystem>Windows</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>Rpcrt4.lib;winmm.lib;comctl32.lib;Wininet.lib;wxmsw29u_aui.lib;wxmsw29u_adv.lib;wxmsw29u_core.lib;wxbase29u.lib;wxpng.lib;wxzlib.lib;wxbase29u_net.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>Rpcrt4.lib;winmm.lib;comctl32.lib;Wininet.lib;wxmsw30u_aui.lib;wxmsw30u_adv.lib;wxmsw30u_core.lib;wxbase30u.lib;wxpng.lib;wxzlib.lib;wxbase30u_net.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <AdditionalLibraryDirectories>C:\Data\C++\Boost\stage_x64\lib;C:\Data\C++\wxWidgets\lib\vc12_x64_release_lib</AdditionalLibraryDirectories> </Link> diff --git a/FreeFileSync/Source/Makefile b/FreeFileSync/Source/Makefile index 919328f2..19057c79 100644 --- a/FreeFileSync/Source/Makefile +++ b/FreeFileSync/Source/Makefile @@ -42,9 +42,9 @@ 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/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 +WX_CONFIG_BIN =$(HOME)/Desktop/wxWidgets/lib/release/bin/wx-config +CXXFLAGS += -I$(HOME)/Desktop/boost +BOOST_LIB_DIR =$(HOME)/Desktop/boost/stage/lib CXXFLAGS += `$(WX_CONFIG_BIN) --cxxflags --debug=no --static=yes` LINKFLAGS += `$(WX_CONFIG_BIN) --libs std, aui --debug=no --static=yes` $(BOOST_LIB_DIR)/libboost_thread.a $(BOOST_LIB_DIR)/libboost_system.a -lX11 @@ -56,9 +56,9 @@ ifeq ($(OPERATING_SYSTEM_NAME), Darwin) COMPILER_BIN=clang++ -stdlib=libc++ CXXFLAGS += -DZEN_MAC -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 +WX_CONFIG_BIN =$(HOME)/Desktop/wxWidgets/lib/release/bin/wx-config +CXXFLAGS += -I$(HOME)/Desktop/boost +BOOST_LIB_DIR =$(HOME)/Desktop/boost/stage/lib MACOS_SDK =-mmacosx-version-min=10.7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk #-Wl,-Bstatic not supported on OSX! diff --git a/FreeFileSync/Source/RealtimeSync/Makefile b/FreeFileSync/Source/RealtimeSync/Makefile index 3ce0a764..f40a4561 100644 --- a/FreeFileSync/Source/RealtimeSync/Makefile +++ b/FreeFileSync/Source/RealtimeSync/Makefile @@ -25,9 +25,9 @@ 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/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 +WX_CONFIG_BIN =$(HOME)/Desktop/wxWidgets/lib/release/bin/wx-config +CXXFLAGS += -I$(HOME)/Desktop/boost +BOOST_LIB_DIR =$(HOME)/Desktop/boost/stage/lib CXXFLAGS += `$(WX_CONFIG_BIN) --cxxflags --debug=no --static=yes` LINKFLAGS += `$(WX_CONFIG_BIN) --libs --debug=no --static=yes` $(BOOST_LIB_DIR)/libboost_thread.a $(BOOST_LIB_DIR)/libboost_system.a -lX11 @@ -39,9 +39,9 @@ ifeq ($(OPERATING_SYSTEM_NAME), Darwin) COMPILER_BIN=clang++ -stdlib=libc++ CXXFLAGS += -DZEN_MAC -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 +WX_CONFIG_BIN =$(HOME)/Desktop/wxWidgets/lib/release/bin/wx-config +CXXFLAGS += -I$(HOME)/Desktop/boost +BOOST_LIB_DIR =$(HOME)/Desktop/boost/stage/lib MACOS_SDK =-mmacosx-version-min=10.7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk #-Wl,-Bstatic not supported on OSX! diff --git a/FreeFileSync/Source/RealtimeSync/RealtimeSync.vcxproj b/FreeFileSync/Source/RealtimeSync/RealtimeSync.vcxproj index 9344fb4b..bc04423f 100644 --- a/FreeFileSync/Source/RealtimeSync/RealtimeSync.vcxproj +++ b/FreeFileSync/Source/RealtimeSync/RealtimeSync.vcxproj @@ -110,7 +110,7 @@ <SubSystem>Windows</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <AdditionalDependencies>comctl32.lib;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> + <AdditionalDependencies>comctl32.lib;wxmsw30ud_adv.lib;wxmsw30ud_core.lib;wxbase30ud.lib;wxpngd.lib;wxzlibd.lib;wxbase30ud_net.lib;comctl32.lib;ws2_32.lib;Rpcrt4.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>C:\Data\C++\Boost\stage\lib;C:\Data\C++\wxWidgets\lib\vc12_x86_debug_dll</AdditionalLibraryDirectories> </Link> <ResourceCompile> @@ -138,7 +138,7 @@ <SubSystem>Windows</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> - <AdditionalDependencies>comctl32.lib;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> + <AdditionalDependencies>comctl32.lib;wxmsw30ud_adv.lib;wxmsw30ud_core.lib;wxbase30ud.lib;wxpngd.lib;wxzlibd.lib;wxbase30ud_net.lib;comctl32.lib;ws2_32.lib;Rpcrt4.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>C:\Data\C++\Boost\stage_x64\lib;C:\Data\C++\wxWidgets\lib\vc12_x64_debug_dll</AdditionalLibraryDirectories> </Link> <ResourceCompile> @@ -163,7 +163,7 @@ </ClCompile> <Link> <SubSystem>Windows</SubSystem> - <AdditionalDependencies>comctl32.lib;wxmsw29u_adv.lib;wxbase29u_net.lib;wxbase29u.lib;wxmsw29u_core.lib;wxpng.lib;wxzlib.lib;ws2_32.lib;winmm.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>comctl32.lib;wxmsw30u_adv.lib;wxbase30u_net.lib;wxbase30u.lib;wxmsw30u_core.lib;wxpng.lib;wxzlib.lib;ws2_32.lib;winmm.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <AdditionalLibraryDirectories>C:\Data\C++\Boost\stage\lib;C:\Data\C++\wxWidgets\lib\vc12_x86_release_lib</AdditionalLibraryDirectories> </Link> @@ -191,7 +191,7 @@ </ClCompile> <Link> <SubSystem>Windows</SubSystem> - <AdditionalDependencies>comctl32.lib;wxmsw29u_adv.lib;wxbase29u_net.lib;wxbase29u.lib;wxmsw29u_core.lib;wxpng.lib;wxzlib.lib;ws2_32.lib;winmm.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>comctl32.lib;wxmsw30u_adv.lib;wxbase30u_net.lib;wxbase30u.lib;wxmsw30u_core.lib;wxpng.lib;wxzlib.lib;ws2_32.lib;winmm.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <AdditionalLibraryDirectories>C:\Data\C++\Boost\stage_x64\lib;C:\Data\C++\wxWidgets\lib\vc12_x64_release_lib</AdditionalLibraryDirectories> </Link> diff --git a/FreeFileSync/Source/RealtimeSync/gui_generated.cpp b/FreeFileSync/Source/RealtimeSync/gui_generated.cpp index 3b3ad3fe..4de8a612 100644 --- a/FreeFileSync/Source/RealtimeSync/gui_generated.cpp +++ b/FreeFileSync/Source/RealtimeSync/gui_generated.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 8 2012) +// C++ code generated with wxFormBuilder (version Nov 6 2013) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! diff --git a/FreeFileSync/Source/RealtimeSync/gui_generated.h b/FreeFileSync/Source/RealtimeSync/gui_generated.h index a816e10a..cb0c0cc5 100644 --- a/FreeFileSync/Source/RealtimeSync/gui_generated.h +++ b/FreeFileSync/Source/RealtimeSync/gui_generated.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 8 2012) +// C++ code generated with wxFormBuilder (version Nov 6 2013) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! diff --git a/FreeFileSync/Source/RealtimeSync/main_dlg.cpp b/FreeFileSync/Source/RealtimeSync/main_dlg.cpp index ee3e7dda..519ca555 100644 --- a/FreeFileSync/Source/RealtimeSync/main_dlg.cpp +++ b/FreeFileSync/Source/RealtimeSync/main_dlg.cpp @@ -196,7 +196,7 @@ void MainDialog::OnMenuAbout(wxCommandEvent& event) #error what is going on? #endif - build += zen::is64BitBuild ? L" x64" : L" x86"; + build += zen::is64BitBuild ? L" x64" : L" x86"; assert_static(zen::is32BitBuild || zen::is64BitBuild); showNotificationDialog(this, DialogInfoType::INFO, PopupDialogCfg(). diff --git a/FreeFileSync/Source/RealtimeSync/monitor.cpp b/FreeFileSync/Source/RealtimeSync/monitor.cpp index 23473857..5ac74884 100644 --- a/FreeFileSync/Source/RealtimeSync/monitor.cpp +++ b/FreeFileSync/Source/RealtimeSync/monitor.cpp @@ -54,7 +54,7 @@ struct WaitResult WaitResult waitForChanges(const std::vector<Zstring>& dirnamePhrases, //throw FileError - const std::function<void(bool)>& onRefreshGui) //bool: readyForSync + const std::function<void(bool readyForSync)>& onRefreshGui) { const std::vector<Zstring> dirNamesFmt = getFormattedDirs(dirnamePhrases); //throw FileError if (dirNamesFmt.empty()) //pathological case, but we have to check else this function will wait endlessly @@ -148,7 +148,7 @@ WaitResult waitForChanges(const std::vector<Zstring>& dirnamePhrases, //throw Fi //wait until all directories become available (again) + logs in network share void waitForMissingDirs(const std::vector<Zstring>& dirnamePhrases, //throw FileError - const std::function<void(const Zstring&)>& onRefreshGui) //Zstring: the directory that is currently being waited for + const std::function<void(const Zstring& dirname)>& onRefreshGui) { while (true) { diff --git a/FreeFileSync/Source/algorithm.cpp b/FreeFileSync/Source/algorithm.cpp index 04d56490..5f7f4abe 100644 --- a/FreeFileSync/Source/algorithm.cpp +++ b/FreeFileSync/Source/algorithm.cpp @@ -204,7 +204,7 @@ bool isEqual(const FilePair& fileObj, const InSyncDir::FileList::value_type* dbF else if (!dbFile) return false; - const Zstring& shortNameDb = dbFile->first; + const Zstring& shortNameDb = dbFile->first; const InSyncDescrFile& descrDb = getDescriptor<side>(dbFile->second); return fileObj.getShortName<side>() == shortNameDb && //detect changes in case (windows) @@ -217,7 +217,7 @@ bool isEqual(const FilePair& fileObj, const InSyncDir::FileList::value_type* dbF //check whether database entry is in sync considering *current* comparison settings inline -bool stillInSync(const InSyncFile& dbFile, CompareVariant compareVar, size_t fileTimeTolerance) +bool stillInSync(const InSyncFile& dbFile, CompareVariant compareVar, int fileTimeTolerance) { switch (compareVar) { @@ -225,8 +225,8 @@ bool stillInSync(const InSyncFile& dbFile, CompareVariant compareVar, size_t fil 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; - //dbFile.left.fileSize == dbFile.right.fileSize; + sameFileTime(dbFile.left.lastWriteTimeRaw, dbFile.right.lastWriteTimeRaw, fileTimeTolerance); + //dbFile.left.fileSize == dbFile.right.fileSize; case CMP_BY_CONTENT: //case-sensitive short name match is a database invariant! @@ -255,7 +255,7 @@ bool isEqual(const SymlinkPair& linkObj, const InSyncDir::LinkList::value_type* else if (!dbLink) return false; - const Zstring& shortNameDb = dbLink->first; + const Zstring& shortNameDb = dbLink->first; const InSyncDescrLink& descrDb = getDescriptor<side>(dbLink->second); return linkObj.getShortName<side>() == shortNameDb && @@ -266,7 +266,7 @@ bool isEqual(const SymlinkPair& linkObj, const InSyncDir::LinkList::value_type* //check whether database entry is in sync considering *current* comparison settings inline -bool stillInSync(const InSyncSymlink& dbLink, CompareVariant compareVar, size_t fileTimeTolerance) +bool stillInSync(const InSyncSymlink& dbLink, CompareVariant compareVar, int fileTimeTolerance) { switch (compareVar) { @@ -274,7 +274,7 @@ bool stillInSync(const InSyncSymlink& dbLink, CompareVariant compareVar, size_t 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; + sameFileTime(dbLink.left.lastWriteTimeRaw, dbLink.right.lastWriteTimeRaw, fileTimeTolerance); case CMP_BY_CONTENT: //case-sensitive short name match is a database invariant! @@ -410,7 +410,7 @@ private: } const CompareVariant cmpVar; - const size_t fileTimeTolerance; + const int 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! @@ -605,7 +605,7 @@ private: const std::wstring txtDbNotInSync; const CompareVariant cmpVar; - const size_t fileTimeTolerance; + const int fileTimeTolerance; }; } @@ -631,7 +631,7 @@ std::vector<DirectionConfig> zen::extractDirectionCfg(const MainConfiguration& m } -void zen::redetermineSyncDirection(const DirectionConfig& dirCfg, BaseDirPair& baseDirectory, std::function<void(const std::wstring&)> reportWarning) +void zen::redetermineSyncDirection(const DirectionConfig& dirCfg, BaseDirPair& baseDirectory, std::function<void(const std::wstring& msg)> reportWarning) { //try to load sync-database files std::shared_ptr<InSyncDir> lastSyncState; @@ -668,7 +668,7 @@ void zen::redetermineSyncDirection(const DirectionConfig& dirCfg, BaseDirPair& b } -void zen::redetermineSyncDirection(const MainConfiguration& mainCfg, FolderComparison& folderCmp, std::function<void(const std::wstring&)> reportWarning) +void zen::redetermineSyncDirection(const MainConfiguration& mainCfg, FolderComparison& folderCmp, std::function<void(const std::wstring& msg)> reportWarning) { if (folderCmp.empty()) return; @@ -1225,7 +1225,7 @@ template <SelectedSide side> struct ItemDeleter : public FSObjectVisitor //throw FileError, but nothrow constructor!!! { ItemDeleter(bool useRecycleBin, DeleteFilesHandler& handler) : - handler_(handler), useRecycleBin_(useRecycleBin), remCallback(*this) + handler_(handler), useRecycleBin_(useRecycleBin) { if (useRecycleBin_) { @@ -1268,26 +1268,20 @@ struct ItemDeleter : public FSObjectVisitor //throw FileError, but nothrow cons virtual void visit(const DirPair& dirObj) { - notifyDirectoryDeletion(dirObj.getFullName<side>()); //notfied twice! see RemoveCallbackImpl -> no big deal + notifyDirectoryDeletion(dirObj.getFullName<side>()); //notfied twice; see below -> no big deal if (useRecycleBin_) zen::recycleOrDelete(dirObj.getFullName<side>()); //throw FileError else - zen::removeDirectory(dirObj.getFullName<side>(), &remCallback); //throw FileError + { + auto onBeforeFileDeletion = [&](const Zstring& filename) { this->notifyFileDeletion (filename); }; //without "this->" GCC 4.7.2 runtime crash on Debian + auto onBeforeDirDeletion = [&](const Zstring& dirname ) { this->notifyDirectoryDeletion(dirname ); }; + + zen::removeDirectory(dirObj.getFullName<side>(), onBeforeFileDeletion, onBeforeDirDeletion); //throw FileError + } } private: - struct RemoveCallbackImpl : public zen::CallbackRemoveDir - { - RemoveCallbackImpl(ItemDeleter& itemDeleter) : itemDeleter_(itemDeleter) {} - - virtual void onBeforeFileDeletion(const Zstring& filename) { itemDeleter_.notifyFileDeletion (filename); } - virtual void onBeforeDirDeletion (const Zstring& dirname) { itemDeleter_.notifyDirectoryDeletion(dirname ); } - - private: - ItemDeleter& itemDeleter_; - }; - void notifyFileDeletion (const Zstring& objName) { notifyItemDeletion(txtRemovingFile , objName); } void notifyDirectoryDeletion(const Zstring& objName) { notifyItemDeletion(txtRemovingDirectory, objName); } void notifySymlinkDeletion (const Zstring& objName) { notifyItemDeletion(txtRemovingSymlink , objName); } @@ -1299,7 +1293,6 @@ private: DeleteFilesHandler& handler_; const bool useRecycleBin_; - RemoveCallbackImpl remCallback; std::wstring txtRemovingFile; std::wstring txtRemovingDirectory; diff --git a/FreeFileSync/Source/algorithm.h b/FreeFileSync/Source/algorithm.h index 09adb5ec..c7af2299 100644 --- a/FreeFileSync/Source/algorithm.h +++ b/FreeFileSync/Source/algorithm.h @@ -17,8 +17,8 @@ void swapGrids(const MainConfiguration& config, FolderComparison& folderCmp); std::vector<DirectionConfig> extractDirectionCfg(const MainConfiguration& mainCfg); -void redetermineSyncDirection(const DirectionConfig& directConfig, BaseDirPair& baseDirectory, std::function<void(const std::wstring&)> reportWarning); -void redetermineSyncDirection(const MainConfiguration& mainCfg, FolderComparison& folderCmp, std::function<void(const std::wstring&)> reportWarning); +void redetermineSyncDirection(const DirectionConfig& directConfig, BaseDirPair& baseDirectory, std::function<void(const std::wstring& msg)> reportWarning); +void redetermineSyncDirection(const MainConfiguration& mainCfg, FolderComparison& folderCmp, std::function<void(const std::wstring& msg)> reportWarning); void setSyncDirectionRec(SyncDirection newDirection, FileSystemObject& fsObj); //set new direction (recursively) diff --git a/FreeFileSync/Source/comparison.cpp b/FreeFileSync/Source/comparison.cpp index 2b3a37b0..c1ce317a 100644 --- a/FreeFileSync/Source/comparison.cpp +++ b/FreeFileSync/Source/comparison.cpp @@ -74,6 +74,7 @@ void determineExistentDirs(const std::vector<FolderPairCfg>& cfgList, //in for (const FolderPairCfg& fpCfg : cfgList) resolvedPairs.push_back(ResolvedFolderPair(getFormattedDirectoryName(fpCfg.dirnamePhraseLeft), getFormattedDirectoryName(fpCfg.dirnamePhraseRight))); + warn_static("get volume by name for idle HDD! => call async getFormattedDirectoryName, but currently not thread-safe") std::set<Zstring, LessFilename> dirnames; for (const ResolvedFolderPair& fp : resolvedPairs) @@ -145,54 +146,12 @@ void checkFolderDependency(const std::vector<ResolvedFolderPair>& folderPairs, b } } - -class CmpCallbackImpl : public CompareCallback -{ -public: - CmpCallbackImpl(ProcessCallback& pc, Int64& bytesReported) : - pc_(pc), - bytesReported_(bytesReported) {} - - virtual void updateCompareStatus(Int64 bytesDelta) - { - //inform about the (differential) processed amount of data - pc_.updateProcessedData(0, bytesDelta); //throw()! -> ensure client and service provider are in sync! - bytesReported_ += bytesDelta; // - - pc_.requestUiRefresh(); //may throw - } - -private: - ProcessCallback& pc_; - Int64& bytesReported_; -}; - - -bool filesHaveSameContentUpdating(const Zstring& filename1, const Zstring& filename2, Int64 expectedBytesToCmp, ProcessCallback& pc) //throw FileError -{ - Int64 bytesReported; //amount of bytes that have been compared and communicated to status handler - - //error = unexpected increase of total workload - zen::ScopeGuard guardStatistics = zen::makeGuard([&] { pc.updateTotalData(0, bytesReported); }); - - CmpCallbackImpl callback(pc, bytesReported); - bool sameContent = filesHaveSameContent(filename1, filename2, callback); //throw FileError - - guardStatistics.dismiss(); - - //update statistics to consider the real amount of data processed: consider short-cut behavior if first bytes differ! - if (bytesReported != expectedBytesToCmp) - pc.updateTotalData(0, bytesReported - expectedBytesToCmp); - - return sameContent; -} - //############################################################################################################################# class ComparisonBuffer { public: - ComparisonBuffer(const std::set<DirectoryKey>& keysToRead, size_t fileTimeTol, ProcessCallback& callback); + ComparisonBuffer(const std::set<DirectoryKey>& keysToRead, int fileTimeTol, ProcessCallback& callback); //create comparison result table and fill category except for files existing on both sides: undefinedFiles and undefinedLinks are appended! std::shared_ptr<BaseDirPair> compareByTimeSize(const ResolvedFolderPair& fp, const FolderPairCfg& fpConfig) const; @@ -208,13 +167,13 @@ private: std::vector<SymlinkPair*>& undefinedLinks) const; std::map<DirectoryKey, DirectoryValue> directoryBuffer; //contains only *existing* directories - const size_t fileTimeTolerance; + const int fileTimeTolerance; ProcessCallback& callback_; }; ComparisonBuffer::ComparisonBuffer(const std::set<DirectoryKey>& keysToRead, - size_t fileTimeTol, + int fileTimeTol, ProcessCallback& callback) : fileTimeTolerance(fileTimeTol), callback_(callback) @@ -305,7 +264,7 @@ std::wstring getDescrDiffMetaDate(const FileOrLinkPair& fileObj) //----------------------------------------------------------------------------- -void categorizeSymlinkByTime(SymlinkPair& linkObj, size_t fileTimeTolerance) +void categorizeSymlinkByTime(SymlinkPair& linkObj, int fileTimeTolerance) { //categorize symlinks that exist on both sides switch (CmpFileTime::getResult(linkObj.getLastWriteTime<LEFT_SIDE>(), @@ -395,7 +354,7 @@ std::shared_ptr<BaseDirPair> ComparisonBuffer::compareByTimeSize(const ResolvedF } -void categorizeSymlinkByContent(SymlinkPair& linkObj, size_t fileTimeTolerance, ProcessCallback& callback) +void categorizeSymlinkByContent(SymlinkPair& linkObj, int fileTimeTolerance, ProcessCallback& callback) { //categorize symlinks that exist on both sides Zstring targetPathRawL; @@ -428,8 +387,8 @@ void categorizeSymlinkByContent(SymlinkPair& linkObj, size_t fileTimeTolerance, //symlinks have same "content" if (linkObj.getShortName<LEFT_SIDE>() != linkObj.getShortName<RIGHT_SIDE>()) linkObj.setCategoryDiffMetadata(getDescrDiffMetaShortnameCase(linkObj)); - else if (CmpFileTime::getResult(linkObj.getLastWriteTime<LEFT_SIDE>(), - linkObj.getLastWriteTime<RIGHT_SIDE>(), fileTimeTolerance) != CmpFileTime::TIME_EQUAL) + else if (!sameFileTime(linkObj.getLastWriteTime<LEFT_SIDE>(), + linkObj.getLastWriteTime<RIGHT_SIDE>(), fileTimeTolerance)) linkObj.setCategoryDiffMetadata(getDescrDiffMetaDate(linkObj)); else linkObj.setCategory<FILE_EQUAL>(); @@ -497,13 +456,15 @@ std::list<std::shared_ptr<BaseDirPair>> ComparisonBuffer::compareByContent(const bool haveSameContent = false; Opt<std::wstring> errMsg = tryReportingError([&] { - haveSameContent = filesHaveSameContentUpdating(fileObj->getFullName<LEFT_SIDE>(), //throw FileError - fileObj->getFullName<RIGHT_SIDE>(), - to<Int64>(fileObj->getFileSize<LEFT_SIDE>()), - callback_); + StatisticsReporter statReporter(1, to<Int64>(fileObj->getFileSize<LEFT_SIDE>()), callback_); - callback_.updateProcessedData(1, 0); //processed bytes are reported in subfunctions! - callback_.requestUiRefresh(); //may throw + auto onUpdateStatus = [&](Int64 bytesDelta) { statReporter.reportDelta(0, bytesDelta); }; + + haveSameContent = filesHaveSameContent(fileObj->getFullName<LEFT_SIDE>(), + fileObj->getFullName<RIGHT_SIDE>(), onUpdateStatus); //throw FileError + statReporter.reportDelta(1, 0); + + statReporter.reportFinished(); }, callback_); if (errMsg) @@ -518,8 +479,8 @@ std::list<std::shared_ptr<BaseDirPair>> ComparisonBuffer::compareByContent(const //3. harmonize with "bool stillInSync()" in algorithm.cpp, FilePair::syncTo() in file_hierarchy.cpp if (fileObj->getShortName<LEFT_SIDE>() != fileObj->getShortName<RIGHT_SIDE>()) fileObj->setCategoryDiffMetadata(getDescrDiffMetaShortnameCase(*fileObj)); - else if (CmpFileTime::getResult(fileObj->getLastWriteTime<LEFT_SIDE>(), - fileObj->getLastWriteTime<RIGHT_SIDE>(), fileTimeTolerance) != CmpFileTime::TIME_EQUAL) + else if (!sameFileTime(fileObj->getLastWriteTime<LEFT_SIDE>(), + fileObj->getLastWriteTime<RIGHT_SIDE>(), fileTimeTolerance)) fileObj->setCategoryDiffMetadata(getDescrDiffMetaDate(*fileObj)); else fileObj->setCategory<FILE_EQUAL>(); @@ -760,7 +721,7 @@ std::shared_ptr<BaseDirPair> ComparisonBuffer::performComparison(const ResolvedF } -void zen::compare(size_t fileTimeTolerance, +void zen::compare(int fileTimeTolerance, xmlAccess::OptionalDialogs& warnings, bool allowUserInteraction, bool runWithBackgroundPriority, @@ -836,7 +797,7 @@ void zen::compare(size_t fileTimeTolerance, for (const auto& w : totalWorkLoad) { - if (dirAvailable(w.first.dirnameLeft)) //only request *currently existing* directories: at this point user is aware that non-ex + empty string are seen as empty folder! + if (dirAvailable(w.first.dirnameLeft)) //only traverse *currently existing* directories: at this point user is aware that non-ex + empty string are seen as empty folder! dirsToRead.insert(DirectoryKey(w.first.dirnameLeft, w.second.filter.nameFilter, w.second.handleSymlinks)); if (dirAvailable(w.first.dirnameRight)) dirsToRead.insert(DirectoryKey(w.first.dirnameRight, w.second.filter.nameFilter, w.second.handleSymlinks)); diff --git a/FreeFileSync/Source/comparison.h b/FreeFileSync/Source/comparison.h index c3c31d1d..b69eaa51 100644 --- a/FreeFileSync/Source/comparison.h +++ b/FreeFileSync/Source/comparison.h @@ -45,7 +45,7 @@ struct FolderPairCfg std::vector<FolderPairCfg> extractCompareCfg(const MainConfiguration& mainCfg); //fill FolderPairCfg and resolve folder pairs //FFS core routine: -void compare(size_t fileTimeTolerance, //max allowed file time deviation +void compare(int fileTimeTolerance, //max allowed file time deviation xmlAccess::OptionalDialogs& warnings, bool allowUserInteraction, bool runWithBackgroundPriority, diff --git a/FreeFileSync/Source/dll/Thumbnail/thumbnail.cpp b/FreeFileSync/Source/dll/Thumbnail/thumbnail.cpp index 53c30bc3..6b6659e4 100644 --- a/FreeFileSync/Source/dll/Thumbnail/thumbnail.cpp +++ b/FreeFileSync/Source/dll/Thumbnail/thumbnail.cpp @@ -78,7 +78,8 @@ HICON createIconFromBitmap(HBITMAP bitmap) //throw SysError iconInfo.hbmMask = bitmapMask; HICON result = ::CreateIconIndirect(&iconInfo); - if (!result) throw SysError(formatSystemError(L"CreateIconIndirect", getLastError())); + if (!result) + throw SysError(formatSystemError(L"CreateIconIndirect", getLastError())); return result; } diff --git a/FreeFileSync/Source/file_hierarchy.cpp b/FreeFileSync/Source/file_hierarchy.cpp index 780f05de..2d5891c1 100644 --- a/FreeFileSync/Source/file_hierarchy.cpp +++ b/FreeFileSync/Source/file_hierarchy.cpp @@ -367,7 +367,7 @@ std::wstring zen::getSyncOpDescription(const FileSystemObject& fsObj) fmtFileName(shortNameOld) + L" ->\n" + //show short name only fmtFileName(shortNameNew); } - //fallback: + //fallback: return getSyncOpDescription(op); case SO_MOVE_LEFT_SOURCE: diff --git a/FreeFileSync/Source/file_hierarchy.h b/FreeFileSync/Source/file_hierarchy.h index e8f35246..51ad113b 100644 --- a/FreeFileSync/Source/file_hierarchy.h +++ b/FreeFileSync/Source/file_hierarchy.h @@ -236,7 +236,7 @@ public: bool dirExistsRight, const HardFilter::FilterRef& filter, CompareVariant cmpVar, - size_t fileTimeTolerance) : + int fileTimeTolerance) : #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4355) //"The this pointer is valid only within nonstatic member functions. It cannot be used in the initializer list for a base class." @@ -260,7 +260,7 @@ public: //get settings which were used while creating BaseDirPair const HardFilter& getFilter() const { return *filter_; } CompareVariant getCompVariant() const { return cmpVar_; } - size_t getFileTimeTolerance() const { return fileTimeTolerance_; } + int getFileTimeTolerance() const { return fileTimeTolerance_; } virtual void flip(); @@ -270,7 +270,7 @@ private: HardFilter::FilterRef filter_; //filter used while scanning directory: represents sub-view of actual files! CompareVariant cmpVar_; - size_t fileTimeTolerance_; + int fileTimeTolerance_; Zstring baseDirPfL; //base sync dir postfixed Zstring baseDirPfR; // @@ -289,7 +289,7 @@ const Zstring& BaseDirPair::getBaseDirPf<RIGHT_SIDE>() const { return baseDirPfR //get rid of shared_ptr indirection template <class IterTy, //underlying iterator type - class U> //target object type + class U> //target object type class DerefIter : public std::iterator<std::bidirectional_iterator_tag, U> { public: diff --git a/FreeFileSync/Source/lib/binary.cpp b/FreeFileSync/Source/lib/binary.cpp index 0e41f7a6..0d62f0ec 100644 --- a/FreeFileSync/Source/lib/binary.cpp +++ b/FreeFileSync/Source/lib/binary.cpp @@ -69,7 +69,7 @@ const std::int64_t TICKS_PER_SEC = ticksPerSec(); } -bool zen::filesHaveSameContent(const Zstring& filename1, const Zstring& filename2, CompareCallback& callback) +bool zen::filesHaveSameContent(const Zstring& filename1, const Zstring& filename2, const std::function<void(Int64 bytesDelta)>& onUpdateStatus) { static boost::thread_specific_ptr<std::vector<char>> cpyBuf1; static boost::thread_specific_ptr<std::vector<char>> cpyBuf2; @@ -98,7 +98,8 @@ bool zen::filesHaveSameContent(const Zstring& filename1, const Zstring& filename const size_t length1 = file1.read(&memory1[0], bufferSize); //throw FileError const size_t length2 = file2.read(&memory2[0], bufferSize); //returns actual number of bytes read //send progress updates immediately after reading to reliably allow speed calculations for our clients! - callback.updateCompareStatus(to<Int64>(std::max(length1, length2))); + if (onUpdateStatus) + onUpdateStatus(to<Int64>(std::max(length1, length2))); if (length1 != length2 || ::memcmp(&memory1[0], &memory2[0], length1) != 0) return false; diff --git a/FreeFileSync/Source/lib/binary.h b/FreeFileSync/Source/lib/binary.h index 8a4abe6b..a105c622 100644 --- a/FreeFileSync/Source/lib/binary.h +++ b/FreeFileSync/Source/lib/binary.h @@ -7,19 +7,16 @@ #ifndef BINARY_H_INCLUDED #define BINARY_H_INCLUDED +#include <functional> #include <zen/zstring.h> #include <zen/file_error.h> #include <zen/int64.h> namespace zen { -struct CompareCallback -{ - virtual ~CompareCallback() {} - virtual void updateCompareStatus(Int64 bytesDelta) = 0; -}; - -bool filesHaveSameContent(const Zstring& filename1, const Zstring& filename2, CompareCallback& callback); //throw FileError +bool filesHaveSameContent(const Zstring& filename1, //throw FileError + const Zstring& filename2, + const std::function<void(Int64 bytesDelta)>& onUpdateStatus); //may be nullptr } #endif // BINARY_H_INCLUDED diff --git a/FreeFileSync/Source/lib/cmp_filetime.h b/FreeFileSync/Source/lib/cmp_filetime.h index 33d214ab..fab011ee 100644 --- a/FreeFileSync/Source/lib/cmp_filetime.h +++ b/FreeFileSync/Source/lib/cmp_filetime.h @@ -1,25 +1,27 @@ #ifndef CMP_FILETIME_H_INCLUDED #define CMP_FILETIME_H_INCLUDED -//#include <wx/stopwatch.h> -#include <wx/time.h> +#include <ctime> #include <zen/int64.h> namespace zen { //--------------------------------------------------------------------------------------------------------------- inline -bool sameFileTime(const Int64& a, const Int64& b, size_t tolerance) +bool sameFileTime(const Int64& lhs, const Int64& rhs, int tolerance) { - if (a < b) - return b <= a + static_cast<ptrdiff_t>(tolerance); + if (tolerance < 0) //= unlimited tolerance by convention! + return true; + + if (lhs < rhs) + return rhs - lhs <= tolerance; else - return a <= b + static_cast<ptrdiff_t>(tolerance); + return lhs - rhs <= tolerance; } //--------------------------------------------------------------------------------------------------------------- //number of seconds since Jan 1st 1970 + 1 year (needn't be too precise) -static const long oneYearFromNow = wxGetUTCTime() + 365 * 24 * 3600; //init at program startup alas in *each* compilation untit -> avoid MT issues +static const Int64 oneYearFromNow = std::time(nullptr) + 365 * 24 * 3600; //init at program startup in *each* compilation untit -> avoid MT issues //refactor when C++11 thread-safe static initialization is availalbe in VS (already in GCC) class CmpFileTime @@ -34,7 +36,7 @@ public: TIME_RIGHT_INVALID }; - static Result getResult(const Int64& lhs, const Int64& rhs, size_t tolerance) + static Result getResult(const Int64& lhs, const Int64& rhs, int tolerance) { if (sameFileTime(lhs, rhs, tolerance)) //last write time may differ by up to 2 seconds (NTFS vs FAT32) return TIME_EQUAL; diff --git a/FreeFileSync/Source/lib/db_file.cpp b/FreeFileSync/Source/lib/db_file.cpp index 1c2a34f3..b8952c8a 100644 --- a/FreeFileSync/Source/lib/db_file.cpp +++ b/FreeFileSync/Source/lib/db_file.cpp @@ -812,8 +812,9 @@ void zen::saveLastSynchronousState(const BaseDirPair& baseDirObj) //throw FileEr //operation finished: rename temp files -> this should work transactionally: //if there were no write access, creation of temp files would have failed removeFile(dbNameLeft); // - removeFile(dbNameRight); //throw FileError - renameFile(dbNameLeftTmp, dbNameLeft); // + renameFile(dbNameLeftTmp, dbNameLeft); //throw FileError + + removeFile(dbNameRight); // renameFile(dbNameRightTmp, dbNameRight); // guardTempFileLeft. dismiss(); //no need to delete temp files anymore diff --git a/FreeFileSync/Source/lib/dir_lock.cpp b/FreeFileSync/Source/lib/dir_lock.cpp index 47249d3e..56fadb8f 100644 --- a/FreeFileSync/Source/lib/dir_lock.cpp +++ b/FreeFileSync/Source/lib/dir_lock.cpp @@ -289,17 +289,17 @@ struct LockInformation //throw FileError computerName += &buffer[0]; const uid_t userIdNo = ::getuid(); //never fails - userId = numberTo<std::string>(userIdNo); + userId = numberTo<std::string>(userIdNo); - //the id alone is not very distinctive, e.g. often 1000 on Ubuntu => add name + //the id alone is not very distinctive, e.g. often 1000 on Ubuntu => add name buffer.resize(std::max<long>(buffer.size(), ::sysconf(_SC_GETPW_R_SIZE_MAX))); //::sysconf may return long(-1) struct passwd buffer2 = {}; struct passwd* pwsEntry = nullptr; if (::getpwuid_r(userIdNo, &buffer2, &buffer[0], buffer.size(), &pwsEntry) != 0) //getlogin() is deprecated and not working on Ubuntu at all!!! throw FileError(_("Cannot get process information."), formatSystemError(L"getpwuid_r", getLastError())); if (!pwsEntry) - throw FileError(_("Cannot get process information."), L"no login found"); //should not happen? - userId += '(' + std::string(pwsEntry->pw_name) + ')'; //follow Linux naming convention "1000(zenju)" + throw FileError(_("Cannot get process information."), L"no login found"); //should not happen? + userId += '(' + std::string(pwsEntry->pw_name) + ')'; //follow Linux naming convention "1000(zenju)" #endif Opt<SessionId> sessionIdTmp = getSessionId(processId); //throw FileError @@ -420,8 +420,8 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr try { const LockInformation& lockInfo = retrieveLockInfo(lockfilename); //throw FileError - //enhance status message and show which user is holding the lock: - infoMsg += L" | " + _("Lock owner:") + L' ' + utfCvrtTo<std::wstring>(lockInfo.userId); + //enhance status message and show which user is holding the lock: + infoMsg += L" | " + _("Lock owner:") + L' ' + utfCvrtTo<std::wstring>(lockInfo.userId); originalLockId = lockInfo.lockId; switch (getProcessStatus(lockInfo)) //throw FileError diff --git a/FreeFileSync/Source/lib/icon_buffer.cpp b/FreeFileSync/Source/lib/icon_buffer.cpp index db83460d..82bdda62 100644 --- a/FreeFileSync/Source/lib/icon_buffer.cpp +++ b/FreeFileSync/Source/lib/icon_buffer.cpp @@ -9,6 +9,7 @@ #include <set> #include <zen/thread.h> //includes <boost/thread.hpp> #include <zen/scope_guard.h> +#include <wx+/image_resources.h> #ifdef ZEN_WIN #include <zen/dll.h> @@ -131,7 +132,7 @@ public: }; -#ifdef ZEN_WIN +#if defined ZEN_WIN || defined ZEN_LINUX Zstring getFileExtension(const Zstring& filename) { const Zstring shortName = afterLast(filename, Zchar('\\')); //warning: using windows file name separator! @@ -140,37 +141,16 @@ Zstring getFileExtension(const Zstring& filename) afterLast(filename, Zchar('.')) : Zstring(); } +#endif -std::set<Zstring, LessFilename> priceyExtensions; //thread-safe! -boost::once_flag initExtensionsOnce = BOOST_ONCE_INIT; // - -//test for extension for non-thumbnail icons that physically have to be retrieved from disc -bool isCheapExtension(const Zstring& extension) -{ - boost::call_once(initExtensionsOnce, []() - { - priceyExtensions.insert(L"exe"); - priceyExtensions.insert(L"ico"); - priceyExtensions.insert(L"ani"); - priceyExtensions.insert(L"cur"); - priceyExtensions.insert(L"msc"); - priceyExtensions.insert(L"scr"); - - priceyExtensions.insert(L"lnk"); // - priceyExtensions.insert(L"url"); //make sure shortcuts are pricey to get them to be detected by SHGetFileInfo - priceyExtensions.insert(L"pif"); // - priceyExtensions.insert(L"website"); // - - }); - return priceyExtensions.find(extension) == priceyExtensions.end(); -} - +#ifdef ZEN_WIN const bool wereVistaOrLater = vistaOrLater(); //thread-safety: init at startup thumb::IconSizeType getThumbSizeType(IconBuffer::IconSize sz) { + //coordinate with IconBuffer::getSize()! using namespace thumb; switch (sz) { @@ -225,11 +205,50 @@ IconHolder iconHolderFromGicon(GIcon* gicon, IconBuffer::IconSize sz) return IconHolder(); } #endif + +#ifdef ZEN_WIN +std::set<Zstring, LessFilename> customIconExt //function-scope statics are not (yet) thread-safe in VC12 +{ + L"ani", + L"cur", + L"exe", + L"ico", + L"msc", + L"scr" +}; +std::set<Zstring, LessFilename> linkExt +{ + L"lnk", + L"pif", + L"url", + L"website" +}; + +//test for extension for non-thumbnail icons that can have a stock icon which does not have to be physically read from disc +bool isStandardIconExtension(const Zstring& extension) +{ + return customIconExt.find(extension) == customIconExt.end() && + linkExt.find(extension) == linkExt.end(); +} +#endif +} + +bool zen::hasLinkExtension(const Zstring& filename) +{ +#ifdef ZEN_WIN + const Zstring& extension = getFileExtension(filename); + return linkExt.find(extension) != linkExt.end(); +#elif defined ZEN_LINUX + const Zstring& extension = getFileExtension(filename); + return extension == "desktop"; +#elif defined ZEN_MAC + return false; //alias files already get their arrow icon via "NSWorkspace::iconForFile" +#endif } //################################################################################################################################################ -IconHolder getThumbnailIcon(const Zstring& filename, int requestedSize) //return 0 on failure +IconHolder getThumbnailImage(const Zstring& filename, int requestedSize) //return 0 on failure { #ifdef ZEN_WIN if (getThumbnail && releaseImageData) @@ -330,22 +349,19 @@ IconHolder getAssociatedIcon(const Zstring& filename, IconBuffer::IconSize sz) break; case IconBuffer::SIZE_MEDIUM: case IconBuffer::SIZE_LARGE: - if (IconHolder ico = getThumbnailIcon(filename, IconBuffer::getSize(sz))) + if (IconHolder ico = getThumbnailImage(filename, IconBuffer::getSize(sz))) return ico; //else: fallback to non-thumbnail icon break; } - warn_static("problem: fr folder links ist getThumbnail erfolgreich => SFGAO_LINK nicht gecheckt!") - //2. retrieve file icons #ifdef ZEN_WIN //perf: optimize fallback case for SIZE_MEDIUM and SIZE_LARGE: const Zstring& extension = getFileExtension(filename); - if (isCheapExtension(extension)) //"pricey" extensions are stored with fullnames and are read from disk, while cheap ones require just the extension + if (isStandardIconExtension(extension)) //"pricey" extensions are stored with fullnames and are read from disk, while cheap ones require just the extension return getAssociatedIconByExt(extension, sz); - //result will not be buffered under extension name, but full filename; this is okay, since we're in SIZE_MEDIUM or SIZE_LARGE context, - //which means the access to get thumbnail failed: thumbnail failure is not dependent from extension in general! + //SIZE_MEDIUM or SIZE_LARGE: result will buffered under full filename, not extension; this is okay: failure to load thumbnail is independent from extension in general! SHFILEINFO fileInfo = {}; if (DWORD_PTR imgList = ::SHGetFileInfo(filename.c_str(), //_In_ LPCTSTR pszPath, -> note: ::SHGetFileInfo() can't handle \\?\-prefix! @@ -362,12 +378,7 @@ 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 -#ifdef __MINGW32__ //Shobjidl.h -#define SFGAO_LINK 0x00010000L // Shortcut (link) or symlinks -#endif - - warn_static("support SFGAO_GHOSTED or hidden?") - //requires SHGFI_ATTRIBUTES + //Check for link icon type (= shell links and symlinks): SHGetFileInfo + SHGFI_ATTRIBUTES: //const bool isLink = (fileInfo.dwAttributes & SFGAO_LINK) != 0; if (getIconByIndex && releaseImageData) @@ -652,6 +663,33 @@ void WorkerThread::operator()() //thread entry //######################### redirect to impl ##################################################### +namespace +{ +const wchar_t* getLinkResourceName(IconBuffer::IconSize sz) +{ + //coordinate with IconBuffer::getSize()! + switch (sz) + { + case IconBuffer::SIZE_SMALL: +#if defined ZEN_WIN || defined ZEN_MAC + return L"link_16"; +#elif defined ZEN_LINUX + return L"link_24"; +#endif + case IconBuffer::SIZE_MEDIUM: +#ifdef ZEN_WIN + if (!wereVistaOrLater) return L"link_32"; +#endif + return L"link_48"; + + case IconBuffer::SIZE_LARGE: + return L"link_128"; + } + assert(false); + return L"link_16"; +} +} + struct IconBuffer::Pimpl { Pimpl() : @@ -668,7 +706,8 @@ struct IconBuffer::Pimpl IconBuffer::IconBuffer(IconSize sz) : pimpl(make_unique<Pimpl>()), iconSizeType(sz), genDirIcon (::getGenericDirectoryIcon(sz).extractWxBitmap()), - genFileIcon(::getGenericFileIcon (sz).extractWxBitmap()) + genFileIcon(::getGenericFileIcon (sz).extractWxBitmap()), + linkIcon(getResourceImage(getLinkResourceName(sz))) { pimpl->worker = boost::thread(WorkerThread(pimpl->workload, pimpl->buffer, sz)); } @@ -710,7 +749,7 @@ bool IconBuffer::readyForRetrieval(const Zstring& filename) { #ifdef ZEN_WIN if (iconSizeType == IconBuffer::SIZE_SMALL) - if (isCheapExtension(getFileExtension(filename))) + if (isStandardIconExtension(getFileExtension(filename))) return true; #endif return pimpl->buffer->hasIcon(filename); @@ -724,7 +763,7 @@ Opt<wxBitmap> IconBuffer::retrieveFileIcon(const Zstring& filename) if (iconSizeType == IconBuffer::SIZE_SMALL) //non-thumbnail view, we need file type icons only! { const Zstring& extension = getFileExtension(filename); - if (isCheapExtension(extension)) //"pricey" extensions are stored with fullnames and are read from disk, while cheap ones require just the extension + if (isStandardIconExtension(extension)) //"pricey" extensions are stored with fullnames and are read from disk, while cheap ones require just the extension { if (Opt<wxBitmap> ico = pimpl->buffer->retrieve(extension)) return ico; diff --git a/FreeFileSync/Source/lib/icon_buffer.h b/FreeFileSync/Source/lib/icon_buffer.h index e1a475cb..59ea03cd 100644 --- a/FreeFileSync/Source/lib/icon_buffer.h +++ b/FreeFileSync/Source/lib/icon_buffer.h @@ -33,6 +33,7 @@ public: const wxBitmap& genericFileIcon() { return genFileIcon; } const wxBitmap& genericDirIcon () { return genDirIcon; } + const wxBitmap& linkOverlayIcon() { return linkIcon; } bool readyForRetrieval(const Zstring& filename); Opt<wxBitmap> retrieveFileIcon(const Zstring& filename); //... and mark as hot @@ -46,7 +47,10 @@ private: const IconSize iconSizeType; const wxBitmap genDirIcon; const wxBitmap genFileIcon; + const wxBitmap linkIcon; }; + +bool hasLinkExtension(const Zstring& filename); } #endif // ICONBUFFER_H_INCLUDED diff --git a/FreeFileSync/Source/lib/localization.cpp b/FreeFileSync/Source/lib/localization.cpp index 3536ba70..ed449034 100644 --- a/FreeFileSync/Source/lib/localization.cpp +++ b/FreeFileSync/Source/lib/localization.cpp @@ -243,7 +243,7 @@ wxLanguage mapLanguageDialect(wxLanguage language) { switch (static_cast<int>(language)) //avoid enumeration value wxLANGUAGE_*' not handled in switch [-Wswitch-enum] { - //variants of wxLANGUAGE_ARABIC + //variants of wxLANGUAGE_ARABIC case wxLANGUAGE_ARABIC_ALGERIA: case wxLANGUAGE_ARABIC_BAHRAIN: case wxLANGUAGE_ARABIC_EGYPT: @@ -263,22 +263,22 @@ wxLanguage mapLanguageDialect(wxLanguage language) case wxLANGUAGE_ARABIC_YEMEN: return wxLANGUAGE_ARABIC; - //variants of wxLANGUAGE_CHINESE_SIMPLIFIED + //variants of wxLANGUAGE_CHINESE_SIMPLIFIED case wxLANGUAGE_CHINESE: case wxLANGUAGE_CHINESE_SINGAPORE: return wxLANGUAGE_CHINESE_SIMPLIFIED; - //variants of wxLANGUAGE_CHINESE_TRADITIONAL + //variants of wxLANGUAGE_CHINESE_TRADITIONAL case wxLANGUAGE_CHINESE_TAIWAN: case wxLANGUAGE_CHINESE_HONGKONG: case wxLANGUAGE_CHINESE_MACAU: return wxLANGUAGE_CHINESE_TRADITIONAL; - //variants of wxLANGUAGE_DUTCH + //variants of wxLANGUAGE_DUTCH case wxLANGUAGE_DUTCH_BELGIAN: return wxLANGUAGE_DUTCH; - //variants of wxLANGUAGE_ENGLISH_UK + //variants of wxLANGUAGE_ENGLISH_UK case wxLANGUAGE_ENGLISH_AUSTRALIA: case wxLANGUAGE_ENGLISH_NEW_ZEALAND: case wxLANGUAGE_ENGLISH_TRINIDAD: @@ -292,13 +292,13 @@ wxLanguage mapLanguageDialect(wxLanguage language) case wxLANGUAGE_ENGLISH_DENMARK: return wxLANGUAGE_ENGLISH_UK; - //variants of wxLANGUAGE_ENGLISH_US + //variants of wxLANGUAGE_ENGLISH_US case wxLANGUAGE_ENGLISH: case wxLANGUAGE_ENGLISH_CANADA: case wxLANGUAGE_ENGLISH_PHILIPPINES: return wxLANGUAGE_ENGLISH_US; - //variants of wxLANGUAGE_FRENCH + //variants of wxLANGUAGE_FRENCH case wxLANGUAGE_FRENCH_BELGIAN: case wxLANGUAGE_FRENCH_CANADIAN: case wxLANGUAGE_FRENCH_LUXEMBOURG: @@ -306,7 +306,7 @@ wxLanguage mapLanguageDialect(wxLanguage language) case wxLANGUAGE_FRENCH_SWISS: return wxLANGUAGE_FRENCH; - //variants of wxLANGUAGE_GERMAN + //variants of wxLANGUAGE_GERMAN case wxLANGUAGE_GERMAN_AUSTRIAN: case wxLANGUAGE_GERMAN_BELGIUM: case wxLANGUAGE_GERMAN_LIECHTENSTEIN: @@ -314,29 +314,29 @@ wxLanguage mapLanguageDialect(wxLanguage language) case wxLANGUAGE_GERMAN_SWISS: return wxLANGUAGE_GERMAN; - //variants of wxLANGUAGE_ITALIAN + //variants of wxLANGUAGE_ITALIAN case wxLANGUAGE_ITALIAN_SWISS: return wxLANGUAGE_ITALIAN; - //variants of wxLANGUAGE_NORWEGIAN_BOKMAL + //variants of wxLANGUAGE_NORWEGIAN_BOKMAL case wxLANGUAGE_NORWEGIAN_NYNORSK: return wxLANGUAGE_NORWEGIAN_BOKMAL; - //variants of wxLANGUAGE_ROMANIAN + //variants of wxLANGUAGE_ROMANIAN case wxLANGUAGE_MOLDAVIAN: return wxLANGUAGE_ROMANIAN; - //variants of wxLANGUAGE_RUSSIAN + //variants of wxLANGUAGE_RUSSIAN case wxLANGUAGE_RUSSIAN_UKRAINE: return wxLANGUAGE_RUSSIAN; - //variants of wxLANGUAGE_SERBIAN + //variants of wxLANGUAGE_SERBIAN case wxLANGUAGE_SERBIAN_CYRILLIC: case wxLANGUAGE_SERBIAN_LATIN: case wxLANGUAGE_SERBO_CROATIAN: return wxLANGUAGE_SERBIAN; - //variants of wxLANGUAGE_SPANISH + //variants of wxLANGUAGE_SPANISH case wxLANGUAGE_SPANISH_ARGENTINA: case wxLANGUAGE_SPANISH_BOLIVIA: case wxLANGUAGE_SPANISH_CHILE: @@ -359,28 +359,28 @@ wxLanguage mapLanguageDialect(wxLanguage language) case wxLANGUAGE_SPANISH_VENEZUELA: return wxLANGUAGE_SPANISH; - //variants of wxLANGUAGE_SWEDISH + //variants of wxLANGUAGE_SWEDISH case wxLANGUAGE_SWEDISH_FINLAND: return wxLANGUAGE_SWEDISH; - //languages without variants: - //case wxLANGUAGE_CROATIAN: - //case wxLANGUAGE_CZECH: - //case wxLANGUAGE_DANISH: - //case wxLANGUAGE_FINNISH: - //case wxLANGUAGE_GREEK: - //case wxLANGUAGE_HEBREW: - //case wxLANGUAGE_HUNGARIAN: - //case wxLANGUAGE_JAPANESE: - //case wxLANGUAGE_KOREAN: - //case wxLANGUAGE_LITHUANIAN: - //case wxLANGUAGE_POLISH: - //case wxLANGUAGE_PORTUGUESE: - //case wxLANGUAGE_PORTUGUESE_BRAZILIAN: - //case wxLANGUAGE_SCOTS_GAELIC: - //case wxLANGUAGE_SLOVENIAN: - //case wxLANGUAGE_TURKISH: - //case wxLANGUAGE_UKRAINIAN: + //languages without variants: + //case wxLANGUAGE_CROATIAN: + //case wxLANGUAGE_CZECH: + //case wxLANGUAGE_DANISH: + //case wxLANGUAGE_FINNISH: + //case wxLANGUAGE_GREEK: + //case wxLANGUAGE_HEBREW: + //case wxLANGUAGE_HUNGARIAN: + //case wxLANGUAGE_JAPANESE: + //case wxLANGUAGE_KOREAN: + //case wxLANGUAGE_LITHUANIAN: + //case wxLANGUAGE_POLISH: + //case wxLANGUAGE_PORTUGUESE: + //case wxLANGUAGE_PORTUGUESE_BRAZILIAN: + //case wxLANGUAGE_SCOTS_GAELIC: + //case wxLANGUAGE_SLOVENIAN: + //case wxLANGUAGE_TURKISH: + //case wxLANGUAGE_UKRAINIAN: default: return language; } diff --git a/FreeFileSync/Source/lib/parallel_scan.cpp b/FreeFileSync/Source/lib/parallel_scan.cpp index 9c6b16a9..7c77d115 100644 --- a/FreeFileSync/Source/lib/parallel_scan.cpp +++ b/FreeFileSync/Source/lib/parallel_scan.cpp @@ -376,7 +376,7 @@ DirCallback::HandleLink DirCallback::onSymlink(const Zchar* shortName, const Zst case SYMLINK_EXCLUDE: return LINK_SKIP; - case SYMLINK_USE_DIRECTLY: + case SYMLINK_DIRECT: if (cfg.filterInstance->passFileFilter(relNameParentPf_ + shortName)) //always use file filter: Link type may not be "stable" on Linux! { output_.addSubLink(shortName, LinkDescriptor(details.lastWriteTime)); @@ -384,7 +384,7 @@ DirCallback::HandleLink DirCallback::onSymlink(const Zchar* shortName, const Zst } return LINK_SKIP; - case SYMLINK_FOLLOW_LINK: + case SYMLINK_FOLLOW: //filter symlinks before trying to follow them: handle user-excluded broken symlinks! //since we don't know what the symlink will resolve to, only do this when both variants agree: if (!cfg.filterInstance->passFileFilter(relNameParentPf_ + shortName)) diff --git a/FreeFileSync/Source/lib/parse_lng.h b/FreeFileSync/Source/lib/parse_lng.h index 19a8e751..7761a666 100644 --- a/FreeFileSync/Source/lib/parse_lng.h +++ b/FreeFileSync/Source/lib/parse_lng.h @@ -685,8 +685,8 @@ std::string generateLng(const TranslationUnorderedList& in, const TransHeader& h out += KnownTokens::text(Token::TK_SRC_END) + '\n'; out += KnownTokens::text(Token::TK_TRG_BEGIN); - out += '\n'; - + if (!forms.empty()) + out += '\n'; for (std::string plForm : forms) { formatMultiLineText(plForm); diff --git a/FreeFileSync/Source/lib/process_xml.cpp b/FreeFileSync/Source/lib/process_xml.cpp index 3bf4d81b..fb0000f7 100644 --- a/FreeFileSync/Source/lib/process_xml.cpp +++ b/FreeFileSync/Source/lib/process_xml.cpp @@ -10,6 +10,7 @@ #include "ffs_paths.h" #include <zen/file_handling.h> #include <zen/file_io.h> + //#include <zen/time.h> #include "xml_base.h" @@ -402,10 +403,10 @@ void writeText(const SymLinkHandling& value, std::string& output) case SYMLINK_EXCLUDE: output = "Exclude"; break; - case SYMLINK_USE_DIRECTLY: + case SYMLINK_DIRECT: output = "Direct"; break; - case SYMLINK_FOLLOW_LINK: + case SYMLINK_FOLLOW: output = "Follow"; break; } @@ -418,9 +419,9 @@ bool readText(const std::string& input, SymLinkHandling& value) zen::trim(tmp); warn_static("remove after migration. 2013.08.20") if (tmp == "UseDirectly") //obsolete! - value = SYMLINK_USE_DIRECTLY; + value = SYMLINK_DIRECT; else if (tmp == "FollowLink") //obsolete! - value = SYMLINK_FOLLOW_LINK; + value = SYMLINK_FOLLOW; else if (tmp == "Ignore") //obsolete! value = SYMLINK_EXCLUDE; else @@ -428,9 +429,9 @@ bool readText(const std::string& input, SymLinkHandling& value) if (tmp == "Exclude") value = SYMLINK_EXCLUDE; else if (tmp == "Direct") - value = SYMLINK_USE_DIRECTLY; + value = SYMLINK_DIRECT; else if (tmp == "Follow") - value = SYMLINK_FOLLOW_LINK; + value = SYMLINK_FOLLOW; else return false; return true; @@ -750,14 +751,17 @@ bool readStruc(const XmlElement& input, ViewFilterDefault& value) success = false; }; + XmlIn sharedView = in["Shared"]; + readAttr(sharedView, "Equal" , value.equal); + readAttr(sharedView, "Conflict", value.conflict); + readAttr(sharedView, "Excluded", value.excluded); + XmlIn catView = in["CategoryView"]; readAttr(catView, "LeftOnly" , value.leftOnly); readAttr(catView, "RightOnly" , value.rightOnly); readAttr(catView, "LeftNewer" , value.leftNewer); readAttr(catView, "RightNewer", value.rightNewer); readAttr(catView, "Different" , value.different); - readAttr(catView, "Equal" , value.equal); - readAttr(catView, "Conflict" , value.conflict); XmlIn actView = in["ActionView"]; readAttr(actView, "CreateLeft" , value.createLeft); @@ -776,14 +780,17 @@ void writeStruc(const ViewFilterDefault& value, XmlElement& output) { XmlOut out(output); + XmlOut sharedView = out["Shared"]; + sharedView.attribute("Equal" , value.equal); + sharedView.attribute("Conflict", value.conflict); + sharedView.attribute("Excluded", value.excluded); + XmlOut catView = out["CategoryView"]; catView.attribute("LeftOnly" , value.leftOnly); catView.attribute("RightOnly" , value.rightOnly); catView.attribute("LeftNewer" , value.leftNewer); catView.attribute("RightNewer", value.rightNewer); catView.attribute("Different" , value.different); - catView.attribute("Equal" , value.equal); - catView.attribute("Conflict" , value.conflict); XmlOut actView = out["ActionView"]; actView.attribute("CreateLeft" , value.createLeft); @@ -999,18 +1006,7 @@ void readConfig(const XmlIn& in, xmlAccess::XmlGuiConfig& config) //read GUI specific config data XmlIn inGuiCfg = in["GuiConfig"]; - warn_static("remove after migration?") - if (inGuiCfg["HideFiltered" ]) //obsolete name - inGuiCfg["HideFiltered" ](config.hideExcludedItems); - else if (inGuiCfg["ShowFiltered" ]) //obsolete name - { - inGuiCfg["ShowFiltered"](config.hideExcludedItems); - config.hideExcludedItems = !config.hideExcludedItems; - } - else - inGuiCfg["HideExcluded"](config.hideExcludedItems); - - inGuiCfg["HandleError" ](config.handleError); + inGuiCfg["HandleError"](config.handleError); warn_static("remove after migration?") if (inGuiCfg["SyncPreviewActive"]) //obsolete name @@ -1117,8 +1113,8 @@ void readConfig(const XmlIn& in, XmlGlobalSettings& config) inColRight(config.gui.columnAttribRight); //########################################################### - inWnd["ViewFilterDefault"](config.gui.viewFilterDefault); - inWnd["Perspective2" ](config.gui.guiPerspectiveLast); + inWnd["DefaultView" ](config.gui.viewFilterDefault); + inWnd["Perspective"](config.gui.guiPerspectiveLast); std::vector<Zstring> tmp = splitFilterByLines(config.gui.defaultExclusionFilter); //default value inGui["DefaultExclusionFilter"](tmp); @@ -1413,7 +1409,6 @@ void writeConfig(const XmlGuiConfig& config, XmlOut& out) //write GUI specific config data XmlOut outGuiCfg = out["GuiConfig"]; - outGuiCfg["HideExcluded" ](config.hideExcludedItems); outGuiCfg["HandleError" ](config.handleError); outGuiCfg["MiddleGridView"](config.highlightSyncAction ? "Action" : "Category"); //refactor into enum!? } @@ -1505,8 +1500,8 @@ void writeConfig(const XmlGlobalSettings& config, XmlOut& out) outColRight(config.gui.columnAttribRight); //########################################################### - outWnd["ViewFilterDefault"](config.gui.viewFilterDefault); - outWnd["Perspective2" ](config.gui.guiPerspectiveLast); + outWnd["DefaultView" ](config.gui.viewFilterDefault); + outWnd["Perspective"](config.gui.guiPerspectiveLast); outGui["DefaultExclusionFilter"](splitFilterByLines(config.gui.defaultExclusionFilter)); diff --git a/FreeFileSync/Source/lib/process_xml.h b/FreeFileSync/Source/lib/process_xml.h index 046cbca2..a7724e25 100644 --- a/FreeFileSync/Source/lib/process_xml.h +++ b/FreeFileSync/Source/lib/process_xml.h @@ -49,13 +49,11 @@ typedef std::vector<std::pair<Description, Commandline>> ExternalApps; struct XmlGuiConfig { XmlGuiConfig() : - hideExcludedItems(false), handleError(ON_GUIERROR_POPUP), highlightSyncAction(true) {} //initialize values zen::MainConfiguration mainCfg; - bool hideExcludedItems; OnGuiError handleError; //reaction on error situation during synchronization bool highlightSyncAction; }; @@ -65,7 +63,6 @@ inline bool operator==(const XmlGuiConfig& lhs, const XmlGuiConfig& rhs) { return lhs.mainCfg == rhs.mainCfg && - lhs.hideExcludedItems == rhs.hideExcludedItems && lhs.handleError == rhs.handleError && lhs.highlightSyncAction == rhs.highlightSyncAction; } @@ -118,13 +115,15 @@ enum FileIconSize struct ViewFilterDefault { - ViewFilterDefault() : equal(false) + ViewFilterDefault() : equal(false), conflict(true), excluded(true) { - leftOnly = rightOnly = leftNewer = rightNewer = different = conflict = true; + leftOnly = rightOnly = leftNewer = rightNewer = different = true; createLeft = createRight = updateLeft = updateRight = deleteLeft = deleteRight = doNothing = true; } - bool equal; - bool leftOnly, rightOnly, leftNewer, rightNewer, different, conflict; //category view + bool equal; // + bool conflict; //shared + bool excluded; // + bool leftOnly, rightOnly, leftNewer, rightNewer, different; //category view bool createLeft, createRight, updateLeft, updateRight, deleteLeft, deleteRight, doNothing; //action view }; @@ -155,7 +154,7 @@ struct XmlGlobalSettings size_t automaticRetryCount; size_t automaticRetryDelay; //unit: [sec] - size_t fileTimeTolerance; //max. allowed file time deviation + int fileTimeTolerance; //max. allowed file time deviation; < 0 means unlimited tolerance bool runWithBackgroundPriority; bool createLockFile; bool verifyFileCopy; //verify copied files @@ -195,8 +194,8 @@ struct XmlGlobalSettings defaultExclusionFilter(Zstr("/.fseventsd/") Zstr("\n") Zstr("/.Spotlight-V100/") Zstr("\n") Zstr("/.Trashes/") Zstr("\n") - Zstr("/._.Trashes") Zstr("\n") - Zstr("*/.DS_Store")), + Zstr("*/.DS_Store") Zstr("\n") + Zstr("*/._.*")), #endif //deleteOnBothSides(false), useRecyclerForManualDeletion(true), //enable if OS supports it; else user will have to activate first and then get an error message diff --git a/FreeFileSync/Source/lib/shadow.cpp b/FreeFileSync/Source/lib/shadow.cpp index 8a30bd3f..7160a3c0 100644 --- a/FreeFileSync/Source/lib/shadow.cpp +++ b/FreeFileSync/Source/lib/shadow.cpp @@ -90,7 +90,7 @@ private: //############################################################################################################# -Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile, const std::function<void(const Zstring&)>& onBeforeMakeVolumeCopy) +Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile, const std::function<void(const Zstring& volumeNamePf)>& onBeforeMakeVolumeCopy) { Zstring filenameFinal = inputFile; diff --git a/FreeFileSync/Source/lib/shadow.h b/FreeFileSync/Source/lib/shadow.h index 36c72c25..ec7bac7b 100644 --- a/FreeFileSync/Source/lib/shadow.h +++ b/FreeFileSync/Source/lib/shadow.h @@ -21,7 +21,7 @@ public: ShadowCopy() {} //return filename on shadow copy volume - follows symlinks! - Zstring makeShadowCopy(const Zstring& inputFile, const std::function<void(const Zstring&)>& onBeforeMakeVolumeCopy); //throw FileError + Zstring makeShadowCopy(const Zstring& inputFile, const std::function<void(const Zstring& volumeNamePf)>& onBeforeMakeVolumeCopy); //throw FileError private: ShadowCopy(const ShadowCopy&); diff --git a/FreeFileSync/Source/lib/status_handler_impl.h b/FreeFileSync/Source/lib/status_handler_impl.h index 6b364ba3..280fe9ae 100644 --- a/FreeFileSync/Source/lib/status_handler_impl.h +++ b/FreeFileSync/Source/lib/status_handler_impl.h @@ -11,7 +11,8 @@ #include <zen/file_error.h> #include "../process_callback.h" - +namespace zen +{ template <typename Function> inline zen::Opt<std::wstring> tryReportingError(Function cmd, ProcessCallback& handler) //return ignored error message if available { @@ -34,4 +35,61 @@ zen::Opt<std::wstring> tryReportingError(Function cmd, ProcessCallback& handler) } +//manage statistics reporting for a single item of work +class StatisticsReporter +{ +public: + StatisticsReporter(int itemsExpected, const Int64& bytesExpected, ProcessCallback& cb) : + taskCancelled(true), + itemsReported(0), + itemsExpected_(itemsExpected), + bytesExpected_(bytesExpected), + cb_(cb) {} + + ~StatisticsReporter() + { + if (taskCancelled) + cb_.updateTotalData(itemsReported, bytesReported); //=> unexpected increase of total workload + } + + void reportDelta(int itemsDelta, const Int64& bytesDelta) //may throw! + { + cb_.updateProcessedData(itemsDelta, bytesDelta); //nothrow! -> ensure client and service provider are in sync! + itemsReported += itemsDelta; + bytesReported += bytesDelta; // + + //special rule: avoid temporary statistics mess up, even though they are corrected anyway below: + if (itemsReported > itemsExpected_) + { + cb_.updateTotalData(itemsReported - itemsExpected_, 0); + itemsReported = itemsExpected_; + } + if (bytesReported > bytesExpected_) + { + cb_.updateTotalData(0, bytesReported - bytesExpected_); //=> everything above "bytesExpected" adds to both "processed" and "total" data + bytesReported = bytesExpected_; + } + + cb_.requestUiRefresh(); //may throw! + } + + void reportFinished() //nothrow! + { + assert(taskCancelled); + //update statistics to consider the real amount of data, e.g. more than the "file size" for ADS streams, + //less for sparse and compressed files, or file changed in the meantime! + cb_.updateTotalData(itemsReported - itemsExpected_, bytesReported - bytesExpected_); //noexcept! + taskCancelled = false; + } + +private: + bool taskCancelled; + int itemsReported; + Int64 bytesReported; + const int itemsExpected_; + const Int64 bytesExpected_; + ProcessCallback& cb_; +}; +} + #endif //STATUSHANDLER_IMPL_H_INCLUDED diff --git a/FreeFileSync/Source/lib/versioning.cpp b/FreeFileSync/Source/lib/versioning.cpp index 82696e3a..19d90dbc 100644 --- a/FreeFileSync/Source/lib/versioning.cpp +++ b/FreeFileSync/Source/lib/versioning.cpp @@ -165,21 +165,26 @@ void moveObject(const Zstring& sourceFile, //throw FileError } -void moveFile(const Zstring& sourceFile, const Zstring& targetFile, CallbackCopyFile& callback) //throw FileError +void moveFile(const Zstring& sourceFile, //throw FileError + const Zstring& targetFile, + const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus) //may be nullptr { - moveObject(sourceFile, //throw FileError - targetFile, - [&] + auto copyDelete = [&] { //create target if (symlinkExists(sourceFile)) copySymlink(sourceFile, targetFile, false); //throw FileError; don't copy filesystem permissions else - copyFile(sourceFile, targetFile, false, true, &callback); //throw FileError - permissions "false", transactional copy "true" + { + auto onDeleteTargetFile = [&]() { assert(!somethingExists(targetFile)); }; + copyFile(sourceFile, targetFile, false, true, onDeleteTargetFile, onUpdateCopyStatus); //throw FileError - permissions "false", transactional copy "true" + } //delete source removeFile(sourceFile); //throw FileError; newly copied file is NOT deleted if exception is thrown here! - }); + }; + + moveObject(sourceFile, targetFile, copyDelete); //throw FileError } @@ -233,23 +238,16 @@ private: } -bool FileVersioner::revisionFile(const Zstring& fullName, const Zstring& relativeName, CallbackMoveFile& callback) //throw FileError +bool FileVersioner::revisionFile(const Zstring& fullName, const Zstring& relativeName, const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus) //throw FileError { - struct CallbackMoveFileImpl : public CallbackMoveDir - { - CallbackMoveFileImpl(CallbackMoveFile& callback) : callback_(callback) {} - private: - virtual void onBeforeFileMove(const Zstring& fileFrom, const Zstring& fileTo) {} - virtual void onBeforeDirMove (const Zstring& dirFrom, const Zstring& dirTo ) {} - virtual void updateStatus(Int64 bytesDelta) { callback_.updateStatus(bytesDelta); } - CallbackMoveFile& callback_; - } cb(callback); - - return revisionFileImpl(fullName, relativeName, cb); //throw FileError + return revisionFileImpl(fullName, relativeName, nullptr, onUpdateCopyStatus); //throw FileError } -bool FileVersioner::revisionFileImpl(const Zstring& fullName, const Zstring& relativeName, CallbackMoveDir& callback) //throw FileError +bool FileVersioner::revisionFileImpl(const Zstring& fullName, //throw FileError + const Zstring& relativeName, + const std::function<void(const Zstring& fileFrom, const Zstring& fileTo)>& onBeforeFileMove, + const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus) { bool moveSuccessful = false; @@ -260,35 +258,33 @@ bool FileVersioner::revisionFileImpl(const Zstring& fullName, const Zstring& rel versioningStyle_, [&](const Zstring& source, const Zstring& target) { - callback.onBeforeFileMove(source, target); //if we're called by revisionDirImpl() we know that "source" exists! + if (onBeforeFileMove) + onBeforeFileMove(source, target); //if we're called by revisionDirImpl() we know that "source" exists! //when called by revisionFile(), "source" might not exist, however onBeforeFileMove() is not propagated in this case! - struct CopyCallbackImpl : public CallbackCopyFile - { - CopyCallbackImpl(CallbackMoveDir& callback) : callback_(callback) {} - private: - virtual void deleteTargetFile(const Zstring& targetFile) { assert(!somethingExists(targetFile)); } - virtual void updateCopyStatus(Int64 bytesDelta) { callback_.updateStatus(bytesDelta); } - CallbackMoveDir& callback_; - } copyCallback(callback); - - moveFile(source, target, copyCallback); //throw FileError + moveFile(source, target, onUpdateCopyStatus); //throw FileError moveSuccessful = true; }); return moveSuccessful; } -void FileVersioner::revisionDir(const Zstring& fullName, const Zstring& relativeName, CallbackMoveDir& callback) //throw FileError +void FileVersioner::revisionDir(const Zstring& fullName, const Zstring& relativeName, //throw FileError + const std::function<void(const Zstring& fileFrom, const Zstring& fileTo)>& onBeforeFileMove, + const std::function<void(const Zstring& dirFrom, const Zstring& dirTo )>& onBeforeDirMove, + const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus) { //no error situation if directory is not existing! manual deletion relies on it! if (!somethingExists(fullName)) return; //neither directory nor any other object (e.g. broken symlink) with that name existing - revisionDirImpl(fullName, relativeName, callback); //throw FileError + revisionDirImpl(fullName, relativeName, onBeforeFileMove, onBeforeDirMove, onUpdateCopyStatus); //throw FileError } -void FileVersioner::revisionDirImpl(const Zstring& fullName, const Zstring& relativeName, CallbackMoveDir& callback) //throw FileError +void FileVersioner::revisionDirImpl(const Zstring& fullName, const Zstring& relativeName, //throw FileError + const std::function<void(const Zstring& fileFrom, const Zstring& fileTo)>& onBeforeFileMove, + const std::function<void(const Zstring& dirFrom, const Zstring& dirTo )>& onBeforeDirMove, + const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus) { assert(somethingExists(fullName)); //[!] @@ -302,7 +298,8 @@ void FileVersioner::revisionDirImpl(const Zstring& fullName, const Zstring& rela versioningStyle_, [&](const Zstring& source, const Zstring& target) { - callback.onBeforeDirMove(source, target); + if (onBeforeDirMove) + onBeforeDirMove(source, target); moveDirSymlink(source, target); //throw FileError }); } @@ -323,28 +320,23 @@ void FileVersioner::revisionDirImpl(const Zstring& fullName, const Zstring& rela } const Zstring fullNamePf = appendSeparator(fullName); - const Zstring relnamePf = appendSeparator(relativeName); + const Zstring relnamePf = appendSeparator(relativeName); //move files - std::for_each(fileList.begin(), fileList.end(), - [&](const Zstring& shortname) - { + for (const Zstring& shortname : fileList) revisionFileImpl(fullNamePf + shortname, //throw FileError relnamePf + shortname, - callback); - }); + onBeforeFileMove, onUpdateCopyStatus); //move items in subdirectories - std::for_each(dirList.begin(), dirList.end(), - [&](const Zstring& shortname) - { + for (const Zstring& shortname : dirList) revisionDirImpl(fullNamePf + shortname, //throw FileError relnamePf + shortname, - callback); - }); + onBeforeFileMove, onBeforeDirMove, onUpdateCopyStatus); //delete source - callback.onBeforeDirMove(fullName, targetDir); + if (onBeforeDirMove) + onBeforeDirMove(fullName, targetDir); removeDirectory(fullName); //throw FileError } } diff --git a/FreeFileSync/Source/lib/versioning.h b/FreeFileSync/Source/lib/versioning.h index 06065656..1751e294 100644 --- a/FreeFileSync/Source/lib/versioning.h +++ b/FreeFileSync/Source/lib/versioning.h @@ -17,9 +17,6 @@ namespace zen { -struct CallbackMoveDir; -struct CallbackMoveFile; - //e.g. move C:\Source\subdir\Sample.txt -> D:\Revisions\subdir\Sample.txt 2012-05-15 131513.txt //scheme: <revisions directory>\<relpath>\<filename>.<ext> YYYY-MM-DD HHMMSS.<ext> /* @@ -46,14 +43,31 @@ public: throw FileError(_("Unable to create timestamp for versioning:") + L" \"" + timeStamp_ + L"\""); } - bool revisionFile(const Zstring& fullName, const Zstring& relativeName, CallbackMoveFile& callback); //throw FileError; return "false" if file is not existing - void revisionDir (const Zstring& fullName, const Zstring& relativeName, CallbackMoveDir& callback); //throw FileError + bool revisionFile(const Zstring& fullName, //throw FileError; return "false" if file is not existing + const Zstring& relativeName, + + //called frequently if move has to revert to copy + delete => see zen::copyFile for limitations when throwing exceptions! + const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus); //may be nullptr + + void revisionDir (const Zstring& fullName, const Zstring& relativeName, //throw FileError + + //optional callbacks: may be nullptr + const std::function<void(const Zstring& fileFrom, const Zstring& fileTo)>& onBeforeFileMove, //one call for each *existing* object! + const std::function<void(const Zstring& dirFrom, const Zstring& dirTo )>& onBeforeDirMove, // + //called frequently if move has to revert to copy + delete => see zen::copyFile for limitations when throwing exceptions! + const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus); //void limitVersions(std::function<void()> updateUI); //throw FileError; call when done revisioning! private: - bool revisionFileImpl(const Zstring& fullName, const Zstring& relativeName, CallbackMoveDir& callback); //throw FileError - void revisionDirImpl (const Zstring& fullName, const Zstring& relativeName, CallbackMoveDir& callback); //throw FileError + bool revisionFileImpl(const Zstring& fullName, const Zstring& relativeName, + const std::function<void(const Zstring& fileFrom, const Zstring& fileTo)>& onBeforeFileMove, + const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus); //throw FileError + + void revisionDirImpl (const Zstring& fullName, const Zstring& relativeName, + const std::function<void(const Zstring& fileFrom, const Zstring& fileTo)>& onBeforeFileMove, + const std::function<void(const Zstring& dirFrom, const Zstring& dirTo )>& onBeforeDirMove, + const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus); //throw FileError const VersioningStyle versioningStyle_; const Zstring versioningDirectory_; @@ -62,24 +76,6 @@ private: //std::vector<Zstring> fileRelNames; //store list of revisioned file and symlink relative names for limitVersions() }; - -struct CallbackMoveFile //see CallbackCopyFile for limitations when throwing exceptions! -{ - virtual ~CallbackMoveFile() {} - virtual void updateStatus(Int64 bytesDelta) = 0; //called frequently if move has to revert to copy + delete: -}; - -struct CallbackMoveDir //see CallbackCopyFile for limitations when throwing exceptions! -{ - virtual ~CallbackMoveDir() {} - - virtual void onBeforeFileMove(const Zstring& fileFrom, const Zstring& fileTo) = 0; //one call for each *existing* object! - virtual void onBeforeDirMove (const Zstring& dirFrom, const Zstring& dirTo ) = 0; // - virtual void updateStatus(Int64 bytesDelta) = 0; //called frequently if move has to revert to copy + delete: -}; - - - namespace impl //declare for unit tests: { bool isMatchingVersion(const Zstring& shortname, const Zstring& shortnameVersion); diff --git a/FreeFileSync/Source/process_callback.h b/FreeFileSync/Source/process_callback.h index fb9648fe..74c5fa06 100644 --- a/FreeFileSync/Source/process_callback.h +++ b/FreeFileSync/Source/process_callback.h @@ -37,15 +37,15 @@ struct ProcessCallback virtual void updateProcessedData(int objectsDelta, zen::Int64 dataDelta) = 0; //noexcept!! virtual void updateTotalData (int objectsDelta, zen::Int64 dataDelta) = 0; // /*the estimated and actual total workload may change *during* sync: - 1. detected file can be moved -> fallback to copy + delete + 1. file cannot be moved -> fallback to copy + delete 2. file copy, actual size changed after comparison 3. file contains significant ADS data, is sparse or compressed - 4. auto-resolution for failed create operations due to missing source - 5. directory deletion: may contain more items than scanned by FFS (excluded by filter) or less (contains followed symlinks) - 6. delete directory to recycler: no matter how many child-elements exist, this is only 1 item to process! - 7. file/directory already deleted externally: nothing to do, 0 logical operations and data + 4. file/directory already deleted externally: nothing to do, 0 logical operations and data + 5. auto-resolution for failed create operations due to missing source + 6. directory deletion: may contain more items than scanned by FFS (excluded by filter) or less (contains followed symlinks) + 7. delete directory to recycler: no matter how many child-elements exist, this is only 1 item to process! 8. user-defined deletion directory on different volume: full file copy required (instead of move) - 9. Binary file comparison: if files differ at the first few bytes, the result is already known + 9. Binary file comparison: short-circuit behavior if files differ 10. Error during file copy, retry: bytes were copied => increases total workload! */ diff --git a/FreeFileSync/Source/structures.cpp b/FreeFileSync/Source/structures.cpp index 04edf537..c04eb222 100644 --- a/FreeFileSync/Source/structures.cpp +++ b/FreeFileSync/Source/structures.cpp @@ -259,18 +259,18 @@ Int64 resolve(size_t value, UnitTime unit, Int64 defaultVal) locTimeStruc.hour = 0; //0-23 return localToTimeT(locTimeStruc); //convert local time back to UTC - //case UTIME_THIS_WEEK: - //{ - // localTimeFmt->tm_sec = 0; //0-61 - // localTimeFmt->tm_min = 0; //0-59 - // localTimeFmt->tm_hour = 0; //0-23 - // const time_t timeFrom = ::mktime(localTimeFmt); - - // int dayOfWeek = (localTimeFmt->tm_wday + 6) % 7; //tm_wday := days since Sunday 0-6 - // // +6 == -1 in Z_7 - - // return Int64(timeFrom) - daysSinceBeginOfWeek(dayOfWeek) * 24 * 3600; - //} + //case UTIME_THIS_WEEK: + //{ + // localTimeFmt->tm_sec = 0; //0-61 + // localTimeFmt->tm_min = 0; //0-59 + // localTimeFmt->tm_hour = 0; //0-23 + // const time_t timeFrom = ::mktime(localTimeFmt); + + // int dayOfWeek = (localTimeFmt->tm_wday + 6) % 7; //tm_wday := days since Sunday 0-6 + // // +6 == -1 in Z_7 + + // return Int64(timeFrom) - daysSinceBeginOfWeek(dayOfWeek) * 24 * 3600; + //} case UTIME_THIS_MONTH: locTimeStruc.second = 0; //0-61 diff --git a/FreeFileSync/Source/structures.h b/FreeFileSync/Source/structures.h index eeaf3f77..71554cc3 100644 --- a/FreeFileSync/Source/structures.h +++ b/FreeFileSync/Source/structures.h @@ -26,8 +26,8 @@ std::wstring getVariantName(CompareVariant var); enum SymLinkHandling { SYMLINK_EXCLUDE, - SYMLINK_USE_DIRECTLY, - SYMLINK_FOLLOW_LINK + SYMLINK_DIRECT, + SYMLINK_FOLLOW }; diff --git a/FreeFileSync/Source/synchronization.cpp b/FreeFileSync/Source/synchronization.cpp index fbb7a499..1c1aad7e 100644 --- a/FreeFileSync/Source/synchronization.cpp +++ b/FreeFileSync/Source/synchronization.cpp @@ -333,9 +333,9 @@ public: //clean-up temporary directory (recycle bin optimization) void tryCleanup(bool allowUserCallback = true); //throw FileError; throw X -> call this in non-exceptional coding, i.e. somewhere after sync! - template <class Function> void removeFileUpdating(const Zstring& fullName, const Zstring& relativeName, const Int64& bytesExpected, Function notifyItemDeletion); //throw FileError - template <class Function> void removeDirUpdating (const Zstring& fullName, const Zstring& relativeName, const Int64& bytesExpected, Function notifyItemDeletion); //reports ONLY data delta via updateProcessedData()! - template <class Function> void removeLinkUpdating(const Zstring& fullName, const Zstring& relativeName, const Int64& bytesExpected, Function notifyItemDeletion); // + template <class Function> void removeFileWithCallback (const Zstring& fullName, const Zstring& relativeName, Function onNotifyItemDeletion, const std::function<void(Int64 bytesDelta)>& onNotifyFileCopy); // + template <class Function> void removeDirWithCallback (const Zstring& fullName, const Zstring& relativeName, Function onNotifyItemDeletion, const std::function<void(Int64 bytesDelta)>& onNotifyFileCopy); //throw FileError + template <class Function> void removeLinkWithCallback (const Zstring& fullName, const Zstring& relativeName, Function onNotifyItemDeletion, const std::function<void(Int64 bytesDelta)>& onNotifyFileCopy); // const std::wstring& getTxtRemovingFile () const { return txtRemovingFile; } // const std::wstring& getTxtRemovingSymLink() const { return txtRemovingSymlink; } //buffered status texts @@ -372,6 +372,9 @@ private: std::wstring txtRemovingFile; std::wstring txtRemovingSymlink; std::wstring txtRemovingDirectory; + + const std::wstring txtMovingFile; + const std::wstring txtMovingFolder; }; @@ -386,7 +389,9 @@ DeletionHandling::DeletionHandling(DeletionPolicy handleDel, //nothrow! versioningDir_(versioningDir), versioningStyle_(versioningStyle), timeStamp_(timeStamp), - deletionPolicy_(handleDel) + deletionPolicy_(handleDel), + txtMovingFile (_("Moving file %x to %y")), + txtMovingFolder(_("Moving folder %x to %y")) { switch (deletionPolicy_) { @@ -412,28 +417,6 @@ DeletionHandling::DeletionHandling(DeletionPolicy handleDel, //nothrow! #ifdef ZEN_WIN -class CallbackMassRecycling : public CallbackRecycling -{ -public: - CallbackMassRecycling(ProcessCallback& statusHandler) : - statusHandler_(statusHandler), - 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) - { - if (!currentItem.empty()) - statusHandler_.reportStatus(replaceCpy(txtRecyclingFile, L"%x", fmtFileName(currentItem))); //throw ? - else - statusHandler_.requestUiRefresh(); //throw ? - } - -private: - ProcessCallback& statusHandler_; - const std::wstring txtRecyclingFile; -}; - - //create + returns temporary directory postfixed with file name separator //to support later cleanup if automatic deletion fails for whatever reason Zstring DeletionHandling::getOrCreateRecyclerTempDirPf() //throw FileError @@ -499,9 +482,20 @@ void DeletionHandling::tryCleanup(bool allowUserCallback) //throw FileError; thr #ifdef ZEN_WIN if (!toBeRecycled.empty()) { + //may throw: first exception is swallowed, notifyDeletionStatus() is then called again where it should throw again and the exception will propagate as expected + auto notifyDeletionStatus = [&](const Zstring& currentItem) + { + if (!currentItem.empty()) + procCallback_.reportStatus(replaceCpy(txtRemovingFile, L"%x", fmtFileName(currentItem))); //throw ? + else + procCallback_.requestUiRefresh(); //throw ? + }; + //move content of temporary directory to recycle bin in a single call - CallbackMassRecycling cbmr(procCallback_); - recycleOrDelete(toBeRecycled, allowUserCallback ? &cbmr : nullptr); //throw FileError + if (allowUserCallback) + recycleOrDelete(toBeRecycled, notifyDeletionStatus); //throw FileError + else + recycleOrDelete(toBeRecycled, nullptr); //throw FileError toBeRecycled.clear(); } @@ -531,86 +525,24 @@ void DeletionHandling::tryCleanup(bool allowUserCallback) //throw FileError; thr template <class Function> -struct CallbackRemoveDirImpl : public CallbackRemoveDir -{ - CallbackRemoveDirImpl(ProcessCallback& statusHandler, - const DeletionHandling& delHandling, - Function notifyItemDeletion) : - statusHandler_(statusHandler), - notifyItemDeletion_(notifyItemDeletion), - txtDeletingFile (delHandling.getTxtRemovingFile()), - txtDeletingFolder(delHandling.getTxtRemovingDir ()) {} - -private: - virtual void onBeforeFileDeletion(const Zstring& filename) { notifyDeletion(txtDeletingFile, filename); } - virtual void onBeforeDirDeletion (const Zstring& dirname ) { notifyDeletion(txtDeletingFolder, dirname ); } - - void notifyDeletion(const std::wstring& statusText, const Zstring& objName) - { - notifyItemDeletion_(); //it would be more correct to report *after* work was done! - statusHandler_.reportStatus(replaceCpy(statusText, L"%x", fmtFileName(objName))); - } - - ProcessCallback& statusHandler_; - Function notifyItemDeletion_; - const std::wstring txtDeletingFile; - const std::wstring txtDeletingFolder; -}; - - -template <class Function> -class CallbackMoveDirImpl : public CallbackMoveDir -{ -public: - CallbackMoveDirImpl(ProcessCallback& callback, - Int64& bytesReported, - Function notifyItemDeletion) : - callback_ (callback), - bytesReported_(bytesReported), - notifyItemDeletion_(notifyItemDeletion), - txtMovingFile (_("Moving file %x to %y")), - txtMovingFolder (_("Moving folder %x to %y")) {} - -private: - virtual void onBeforeFileMove(const Zstring& fileFrom, const Zstring& fileTo) { notifyMove(txtMovingFile, fileFrom, fileTo); } - virtual void onBeforeDirMove (const Zstring& dirFrom, const Zstring& dirTo ) { notifyMove(txtMovingFolder, dirFrom, dirTo); } - - void notifyMove(const std::wstring& statusText, const Zstring& fileFrom, const Zstring& fileTo) const - { - notifyItemDeletion_(); //it would be more correct to report *after* work was done! - callback_.reportStatus(replaceCpy(replaceCpy(statusText, L"%x", L"\n" + fmtFileName(fileFrom)), L"%y", L"\n" + fmtFileName(fileTo))); - }; - - 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_; - Function notifyItemDeletion_; - const std::wstring txtMovingFile; - const std::wstring txtMovingFolder; -}; - - -template <class Function> -void DeletionHandling::removeDirUpdating(const Zstring& fullName, - const Zstring& relativeName, - const Int64& bytesExpected, Function notifyItemDeletion) //throw FileError +void DeletionHandling::removeDirWithCallback(const Zstring& fullName, + const Zstring& relativeName, + Function onNotifyItemDeletion, + const std::function<void(Int64 bytesDelta)>& onNotifyFileCopy) //throw FileError { - Int64 bytesReported; - ScopeGuard guardStatistics = makeGuard([&] { procCallback_.updateTotalData(0, bytesReported); }); //error = unexpected increase of total workload - switch (deletionPolicy_) { case DELETE_PERMANENTLY: { - CallbackRemoveDirImpl<Function> remDirCallback(procCallback_, *this, notifyItemDeletion); - removeDirectory(fullName, &remDirCallback); + auto notifyDeletion = [&](const std::wstring& statusText, const Zstring& objName) + { + onNotifyItemDeletion(); //it would be more correct to report *after* work was done! + procCallback_.reportStatus(replaceCpy(statusText, L"%x", fmtFileName(objName))); + }; + auto onBeforeFileDeletion = [&](const Zstring& filename) { notifyDeletion(txtRemovingFile, filename); }; + auto onBeforeDirDeletion = [&](const Zstring& dirname ) { notifyDeletion(txtRemovingDirectory, dirname ); }; + + removeDirectory(fullName, onBeforeFileDeletion, onBeforeDirDeletion); } break; @@ -658,32 +590,34 @@ void DeletionHandling::removeDirUpdating(const Zstring& fullName, const bool deleted = recycleOrDelete(fullName); //throw FileError #endif if (deleted) - notifyItemDeletion(); //moving to recycler is ONE logical operation, irrespective of the number of child elements! + onNotifyItemDeletion(); //moving to recycler is ONE logical operation, irrespective of the number of child elements! } break; case DELETE_TO_VERSIONING: { - CallbackMoveDirImpl<Function> callback(procCallback_, bytesReported, notifyItemDeletion); - getOrCreateVersioner().revisionDir(fullName, relativeName, callback); //throw FileError + auto notifyMove = [&](const std::wstring& statusText, const Zstring& fileFrom, const Zstring& fileTo) + { + onNotifyItemDeletion(); //it would be more correct to report *after* work was done! + procCallback_.reportStatus(replaceCpy(replaceCpy(statusText, L"%x", L"\n" + fmtFileName(fileFrom)), L"%y", L"\n" + fmtFileName(fileTo))); + }; + + auto onBeforeFileMove = [&](const Zstring& fileFrom, const Zstring& fileTo) { notifyMove(txtMovingFile, fileFrom, fileTo); }; + auto onBeforeDirMove = [&](const Zstring& dirFrom, const Zstring& dirTo ) { notifyMove(txtMovingFolder, dirFrom, dirTo); }; + + getOrCreateVersioner().revisionDir(fullName, relativeName, onBeforeFileMove, onBeforeDirMove, onNotifyFileCopy); //throw FileError } break; } - - //update statistics to consider the real amount of data - guardStatistics.dismiss(); - if (bytesReported != bytesExpected) - procCallback_.updateTotalData(0, bytesReported - bytesExpected); //noexcept! } template <class Function> -void DeletionHandling::removeFileUpdating(const Zstring& fullName, - const Zstring& relativeName, - const Int64& bytesExpected, Function notifyItemDeletion) //throw FileError +void DeletionHandling::removeFileWithCallback(const Zstring& fullName, + const Zstring& relativeName, + Function onNotifyItemDeletion, + const std::function<void(Int64 bytesDelta)>& onNotifyFileCopy) //throw FileError { - Int64 bytesReported; - auto guardStatistics = makeGuard([&] { procCallback_.updateTotalData(0, bytesReported); }); //error = unexpected increase of total workload bool deleted = false; if (endsWith(relativeName, TEMP_FILE_ENDING)) //special rule for .ffs_tmp files: always delete permanently! @@ -741,44 +675,21 @@ void DeletionHandling::removeFileUpdating(const Zstring& fullName, break; case DELETE_TO_VERSIONING: - { - struct CallbackMoveFileImpl : public CallbackMoveFile - { - CallbackMoveFileImpl(ProcessCallback& callback, Int64& bytes) : callback_(callback), bytesReported_(bytes) {} - - 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 - } - break; + deleted = getOrCreateVersioner().revisionFile(fullName, relativeName, onNotifyFileCopy); //throw FileError + break; } if (deleted) - notifyItemDeletion(); - - //update statistics to consider the real amount of data - guardStatistics.dismiss(); - if (bytesReported != bytesExpected) - procCallback_.updateTotalData(0, bytesReported - bytesExpected); //noexcept! + onNotifyItemDeletion(); } template <class Function> inline -void DeletionHandling::removeLinkUpdating(const Zstring& fullName, const Zstring& relativeName, const Int64& bytesExpected, Function notifyItemDeletion) //throw FileError +void DeletionHandling::removeLinkWithCallback(const Zstring& fullName, const Zstring& relativeName, Function onNotifyItemDeletion, const std::function<void(Int64 bytesDelta)>& onNotifyFileCopy) //throw FileError { if (dirExists(fullName)) //dir symlink - return removeDirUpdating(fullName, relativeName, bytesExpected, notifyItemDeletion); //throw FileError + return removeDirWithCallback(fullName, relativeName, onNotifyItemDeletion, onNotifyFileCopy); //throw FileError else //file symlink, broken symlink - return removeFileUpdating(fullName, relativeName, bytesExpected, notifyItemDeletion); //throw FileError + return removeFileWithCallback(fullName, relativeName, onNotifyItemDeletion, onNotifyFileCopy); //throw FileError } //------------------------------------------------------------------------------------------------------------ @@ -947,8 +858,11 @@ private: procCallback_.reportInfo(replaceCpy(replaceCpy(rawText, L"%x", L"\n" + fmtFileName(objname1)), L"%y", L"\n" + fmtFileName(objname2))); }; - template <class Function> - InSyncAttributes copyFileUpdating(const Zstring& sourceFile, const Zstring& targetFile, const Int64& bytesExpected, Function delTargetCommand) const; //throw FileError; reports data delta via updateProcessedData() + InSyncAttributes copyFileWithCallback(const Zstring& sourceFile, + const Zstring& targetFile, + const std::function<void()>& onDeleteTargetFile, + const std::function<void(Int64 bytesDelta)>& onNotifyFileCopy) const; //throw FileError + void verifyFileCopy(const Zstring& source, const Zstring& target) const; template <SelectedSide side> @@ -1165,7 +1079,7 @@ void SynchronizeFolderPair::runZeroPass(HierarchyObject& hierObj) if (FilePair* targetObj = dynamic_cast<FilePair*>(FileSystemObject::retrieve(fileObj.getMoveRef()))) { FilePair* sourceObj = &fileObj; - assert(dynamic_cast<FilePair*>(FileSystemObject::retrieve(targetObj->getMoveRef())) == sourceObj); + assert(dynamic_cast<FilePair*>(FileSystemObject::retrieve(targetObj->getMoveRef())) == sourceObj); zen::Opt<std::wstring> errMsg = tryReportingError([&] { @@ -1180,23 +1094,23 @@ void SynchronizeFolderPair::runZeroPass(HierarchyObject& hierObj) //move operation has failed! We cannot allow to continue and have move source's parent directory deleted, messing up statistics! // => revert to ordinary "copy + delete" - auto getStat = [&]() -> std::pair<int, Int64> + auto getStats = [&]() -> std::pair<int, Int64> { SyncStatistics statSrc(*sourceObj); SyncStatistics statTrg(*targetObj); - return std::make_pair(getCUD(statSrc) + getCUD(statTrg), statSrc.getDataToProcess() + statTrg.getDataToProcess()); }; - const auto statBefore = getStat(); + const auto statBefore = getStats(); sourceObj->setMoveRef(nullptr); targetObj->setMoveRef(nullptr); - const auto statAfter = getStat(); - //fix statistics to total to match "copy + delete" + const auto statAfter = getStats(); + //fix statistics total to match "copy + delete" procCallback_.updateTotalData(statAfter.first - statBefore.first, statAfter.second - statBefore.second); } } + else assert(false); break; case SO_MOVE_LEFT_TARGET: //it's enough to try each move-pair *once* @@ -1415,11 +1329,17 @@ void SynchronizeFolderPair::synchronizeFileInt(FilePair& fileObj, SyncOperation const Zstring& target = fileObj.getBaseDirPf<sideTrg>() + fileObj.getRelativeName<sideSrc>(); //can't use "getFullName" as target is not yet existing reportInfo(txtCreatingFile, target); + StatisticsReporter statReporter(1, to<zen::Int64>(fileObj.getFileSize<sideSrc>()), procCallback_); try { - const InSyncAttributes newAttr = copyFileUpdating(fileObj.getFullName<sideSrc>(), - target, - to<Int64>(fileObj.getFileSize<sideSrc>()), [] {} /*no target to delete*/); //throw FileError + auto onNotifyFileCopy = [&](Int64 bytesDelta) { statReporter.reportDelta(0, bytesDelta); }; + + const InSyncAttributes newAttr = copyFileWithCallback(fileObj.getFullName<sideSrc>(), + target, + nullptr, //no target to delete + onNotifyFileCopy); //throw FileError + statReporter.reportDelta(1, 0); + //update FilePair fileObj.setSyncedTo<sideTrg>(fileObj.getShortName<sideSrc>(), newAttr.fileSize, newAttr.modificationTime, //target time set from source @@ -1427,17 +1347,15 @@ void SynchronizeFolderPair::synchronizeFileInt(FilePair& fileObj, SyncOperation newAttr.targetFileId, newAttr.sourceFileId, false, fileObj.isFollowedSymlink<sideSrc>()); - - procCallback_.updateProcessedData(1, 0); //processed bytes are reported in copyFileUpdating()! } catch (FileError&) { if (somethingExists(fileObj.getFullName<sideSrc>())) //do not check on type (symlink, file, folder) -> if there is a type change, FFS should error out! throw; //source deleted meanwhile...nothing was done (logical point of view!) - procCallback_.updateTotalData(-1, -to<zen::Int64>(fileObj.getFileSize<sideSrc>())); fileObj.removeObject<sideSrc>(); //remove only *after* evaluating "fileObj, sideSrc"! } + statReporter.reportFinished(); } break; @@ -1445,22 +1363,17 @@ void SynchronizeFolderPair::synchronizeFileInt(FilePair& fileObj, SyncOperation case SO_DELETE_RIGHT: reportInfo(getDelHandling<sideTrg>().getTxtRemovingFile(), fileObj.getFullName<sideTrg>()); { - int objectsReported = 0; - auto guardStatistics = makeGuard([&] { procCallback_.updateTotalData(objectsReported, 0); }); //error = unexpected increase of total workload - const int objectsExpected = 1; - const Int64 bytesExpected = 0; + StatisticsReporter statReporter(1, 0, procCallback_); - getDelHandling<sideTrg>().removeFileUpdating(fileObj.getFullName<sideTrg>(), fileObj.getObjRelativeName(), bytesExpected, [&] //throw FileError - { - procCallback_.updateProcessedData(1, 0); //noexcept - ++objectsReported; - }); + auto onNotifyItemDeletion = [&] { statReporter.reportDelta(1, 0); }; + auto onNotifyFileCopy = [&](Int64 bytesDelta) { statReporter.reportDelta(0, bytesDelta); }; + + getDelHandling<sideTrg>().removeFileWithCallback(fileObj.getFullName<sideTrg>(), fileObj.getObjRelativeName(), onNotifyItemDeletion, onNotifyFileCopy); //throw FileError - guardStatistics.dismiss(); //update statistics to consider the real amount of data - if (objectsReported != objectsExpected) - procCallback_.updateTotalData(objectsReported - objectsExpected, 0); //noexcept! + fileObj.removeObject<sideTrg>(); //update FilePair + + statReporter.reportFinished(); } - fileObj.removeObject<sideTrg>(); //update FilePair break; case SO_MOVE_LEFT_TARGET: @@ -1509,14 +1422,15 @@ void SynchronizeFolderPair::synchronizeFileInt(FilePair& fileObj, SyncOperation renameFile(fileObj.getFullName<sideTrg>(), beforeLast(fileObj.getFullName<sideTrg>(), FILE_NAME_SEPARATOR) + FILE_NAME_SEPARATOR + fileObj.getShortName<sideSrc>()); //throw FileError - const InSyncAttributes newAttr = copyFileUpdating(fileObj.getFullName<sideSrc>(), - targetFile, - to<Int64>(fileObj.getFileSize<sideSrc>()), - [&] //delete target at appropriate time + StatisticsReporter statReporter(1, to<zen::Int64>(fileObj.getFileSize<sideSrc>()), procCallback_); + + auto onNotifyFileCopy = [&](Int64 bytesDelta) { statReporter.reportDelta(0, bytesDelta); }; + + auto onDeleteTargetFile = [&] //delete target at appropriate time { reportStatus(this->getDelHandling<sideTrg>().getTxtRemovingFile(), targetFile); - this->getDelHandling<sideTrg>().removeFileUpdating(targetFile, fileObj.getObjRelativeName(), 0, [] {}); //throw FileError; + this->getDelHandling<sideTrg>().removeFileWithCallback(targetFile, fileObj.getObjRelativeName(), [] {}, onNotifyFileCopy); //throw FileError; //no (logical) item count update desired - but total byte count may change, e.g. move(copy) deleted file to versioning dir //fileObj.removeObject<sideTrg>(); -> doesn't make sense for isFollowedSymlink(); "fileObj, sideTrg" evaluated below! @@ -1525,7 +1439,13 @@ void SynchronizeFolderPair::synchronizeFileInt(FilePair& fileObj, SyncOperation //=> don't risk reportStatus() throwing GuiAbortProcess() leaving the target deleted rather than updated! if (!transactionalFileCopy_) reportStatus(txtOverwritingFile, targetFile); //restore status text copy file - }); //throw FileError + }; + + const InSyncAttributes newAttr = copyFileWithCallback(fileObj.getFullName<sideSrc>(), + targetFile, + onDeleteTargetFile, + onNotifyFileCopy); //throw FileError + statReporter.reportDelta(1, 0); //we model "delete + copy" as ONE logical operation //update FilePair fileObj.setSyncedTo<sideTrg>(fileObj.getShortName<sideSrc>(), newAttr.fileSize, @@ -1536,7 +1456,7 @@ void SynchronizeFolderPair::synchronizeFileInt(FilePair& fileObj, SyncOperation fileObj.isFollowedSymlink<sideTrg>(), fileObj.isFollowedSymlink<sideSrc>()); - procCallback_.updateProcessedData(1, 0); //we model "delete + copy" as ONE logical operation + statReporter.reportFinished(); } break; @@ -1551,7 +1471,7 @@ void SynchronizeFolderPair::synchronizeFileInt(FilePair& fileObj, SyncOperation beforeLast(fileObj.getFullName<sideTrg>(), FILE_NAME_SEPARATOR) + FILE_NAME_SEPARATOR + fileObj.getShortName<sideSrc>()); //throw FileError if (!sameFileTime(fileObj.getLastWriteTime<sideTrg>(), fileObj.getLastWriteTime<sideSrc>(), 2)) //respect 2 second FAT/FAT32 precision - setFileTime(fileObj.getFullName<sideTrg>(), fileObj.getLastWriteTime<sideSrc>(), SYMLINK_FOLLOW); //throw FileError + setFileTime(fileObj.getFullName<sideTrg>(), fileObj.getLastWriteTime<sideSrc>(), ProcSymlink::FOLLOW); //throw FileError //do NOT read *current* source file time, but use buffered value which corresponds to time of comparison! //-> both sides *should* be completely equal now... @@ -1565,7 +1485,7 @@ void SynchronizeFolderPair::synchronizeFileInt(FilePair& fileObj, SyncOperation fileObj.isFollowedSymlink<sideSrc>()); procCallback_.updateProcessedData(1, 0); - break; + break; case SO_MOVE_LEFT_SOURCE: //use SO_MOVE_LEFT_TARGET/SO_MOVE_RIGHT_TARGET to execute move: case SO_MOVE_RIGHT_SOURCE: //=> makes sure parent directory has been created @@ -1613,6 +1533,7 @@ void SynchronizeFolderPair::synchronizeLinkInt(SymlinkPair& linkObj, SyncOperati reportInfo(txtCreatingLink, target); + StatisticsReporter statReporter(1, 0, procCallback_); try { zen::copySymlink(linkObj.getFullName<sideSrc>(), target, copyFilePermissions_); //throw FileError @@ -1621,16 +1542,16 @@ void SynchronizeFolderPair::synchronizeLinkInt(SymlinkPair& linkObj, SyncOperati linkObj.getLastWriteTime<sideSrc>(), //target time set from source linkObj.getLastWriteTime<sideSrc>()); - procCallback_.updateProcessedData(1, 0); + statReporter.reportDelta(1, 0); } catch (FileError&) { if (somethingExists(linkObj.getFullName<sideSrc>())) //do not check on type (symlink, file, folder) -> if there is a type change, FFS should not be quiet about it! throw; //source deleted meanwhile...nothing was done (logical point of view!) - procCallback_.updateTotalData(-1, 0); linkObj.removeObject<sideSrc>(); } + statReporter.reportFinished(); } break; @@ -1638,46 +1559,48 @@ void SynchronizeFolderPair::synchronizeLinkInt(SymlinkPair& linkObj, SyncOperati case SO_DELETE_RIGHT: reportInfo(getDelHandling<sideTrg>().getTxtRemovingSymLink(), linkObj.getFullName<sideTrg>()); { - int objectsReported = 0; - auto guardStatistics = makeGuard([&] { procCallback_.updateTotalData(objectsReported, 0); }); //error = unexpected increase of total workload - const int objectsExpected = 1; - const Int64 bytesExpected = 0; + StatisticsReporter statReporter(1, 0, procCallback_); - getDelHandling<sideTrg>().removeLinkUpdating(linkObj.getFullName<sideTrg>(), linkObj.getObjRelativeName(), bytesExpected, [&] //throw FileError - { - procCallback_.updateProcessedData(1, 0); //noexcept - ++objectsReported; - }); + auto onNotifyItemDeletion = [&] { statReporter.reportDelta(1, 0); }; + auto onNotifyFileCopy = [&](Int64 bytesDelta) { statReporter.reportDelta(0, bytesDelta); }; - guardStatistics.dismiss(); //update statistics to consider the real amount of data - if (objectsReported != objectsExpected) - procCallback_.updateTotalData(objectsReported - objectsExpected, 0); //noexcept! + getDelHandling<sideTrg>().removeLinkWithCallback(linkObj.getFullName<sideTrg>(), linkObj.getObjRelativeName(), onNotifyItemDeletion, onNotifyFileCopy); //throw FileError + + linkObj.removeObject<sideTrg>(); //update SymlinkPair + + statReporter.reportFinished(); } - linkObj.removeObject<sideTrg>(); //update SymlinkPair break; case SO_OVERWRITE_LEFT: case SO_OVERWRITE_RIGHT: reportInfo(txtOverwritingLink, linkObj.getFullName<sideTrg>()); + { + StatisticsReporter statReporter(1, 0, procCallback_); - //reportStatus(getDelHandling<sideTrg>().getTxtRemovingSymLink(), linkObj.getFullName<sideTrg>()); - getDelHandling<sideTrg>().removeLinkUpdating(linkObj.getFullName<sideTrg>(), linkObj.getObjRelativeName(), 0, [] {}); //throw FileError + auto onNotifyFileCopy = [&](Int64 bytesDelta) { statReporter.reportDelta(0, bytesDelta); }; - //linkObj.removeObject<sideTrg>(); -> "linkObj, sideTrg" evaluated below! + //reportStatus(getDelHandling<sideTrg>().getTxtRemovingSymLink(), linkObj.getFullName<sideTrg>()); + getDelHandling<sideTrg>().removeLinkWithCallback(linkObj.getFullName<sideTrg>(), linkObj.getObjRelativeName(), [] {}, onNotifyFileCopy); //throw FileError - //=> don't risk reportStatus() throwing GuiAbortProcess() leaving the target deleted rather than updated: + //linkObj.removeObject<sideTrg>(); -> "linkObj, sideTrg" evaluated below! - //reportStatus(txtOverwritingLink, linkObj.getFullName<sideTrg>()); //restore status text - zen::copySymlink(linkObj.getFullName<sideSrc>(), - linkObj.getBaseDirPf<sideTrg>() + linkObj.getRelativeName<sideSrc>(), //respect differences in case of source object - copyFilePermissions_); //throw FileError + //=> don't risk reportStatus() throwing GuiAbortProcess() leaving the target deleted rather than updated: + //reportStatus(txtOverwritingLink, linkObj.getFullName<sideTrg>()); //restore status text - //update SymlinkPair - linkObj.setSyncedTo<sideTrg>(linkObj.getShortName<sideSrc>(), - linkObj.getLastWriteTime<sideSrc>(), //target time set from source - linkObj.getLastWriteTime<sideSrc>()); + zen::copySymlink(linkObj.getFullName<sideSrc>(), + linkObj.getBaseDirPf<sideTrg>() + linkObj.getRelativeName<sideSrc>(), //respect differences in case of source object + copyFilePermissions_); //throw FileError + + statReporter.reportDelta(1, 0); //we model "delete + copy" as ONE logical operation - procCallback_.updateProcessedData(1, 0); //we model "delete + copy" as ONE logical operation + //update SymlinkPair + linkObj.setSyncedTo<sideTrg>(linkObj.getShortName<sideSrc>(), + linkObj.getLastWriteTime<sideSrc>(), //target time set from source + linkObj.getLastWriteTime<sideSrc>()); + + statReporter.reportFinished(); + } break; case SO_COPY_METADATA_TO_LEFT: @@ -1689,7 +1612,7 @@ void SynchronizeFolderPair::synchronizeLinkInt(SymlinkPair& linkObj, SyncOperati beforeLast(linkObj.getFullName<sideTrg>(), FILE_NAME_SEPARATOR) + FILE_NAME_SEPARATOR + linkObj.getShortName<sideSrc>()); //throw FileError if (!sameFileTime(linkObj.getLastWriteTime<sideTrg>(), linkObj.getLastWriteTime<sideSrc>(), 2)) //respect 2 second FAT/FAT32 precision - setFileTime(linkObj.getFullName<sideTrg>(), linkObj.getLastWriteTime<sideSrc>(), SYMLINK_DIRECT); //throw FileError + setFileTime(linkObj.getFullName<sideTrg>(), linkObj.getLastWriteTime<sideSrc>(), ProcSymlink::DIRECT); //throw FileError //-> both sides *should* be completely equal now... linkObj.setSyncedTo<sideTrg>(linkObj.getShortName<sideSrc>(), @@ -1775,27 +1698,22 @@ void SynchronizeFolderPair::synchronizeFolderInt(DirPair& dirObj, SyncOperation case SO_DELETE_RIGHT: reportInfo(getDelHandling<sideTrg>().getTxtRemovingDir(), dirObj.getFullName<sideTrg>()); { - int objectsReported = 0; - auto guardStatistics = makeGuard([&] { procCallback_.updateTotalData(objectsReported, 0); }); //error = unexpected increase of total workload const SyncStatistics subStats(dirObj); //counts sub-objects only! - const int objectsExpected = 1 + getCUD(subStats); - const Int64 bytesExpected = subStats.getDataToProcess(); - assert(bytesExpected == 0); - getDelHandling<sideTrg>().removeDirUpdating(dirObj.getFullName<sideTrg>(), dirObj.getObjRelativeName(), bytesExpected, [&] //throw FileError - { - procCallback_.updateProcessedData(1, 0); //noexcept - ++objectsReported; - }); + StatisticsReporter statReporter(1 + getCUD(subStats), subStats.getDataToProcess(), procCallback_); + + auto onNotifyItemDeletion = [&] { statReporter.reportDelta(1, 0); }; + auto onNotifyFileCopy = [&](Int64 bytesDelta) { statReporter.reportDelta(0, bytesDelta); }; + + getDelHandling<sideTrg>().removeDirWithCallback(dirObj.getFullName<sideTrg>(), dirObj.getObjRelativeName(), onNotifyItemDeletion, onNotifyFileCopy); //throw FileError + + dirObj.refSubFiles().clear(); // + dirObj.refSubLinks().clear(); //update DirPair + dirObj.refSubDirs ().clear(); // + dirObj.removeObject<sideTrg>(); // - guardStatistics.dismiss(); //update statistics to consider the real amount of data - if (objectsReported != objectsExpected) - procCallback_.updateTotalData(objectsReported - objectsExpected, 0); //noexcept! + statReporter.reportFinished(); } - dirObj.refSubFiles().clear(); // - dirObj.refSubLinks().clear(); //update DirPair - dirObj.refSubDirs ().clear(); // - dirObj.removeObject<sideTrg>(); // break; case SO_COPY_METADATA_TO_LEFT: @@ -1829,114 +1747,69 @@ void SynchronizeFolderPair::synchronizeFolderInt(DirPair& dirObj, SyncOperation procCallback_.requestUiRefresh(); //may throw } -//########################################################################################### - -template <class Function> -class WhileCopying : public zen::CallbackCopyFile -{ -public: - WhileCopying(Int64& bytesReported, - ProcessCallback& statusHandler, - Function delTargetCmd) : - bytesReported_(bytesReported), - statusHandler_(statusHandler), - delTargetCmd_(std::move(delTargetCmd)) {} - - virtual void deleteTargetFile(const Zstring& targetFile) { delTargetCmd_(); } - - virtual void updateCopyStatus(Int64 bytesDelta) - { - statusHandler_.updateProcessedData(0, bytesDelta); //throw()! -> ensure client and service provider are in sync! - bytesReported_ += bytesDelta; // - - statusHandler_.requestUiRefresh(); //may throw - } - -private: - Int64& bytesReported_; - ProcessCallback& statusHandler_; - Function delTargetCmd_; -}; +//########################################################################################### -//throw FileError; reports data delta via updateProcessedData() -template <class Function> -InSyncAttributes SynchronizeFolderPair::copyFileUpdating(const Zstring& sourceFile, - const Zstring& targetFile, - const Int64& bytesExpected, - Function delTargetCommand) const //returns current attributes of source file +InSyncAttributes SynchronizeFolderPair::copyFileWithCallback(const Zstring& sourceFile, //throw FileError + const Zstring& targetFile, + const std::function<void()>& onDeleteTargetFile, + const std::function<void(Int64 bytesDelta)>& onNotifyFileCopy) const //returns current attributes of source file { - Zstring source = sourceFile; - InSyncAttributes newAttr; - Int64 bytesReported; - - auto copyOperation = [&] + auto copyOperation = [this, &targetFile, &onDeleteTargetFile, &onNotifyFileCopy](const Zstring& sourceFileTmp) { - auto guardStatistics = makeGuard([&] - { - procCallback_.updateTotalData(0, bytesReported); //error = unexpected increase of total workload - bytesReported = 0; - }); - - WhileCopying<Function> callback(bytesReported, procCallback_, delTargetCommand); - - copyFile(source, //type File implicitly means symlinks need to be dereferenced! - targetFile, - copyFilePermissions_, - transactionalFileCopy_, - &callback, - &newAttr); //throw FileError, ErrorFileLocked + InSyncAttributes newAttr; + copyFile(sourceFileTmp, //type File implicitly means symlinks need to be dereferenced! + targetFile, + copyFilePermissions_, + transactionalFileCopy_, + onDeleteTargetFile, onNotifyFileCopy, + &newAttr); //throw FileError, ErrorFileLocked //#################### Verification ############################# if (verifyCopiedFiles_) { auto guardTarget = makeGuard([&] { removeFile(targetFile); }); //delete target if verification fails - verifyFileCopy(source, targetFile); //throw FileError + verifyFileCopy(sourceFileTmp, targetFile); //throw FileError guardTarget.dismiss(); } //#################### /Verification ############################# - //update statistics to consider the real amount of data, e.g. more than the "file size" for ADS streams, - //less for sparse and compressed files, or file changed in the meantime! - if (bytesReported != bytesExpected) - procCallback_.updateTotalData(0, bytesReported - bytesExpected); //noexcept! - - guardStatistics.dismiss(); + return newAttr; }; #ifdef ZEN_WIN try { - copyOperation(); + return copyOperation(sourceFile); } catch (ErrorFileLocked& e1) { //if file is locked (try to) use Windows Volume Shadow Copy Service if (!shadowCopyHandler_) throw; + + Zstring shadowSource; try { //contains prefix: E.g. "\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Program Files\FFS\sample.dat" - source = shadowCopyHandler_->makeShadowCopy(source, //throw FileError - [&](const Zstring& volumeName) + shadowSource = shadowCopyHandler_->makeShadowCopy(sourceFile, //throw FileError + [&](const Zstring& volumeName) { procCallback_.reportStatus(replaceCpy(_("Creating a Volume Shadow Copy for %x..."), L"%x", fmtFileName(volumeName))); procCallback_.forceUiRefresh(); }); } - catch (const FileError& e2) + catch (const FileError& e2) //enhance error massage { throw FileError(e1.toString(), e2.toString()); } //now try again - copyOperation(); + return copyOperation(shadowSource); } #else - copyOperation(); + return copyOperation(sourceFile); #endif - - return newAttr; } //--------------------- data verification ------------------------- @@ -2146,33 +2019,25 @@ void zen::synchronize(const TimeComp& timeStamp, }; //aggregate information - std::map<Zstring, std::pair<size_t, size_t>> dirReadWriteCount; //count read/write accesses + std::map<Zstring, std::pair<size_t, size_t>, LessFilename> dirReadWriteCount; //count read/write accesses auto incReadCount = [&](const Zstring& baseDir) { dirReadWriteCount[baseDir]; //create entry - for (auto it = dirReadWriteCount.begin(); it != dirReadWriteCount.end(); ++it) - { - auto& countRef = it->second; - if (dependentDir(baseDir, it->first)) - ++countRef.first; - } + for (auto& item : dirReadWriteCount) + if (dependentDir(baseDir, item.first)) + ++item.second.first; }; auto incWriteCount = [&](const Zstring& baseDir) { dirReadWriteCount[baseDir]; //create entry - for (auto it = dirReadWriteCount.begin(); it != dirReadWriteCount.end(); ++it) - { - auto& countRef = it->second; - if (dependentDir(baseDir, it->first)) - ++countRef.second; - } + for (auto& item : dirReadWriteCount) + if (dependentDir(baseDir, item.first)) + ++item.second.second; }; - typedef std::vector<std::pair<Zstring, Zstring>> DirPairList; - DirPairList significantDiff; + std::vector<std::pair<Zstring, Zstring>> significantDiffPairs; - typedef std::vector<std::pair<Zstring, std::pair<Int64, Int64>>> DirSpaceRequAvailList; //dirname / space required / space available - DirSpaceRequAvailList diskSpaceMissing; + std::vector<std::pair<Zstring, std::pair<Int64, Int64>>> diskSpaceMissing; //dirname / space required / space available #ifdef ZEN_WIN //status of base directories which are set to DELETE_TO_RECYCLER (and contain actual items to be deleted) @@ -2285,7 +2150,7 @@ void zen::synchronize(const TimeComp& timeStamp, //check if more than 50% of total number of files/dirs are to be created/overwritten/deleted if (significantDifferenceDetected(folderPairStat)) - significantDiff.push_back(std::make_pair(j->getBaseDirPf<LEFT_SIDE>(), j->getBaseDirPf<RIGHT_SIDE>())); + significantDiffPairs.push_back(std::make_pair(j->getBaseDirPf<LEFT_SIDE>(), j->getBaseDirPf<RIGHT_SIDE>())); //check for sufficient free diskspace auto checkSpace = [&](const Zstring& baseDirPf, const Int64& minSpaceNeeded) @@ -2329,41 +2194,37 @@ void zen::synchronize(const TimeComp& timeStamp, //check if unresolved conflicts exist if (statisticsTotal.getConflict() > 0) { - //show the first few conflicts in warning message also: std::wstring msg = _("The following items have unresolved conflicts and will not be synchronized:"); - const auto& conflictMsgs = statisticsTotal.getConflictMessages(); //get *all* sync conflicts - for (auto it = conflictMsgs.begin(); it != conflictMsgs.end(); ++it) - msg += L"\n\n" + fmtFileName(it->first) + L": " + it->second; + for (const auto& item : statisticsTotal.getConflictMessages()) //show *all* conflicts in warning message + msg += L"\n\n" + fmtFileName(item.first) + L": " + item.second; callback.reportWarning(msg, warnings.warningUnresolvedConflicts); } - //check if user accidentally selected wrong directories for sync - if (!significantDiff.empty()) + if (!significantDiffPairs.empty()) { std::wstring msg = _("The following folders are significantly different. Make sure you are matching the correct folders for synchronization."); - for (auto it = significantDiff.begin(); it != significantDiff.end(); ++it) + for (const auto& item : significantDiffPairs) msg += std::wstring(L"\n\n") + - it->first + L" <-> " + L"\n" + - it->second; + item.first + L" <-> " + L"\n" + + item.second; callback.reportWarning(msg, warnings.warningSignificantDifference); } - //check for sufficient free diskspace if (!diskSpaceMissing.empty()) { std::wstring msg = _("Not enough free disk space available in:"); - for (auto it = diskSpaceMissing.begin(); it != diskSpaceMissing.end(); ++it) + for (const auto& item : diskSpaceMissing) msg += std::wstring(L"\n\n") + - it->first + L"\n" + - _("Required:") + L" " + filesizeToShortString(it->second.first) + L"\n" + - _("Available:") + L" " + filesizeToShortString(it->second.second); + item.first + L"\n" + + _("Required:") + L" " + filesizeToShortString(item.second.first) + L"\n" + + _("Available:") + L" " + filesizeToShortString(item.second.second); callback.reportWarning(msg, warnings.warningNotEnoughDiskSpace); } @@ -2372,9 +2233,9 @@ void zen::synchronize(const TimeComp& timeStamp, //windows: check if recycle bin really exists; if not, Windows will silently delete, which is wrong { std::wstring dirListMissingRecycler; - for (auto it = baseDirHasRecycler.begin(); it != baseDirHasRecycler.end(); ++it) - if (!it->second) - dirListMissingRecycler += std::wstring(L"\n") + it->first; + for (const auto& item : baseDirHasRecycler) + if (!item.second) + dirListMissingRecycler += std::wstring(L"\n") + item.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); @@ -2382,22 +2243,24 @@ void zen::synchronize(const TimeComp& timeStamp, #endif //check if folders are used by multiple pairs in read/write access - std::vector<Zstring> conflictDirs; - for (auto it = dirReadWriteCount.cbegin(); it != dirReadWriteCount.cend(); ++it) { - const std::pair<size_t, size_t>& countRef = it->second; //# read/write accesses + std::vector<Zstring> conflictDirs; + for (const auto& item : dirReadWriteCount) + { + const std::pair<size_t, size_t>& countRef = item.second; //# read/write accesses - if (countRef.first + countRef.second >= 2 && countRef.second >= 1) //race condition := multiple accesses of which at least one is a write - conflictDirs.push_back(it->first); - } + if (countRef.first + countRef.second >= 2 && countRef.second >= 1) //race condition := multiple accesses of which at least one is a write + conflictDirs.push_back(item.first); + } - if (!conflictDirs.empty()) - { - std::wstring msg = _("A folder will be modified which is part of multiple folder pairs. Please review synchronization settings.") + L"\n"; - std::for_each(conflictDirs.begin(), conflictDirs.end(), - [&](const Zstring& dirname) { msg += std::wstring(L"\n") + dirname; }); + if (!conflictDirs.empty()) + { + std::wstring msg = _("A folder will be modified which is part of multiple folder pairs. Please review synchronization settings.") + L"\n"; + for (const Zstring& dirname : conflictDirs) + msg += std::wstring(L"\n") + dirname; - callback.reportWarning(msg, warnings.warningFolderPairRaceCondition); + callback.reportWarning(msg, warnings.warningFolderPairRaceCondition); + } } //-------------------end of basic checks------------------------------------------ @@ -2516,4 +2379,4 @@ void zen::synchronize(const TimeComp& timeStamp, { callback.reportFatalError(utfCvrtTo<std::wstring>(e.what())); } -}
\ No newline at end of file +} diff --git a/FreeFileSync/Source/ui/batch_status_handler.cpp b/FreeFileSync/Source/ui/batch_status_handler.cpp index bd08da73..e9663654 100644 --- a/FreeFileSync/Source/ui/batch_status_handler.cpp +++ b/FreeFileSync/Source/ui/batch_status_handler.cpp @@ -167,7 +167,8 @@ BatchStatusHandler::~BatchStatusHandler() else try { - tryReportingError([&] { shellExecute2(expandMacros(utfCvrtTo<Zstring>(finalCommand)), EXEC_TYPE_SYNC); }, //throw FileError, throw X? + //use EXEC_TYPE_ASYNC until there is reason no to: https://sourceforge.net/p/freefilesync/discussion/help/thread/828dca52 + tryReportingError([&] { shellExecute2(expandMacros(utfCvrtTo<Zstring>(finalCommand)), EXEC_TYPE_ASYNC); }, //throw FileError, throw X? *this); } catch (...) {} diff --git a/FreeFileSync/Source/ui/column_attr.h b/FreeFileSync/Source/ui/column_attr.h index f930f2ef..a5564293 100644 --- a/FreeFileSync/Source/ui/column_attr.h +++ b/FreeFileSync/Source/ui/column_attr.h @@ -55,7 +55,7 @@ std::vector<ColumnAttributeRim> getDefaultColumnAttributesRight() 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, false)); //already shown on left side - attr.push_back(ColumnAttributeRim(COL_TYPE_FILENAME, 200, 0, true)); + attr.push_back(ColumnAttributeRim(COL_TYPE_FILENAME, 200, 0, true)); 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)); diff --git a/FreeFileSync/Source/ui/custom_grid.cpp b/FreeFileSync/Source/ui/custom_grid.cpp index 8ab6e2db..2d551ad6 100644 --- a/FreeFileSync/Source/ui/custom_grid.cpp +++ b/FreeFileSync/Source/ui/custom_grid.cpp @@ -37,8 +37,6 @@ const wxColour COLOR_SYNC_BLUE (185, 188, 255); const wxColour COLOR_SYNC_GREEN (196, 255, 185); const wxColour COLOR_NOT_ACTIVE (228, 228, 228); //light grey - -const Zstring ICON_FILE_FOLDER = Zstr("folder"); const size_t ROW_COUNT_NO_DATA = 10; /* @@ -227,18 +225,18 @@ public: if (isFailedLoad(currentRow)) //find failed attempts to load icon { - const Zstring filename = getIconFile(currentRow); - if (!filename.empty() && filename != ICON_FILE_FOLDER) + const IconInfo ii = getIconInfo(currentRow); + if (!ii.iconPath.empty()) { //test if they are already loaded in buffer: - if (iconMgr_->refIconBuffer().readyForRetrieval(filename)) + if (iconMgr_->refIconBuffer().readyForRetrieval(ii.iconPath)) { //do a *full* refresh for *every* failed load to update partial DC updates while scrolling refreshCell(refGrid(), currentRow, static_cast<ColumnType>(COL_TYPE_FILENAME)); setFailedLoad(currentRow, false); } else //not yet in buffer: mark for async. loading - newLoad.push_back(filename); + newLoad.push_back(ii.iconPath); } } } @@ -260,10 +258,10 @@ public: { const ptrdiff_t currentRow = rowsOnScreen.first - (preloadSize + 1) / 2 + getAlternatingPos(i, visibleRowCount + preloadSize); //for odd preloadSize start one row earlier - const Zstring filename = getIconFile(currentRow); - if (!filename.empty() && filename != ICON_FILE_FOLDER) - if (!iconMgr_->refIconBuffer().readyForRetrieval(filename)) - newLoad.push_back(std::make_pair(i, filename)); //insert least-important items on outer rim first + const IconInfo ii = getIconInfo(currentRow); + if (!ii.iconPath.empty()) + if (!iconMgr_->refIconBuffer().readyForRetrieval(ii.iconPath)) + newLoad.push_back(std::make_pair(i, ii.iconPath)); //insert least-important items on outer rim first } } } @@ -528,37 +526,42 @@ private: //Note: it's not sufficient to start up on failed icon loads only, since we support prefetching of not yet visible rows!!! iconMgr_->startIconUpdater(); - const Zstring filename = getIconFile(row); - if (!filename.empty()) - { - wxBitmap fileIcon; + const IconInfo ii = getIconInfo(row); - //first check if it is a directory icon: - if (filename == ICON_FILE_FOLDER) - fileIcon = iconMgr_->refIconBuffer().genericDirIcon(); - else //retrieve file icon + wxBitmap fileIcon; + if (ii.drawAsFolder) + fileIcon = iconMgr_->refIconBuffer().genericDirIcon(); + else if (!ii.iconPath.empty()) //retrieve file icon + { + if (Opt<wxBitmap> tmpIco = iconMgr_->refIconBuffer().retrieveFileIcon(ii.iconPath)) + fileIcon = *tmpIco; + else { - if (Opt<wxBitmap> tmpIco = iconMgr_->refIconBuffer().retrieveFileIcon(filename)) - fileIcon = *tmpIco; - else - { - fileIcon = iconMgr_->refIconBuffer().genericFileIcon(); //better than nothing - setFailedLoad(row); //save status of failed icon load -> used for async. icon loading - //falsify only! we want to avoid writing incorrect success values when only partially updating the DC, e.g. when scrolling, - //see repaint behavior of ::ScrollWindow() function! - } + fileIcon = iconMgr_->refIconBuffer().genericFileIcon(); //better than nothing + setFailedLoad(row); //save status of failed icon load -> used for async. icon loading + //falsify only! we want to avoid writing incorrect success values when only partially updating the DC, e.g. when scrolling, + //see repaint behavior of ::ScrollWindow() function! } + } + + if (fileIcon.IsOk()) + { + wxRect rectIcon = rectTmp; + rectIcon.width = iconSize; //support small thumbnail centering - if (fileIcon.IsOk()) + auto drawIcon = [&](const wxBitmap& icon) { - wxRect rectIcon = rectTmp; - rectIcon.width = iconSize; //support small thumbnail centering if (isActive) - drawBitmapRtlNoMirror(dc, fileIcon, rectIcon, wxALIGN_CENTER, buffer); + drawBitmapRtlNoMirror(dc, icon, rectIcon, wxALIGN_CENTER, this->buffer); //without "this->" GCC 4.7.2 compiler crash on Debian else - drawBitmapRtlNoMirror(dc, wxBitmap(fileIcon.ConvertToImage().ConvertToGreyscale(1.0 / 3, 1.0 / 3, 1.0 / 3)), //treat all channels equally! - rectIcon, wxALIGN_CENTER, buffer); - } + drawBitmapRtlNoMirror(dc, wxBitmap(icon.ConvertToImage().ConvertToGreyscale(1.0 / 3, 1.0 / 3, 1.0 / 3)), //treat all channels equally! + rectIcon, wxALIGN_CENTER, this->buffer); + }; + + drawIcon(fileIcon); + + if (ii.drawAsLink) + drawIcon(iconMgr_->refIconBuffer().linkOverlayIcon()); } } rectTmp.x += iconSize; @@ -647,32 +650,45 @@ private: } } - Zstring getIconFile(size_t row) const //return ICON_FILE_FOLDER if row points to a folder + struct IconInfo { + Zstring iconPath; //mutually exclusive: either non-empty iconPath, or folder, or neither if no entry at this row + bool drawAsFolder; // + bool drawAsLink; + }; + + IconInfo getIconInfo(size_t row) const //return ICON_FILE_FOLDER if row points to a folder + { + IconInfo out = {}; + const FileSystemObject* fsObj = getRawData(row); if (fsObj && !fsObj->isEmpty<side>()) { struct GetIcon : public FSObjectVisitor { + GetIcon(IconInfo& ii) : ii_(ii) {} + virtual void visit(const FilePair& fileObj) { - iconName = fileObj.getFullName<side>(); + ii_.iconPath = fileObj.getFullName<side>(); + ii_.drawAsLink = fileObj.isFollowedSymlink<side>() || hasLinkExtension(ii_.iconPath); } virtual void visit(const SymlinkPair& linkObj) { - iconName = linkObj.getFullName<side>(); + ii_.iconPath = linkObj.getFullName<side>(); + ii_.drawAsLink = true; } virtual void visit(const DirPair& dirObj) { - iconName = ICON_FILE_FOLDER; + ii_.drawAsFolder = true; + //todo: if ("is followed symlink") ii_.drawAsLink = true; } - Zstring iconName; - } getIcon; + IconInfo& ii_; + } getIcon(out); fsObj->accept(getIcon); - return getIcon.iconName; } - return Zstring(); + return out; } virtual wxString getToolTip(size_t row, ColumnType colType) const override @@ -1036,9 +1052,9 @@ private: case COL_TYPE_CHECKBOX: break; case COL_TYPE_CMP_CATEGORY: - return _("Category") + L" (F9)"; + return _("Category") + L" (F10)"; case COL_TYPE_SYNC_ACTION: - return _("Action") + L" (F9)"; + return _("Action") + L" (F10)"; } return wxEmptyString; } diff --git a/FreeFileSync/Source/ui/grid_view.cpp b/FreeFileSync/Source/ui/grid_view.cpp index e1e16e47..b19bf49d 100644 --- a/FreeFileSync/Source/ui/grid_view.cpp +++ b/FreeFileSync/Source/ui/grid_view.cpp @@ -109,20 +109,21 @@ ptrdiff_t GridView::findRowFirstChild(const HierarchyObject* hierObj) const GridView::StatusCmpResult::StatusCmpResult() : + existsExcluded (false), + existsEqual (false), + existsConflict (false), existsLeftOnly (false), existsRightOnly (false), existsLeftNewer (false), existsRightNewer(false), existsDifferent (false), - existsEqual (false), - existsConflict (false), filesOnLeftView (0), foldersOnLeftView (0), filesOnRightView (0), foldersOnRightView(0) {} -GridView::StatusCmpResult GridView::updateCmpResult(bool hideFiltered, //maps sortedRef to viewRef +GridView::StatusCmpResult GridView::updateCmpResult(bool showExcluded, //maps sortedRef to viewRef bool leftOnlyFilesActive, bool rightOnlyFilesActive, bool leftNewerFilesActive, @@ -135,8 +136,12 @@ GridView::StatusCmpResult GridView::updateCmpResult(bool hideFiltered, //maps so updateView([&](const FileSystemObject& fsObj) -> bool { - if (hideFiltered && !fsObj.isActive()) - return false; + if (!fsObj.isActive()) + { + output.existsExcluded = true; + if (!showExcluded) + return false; + } switch (fsObj.getCategory()) { @@ -180,6 +185,9 @@ GridView::StatusCmpResult GridView::updateCmpResult(bool hideFiltered, //maps so GridView::StatusSyncPreview::StatusSyncPreview() : + existsExcluded (false), + existsEqual (false), + existsConflict (false), existsSyncCreateLeft (false), existsSyncCreateRight(false), existsSyncDeleteLeft (false), @@ -187,15 +195,13 @@ GridView::StatusSyncPreview::StatusSyncPreview() : existsSyncDirLeft (false), existsSyncDirRight (false), existsSyncDirNone (false), - existsSyncEqual (false), - existsConflict (false), filesOnLeftView (0), foldersOnLeftView (0), filesOnRightView (0), foldersOnRightView(0) {} -GridView::StatusSyncPreview GridView::updateSyncPreview(bool hideFiltered, //maps sortedRef to viewRef +GridView::StatusSyncPreview GridView::updateSyncPreview(bool showExcluded, //maps sortedRef to viewRef bool syncCreateLeftActive, bool syncCreateRightActive, bool syncDeleteLeftActive, @@ -210,8 +216,12 @@ GridView::StatusSyncPreview GridView::updateSyncPreview(bool hideFiltered, //map updateView([&](const FileSystemObject& fsObj) -> bool { - if (hideFiltered && !fsObj.isActive()) - return false; + if (!fsObj.isActive()) + { + output.existsExcluded = true; + if (!showExcluded) + return false; + } switch (fsObj.getSyncOperation()) //evaluate comparison result and sync direction { @@ -250,7 +260,7 @@ GridView::StatusSyncPreview GridView::updateSyncPreview(bool hideFiltered, //map if (!syncDirNoneActive) return false; break; case SO_EQUAL: - output.existsSyncEqual = true; + output.existsEqual = true; if (!syncEqualActive) return false; break; case SO_UNRESOLVED_CONFLICT: @@ -532,14 +542,14 @@ void GridView::sortView(ColumnTypeRim type, bool onLeft, bool ascending) else if (!ascending && onLeft) std::stable_sort(sortedRef.begin(), sortedRef.end(), LessExtension<false, LEFT_SIDE >()); else if (!ascending && !onLeft) std::stable_sort(sortedRef.begin(), sortedRef.end(), LessExtension<false, RIGHT_SIDE>()); break; - //case SORT_BY_CMP_RESULT: - // if ( ascending) std::stable_sort(sortedRef.begin(), sortedRef.end(), LessCmpResult<true >()); - // else if (!ascending) std::stable_sort(sortedRef.begin(), sortedRef.end(), LessCmpResult<false>()); - // break; - //case SORT_BY_SYNC_DIRECTION: - // if ( ascending) std::stable_sort(sortedRef.begin(), sortedRef.end(), LessSyncDirection<true >()); - // else if (!ascending) std::stable_sort(sortedRef.begin(), sortedRef.end(), LessSyncDirection<false>()); - // break; + //case SORT_BY_CMP_RESULT: + // if ( ascending) std::stable_sort(sortedRef.begin(), sortedRef.end(), LessCmpResult<true >()); + // else if (!ascending) std::stable_sort(sortedRef.begin(), sortedRef.end(), LessCmpResult<false>()); + // break; + //case SORT_BY_SYNC_DIRECTION: + // if ( ascending) std::stable_sort(sortedRef.begin(), sortedRef.end(), LessSyncDirection<true >()); + // else if (!ascending) std::stable_sort(sortedRef.begin(), sortedRef.end(), LessSyncDirection<false>()); + // break; case COL_TYPE_DIRECTORY: if ( ascending) std::stable_sort(sortedRef.begin(), sortedRef.end(), [](const RefIndex a, const RefIndex b) { return a.folderIndex < b.folderIndex; }); else if (!ascending) std::stable_sort(sortedRef.begin(), sortedRef.end(), [](const RefIndex a, const RefIndex b) { return a.folderIndex > b.folderIndex; }); diff --git a/FreeFileSync/Source/ui/grid_view.h b/FreeFileSync/Source/ui/grid_view.h index c01ac240..bf2a51ea 100644 --- a/FreeFileSync/Source/ui/grid_view.h +++ b/FreeFileSync/Source/ui/grid_view.h @@ -34,13 +34,15 @@ public: { StatusCmpResult(); + bool existsExcluded; + bool existsEqual; + bool existsConflict; + bool existsLeftOnly; bool existsRightOnly; bool existsLeftNewer; bool existsRightNewer; bool existsDifferent; - bool existsEqual; - bool existsConflict; unsigned int filesOnLeftView; unsigned int foldersOnLeftView; @@ -52,7 +54,7 @@ public: }; //comparison results view - StatusCmpResult updateCmpResult(bool hideFiltered, + StatusCmpResult updateCmpResult(bool showExcluded, bool leftOnlyFilesActive, bool rightOnlyFilesActive, bool leftNewerFilesActive, @@ -65,6 +67,10 @@ public: { StatusSyncPreview(); + bool existsExcluded; + bool existsEqual; + bool existsConflict; + bool existsSyncCreateLeft; bool existsSyncCreateRight; bool existsSyncDeleteLeft; @@ -72,8 +78,6 @@ public: bool existsSyncDirLeft; bool existsSyncDirRight; bool existsSyncDirNone; - bool existsSyncEqual; - bool existsConflict; unsigned int filesOnLeftView; unsigned int foldersOnLeftView; @@ -85,7 +89,7 @@ public: }; //synchronization preview - StatusSyncPreview updateSyncPreview(bool hideFiltered, + StatusSyncPreview updateSyncPreview(bool showExcluded, bool syncCreateLeftActive, bool syncCreateRightActive, bool syncDeleteLeftActive, diff --git a/FreeFileSync/Source/ui/gui_generated.cpp b/FreeFileSync/Source/ui/gui_generated.cpp index 91783b83..8ddfc163 100644 --- a/FreeFileSync/Source/ui/gui_generated.cpp +++ b/FreeFileSync/Source/ui/gui_generated.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 8 2012) +// C++ code generated with wxFormBuilder (version Nov 6 2013) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -43,7 +43,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_menuItem10 = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("1. &Compare") ) + wxT('\t') + wxT("F5"), wxEmptyString, wxITEM_NORMAL ); m_menuFile->Append( m_menuItem10 ); - m_menuItem11 = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("2. &Synchronize") ) + wxT('\t') + wxT("F8"), wxEmptyString, wxITEM_NORMAL ); + m_menuItem11 = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("2. &Synchronize") ) + wxT('\t') + wxT("F9"), wxEmptyString, wxITEM_NORMAL ); m_menuFile->Append( m_menuItem11 ); m_menuFile->AppendSeparator(); @@ -129,6 +129,12 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer1721->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL, 5 ); + m_bpButtonFilter = new wxBitmapButton( m_panelTopButtons, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 60,44 ), wxBU_AUTODRAW|wxFULL_REPAINT_ON_RESIZE ); + bSizer1721->Add( m_bpButtonFilter, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT|wxEXPAND, 5 ); + + + bSizer1721->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL, 5 ); + m_bpButtonSyncConfig = new wxBitmapButton( m_panelTopButtons, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 44,44 ), wxBU_AUTODRAW ); m_bpButtonSyncConfig->SetToolTip( _("dummy") ); @@ -547,29 +553,67 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizerConfig->Fit( m_panelConfig ); bSizerPanelHolder->Add( m_panelConfig, 0, 0, 5 ); - m_panelFilter = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - wxBoxSizer* bSizer171; - bSizer171 = new wxBoxSizer( wxHORIZONTAL ); + m_panelViewFilter = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + bSizerViewFilter = new wxBoxSizer( wxHORIZONTAL ); + + m_bpButtonViewTypeSyncAction = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 82,42 ), wxBU_AUTODRAW ); + bSizerViewFilter->Add( m_bpButtonViewTypeSyncAction, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxRIGHT, 5 ); + + m_bpButtonShowExcluded = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); + bSizerViewFilter->Add( m_bpButtonShowExcluded, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + + bSizerViewFilter->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_bpButtonShowCreateLeft = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); + bSizerViewFilter->Add( m_bpButtonShowCreateLeft, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_bpButtonShowUpdateLeft = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); + bSizerViewFilter->Add( m_bpButtonShowUpdateLeft, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_bpButtonShowDeleteLeft = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); + bSizerViewFilter->Add( m_bpButtonShowDeleteLeft, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_bpButtonShowLeftOnly = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); + bSizerViewFilter->Add( m_bpButtonShowLeftOnly, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_bpButtonShowLeftNewer = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); + bSizerViewFilter->Add( m_bpButtonShowLeftNewer, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_bpButtonShowEqual = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); + bSizerViewFilter->Add( m_bpButtonShowEqual, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_bpButtonShowDifferent = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); + bSizerViewFilter->Add( m_bpButtonShowDifferent, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - m_bpButtonFilter = new wxBitmapButton( m_panelFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW|wxFULL_REPAINT_ON_RESIZE ); - bSizer171->Add( m_bpButtonFilter, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + m_bpButtonShowDoNothing = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); + bSizerViewFilter->Add( m_bpButtonShowDoNothing, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_bpButtonShowRightNewer = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); + bSizerViewFilter->Add( m_bpButtonShowRightNewer, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_bpButtonShowRightOnly = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); + bSizerViewFilter->Add( m_bpButtonShowRightOnly, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_bpButtonShowDeleteRight = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); + bSizerViewFilter->Add( m_bpButtonShowDeleteRight, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - m_checkBoxHideExcluded = new wxCheckBox( m_panelFilter, wxID_ANY, _("Hide excluded items"), wxDefaultPosition, wxDefaultSize, 0 ); - m_checkBoxHideExcluded->SetToolTip( _("Show filtered or temporarily excluded files") ); + m_bpButtonShowUpdateRight = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); + bSizerViewFilter->Add( m_bpButtonShowUpdateRight, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - bSizer171->Add( m_checkBoxHideExcluded, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + m_bpButtonShowCreateRight = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); + bSizerViewFilter->Add( m_bpButtonShowCreateRight, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + m_bpButtonShowConflict = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); + bSizerViewFilter->Add( m_bpButtonShowConflict, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - m_panelFilter->SetSizer( bSizer171 ); - m_panelFilter->Layout(); - bSizer171->Fit( m_panelFilter ); - bSizerPanelHolder->Add( m_panelFilter, 0, 0, 5 ); - m_panelStatistics = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - bSizer1801 = new wxBoxSizer( wxHORIZONTAL ); + bSizerViewFilter->Add( 0, 0, 1, wxEXPAND, 5 ); + m_panelStatistics = new wxPanel( m_panelViewFilter, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER|wxTAB_TRAVERSAL ); + m_panelStatistics->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - bSizer1801->Add( 0, 0, 1, wxEXPAND, 5 ); + bSizer1801 = new wxBoxSizer( wxVERTICAL ); bSizerStatistics = new wxBoxSizer( wxHORIZONTAL ); @@ -752,70 +796,13 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizerStatistics->Add( bSizer178, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - bSizer1801->Add( bSizerStatistics, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - - bSizer1801->Add( 0, 0, 1, wxEXPAND, 5 ); + bSizer1801->Add( bSizerStatistics, 0, wxALIGN_CENTER_VERTICAL|wxALL, 4 ); m_panelStatistics->SetSizer( bSizer1801 ); m_panelStatistics->Layout(); bSizer1801->Fit( m_panelStatistics ); - bSizerPanelHolder->Add( m_panelStatistics, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - m_panelViewFilter = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - bSizerViewFilter = new wxBoxSizer( wxHORIZONTAL ); - - m_bpButtonViewTypeSyncAction = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); - bSizerViewFilter->Add( m_bpButtonViewTypeSyncAction, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - - - bSizerViewFilter->Add( 0, 0, 1, wxEXPAND, 5 ); - - m_bpButtonShowCreateLeft = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); - bSizerViewFilter->Add( m_bpButtonShowCreateLeft, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - - m_bpButtonShowUpdateLeft = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); - bSizerViewFilter->Add( m_bpButtonShowUpdateLeft, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - - m_bpButtonShowDeleteLeft = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); - bSizerViewFilter->Add( m_bpButtonShowDeleteLeft, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - - m_bpButtonShowLeftOnly = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); - bSizerViewFilter->Add( m_bpButtonShowLeftOnly, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - - m_bpButtonShowLeftNewer = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); - bSizerViewFilter->Add( m_bpButtonShowLeftNewer, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - - m_bpButtonShowEqual = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); - bSizerViewFilter->Add( m_bpButtonShowEqual, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - - m_bpButtonShowDifferent = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); - bSizerViewFilter->Add( m_bpButtonShowDifferent, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - - m_bpButtonShowDoNothing = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); - bSizerViewFilter->Add( m_bpButtonShowDoNothing, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - - m_bpButtonShowRightNewer = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); - bSizerViewFilter->Add( m_bpButtonShowRightNewer, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - - m_bpButtonShowRightOnly = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); - bSizerViewFilter->Add( m_bpButtonShowRightOnly, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - - m_bpButtonShowDeleteRight = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); - bSizerViewFilter->Add( m_bpButtonShowDeleteRight, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - - m_bpButtonShowUpdateRight = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); - bSizerViewFilter->Add( m_bpButtonShowUpdateRight, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - - m_bpButtonShowCreateRight = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); - bSizerViewFilter->Add( m_bpButtonShowCreateRight, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - - m_bpButtonShowConflict = new ToggleButton( m_panelViewFilter, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); - bSizerViewFilter->Add( m_bpButtonShowConflict, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); - - - bSizerViewFilter->Add( 0, 0, 1, wxEXPAND, 5 ); + bSizerViewFilter->Add( m_panelStatistics, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); m_panelViewFilter->SetSizer( bSizerViewFilter ); @@ -847,6 +834,8 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_buttonCompare->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnCompare ), NULL, this ); m_bpButtonCmpConfig->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnCmpSettings ), NULL, this ); m_bpButtonCmpConfig->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( MainDialogGenerated::OnCompSettingsContext ), NULL, this ); + m_bpButtonFilter->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnConfigureFilter ), NULL, this ); + m_bpButtonFilter->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( MainDialogGenerated::OnGlobalFilterContext ), NULL, this ); m_bpButtonSyncConfig->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncSettings ), NULL, this ); m_bpButtonSyncConfig->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( MainDialogGenerated::OnSyncSettingsContext ), NULL, this ); m_buttonSync->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnStartSync ), NULL, this ); @@ -862,10 +851,9 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_listBoxHistory->Connect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnLoadFromHistory ), NULL, this ); m_listBoxHistory->Connect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler( MainDialogGenerated::OnLoadFromHistoryDoubleClick ), NULL, this ); m_listBoxHistory->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( MainDialogGenerated::OnCfgHistoryRightClick ), NULL, this ); - m_bpButtonFilter->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnConfigureFilter ), NULL, this ); - m_bpButtonFilter->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( MainDialogGenerated::OnGlobalFilterContext ), NULL, this ); - m_checkBoxHideExcluded->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnShowExcluded ), NULL, this ); m_bpButtonViewTypeSyncAction->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnToggleViewType ), NULL, this ); + m_bpButtonShowExcluded->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnToggleViewButton ), NULL, this ); + m_bpButtonShowExcluded->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( MainDialogGenerated::OnViewButtonRightClick ), NULL, this ); m_bpButtonShowCreateLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnToggleViewButton ), NULL, this ); m_bpButtonShowCreateLeft->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( MainDialogGenerated::OnViewButtonRightClick ), NULL, this ); m_bpButtonShowUpdateLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnToggleViewButton ), NULL, this ); @@ -1090,7 +1078,7 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const fgSizer1->Add( bSizer172, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - m_staticTextMirror = new wxStaticText( m_panel37, wxID_ANY, _("Create a mirror backup of the left folder which exactly matches the right folder after synchronization."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextMirror = new wxStaticText( m_panel37, wxID_ANY, _("Create a mirror backup of the left folder by adapting the right folder to match."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextMirror->Wrap( 480 ); fgSizer1->Add( m_staticTextMirror, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -1147,7 +1135,7 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const 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.") ); + m_checkBoxDetectMove->SetToolTip( _("- Requires and creates database files\n- Detection active after initial sync\n- Not supported by all file systems") ); bSizer1751->Add( m_checkBoxDetectMove, 1, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 5 ); @@ -1546,13 +1534,16 @@ SyncConfirmationDlgGenerated::SyncConfirmationDlgGenerated( wxWindow* parent, wx m_staticline371 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); bSizer134->Add( m_staticline371, 0, wxEXPAND, 5 ); - m_panelStatistics = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_panelStatistics = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); m_panelStatistics->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); wxBoxSizer* bSizer185; bSizer185 = new wxBoxSizer( wxHORIZONTAL ); + bSizer185->Add( 40, 0, 0, 0, 5 ); + + bSizer185->Add( 0, 0, 1, 0, 5 ); m_staticline38 = new wxStaticLine( m_panelStatistics, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ); @@ -1684,6 +1675,15 @@ SyncConfirmationDlgGenerated::SyncConfirmationDlgGenerated( wxWindow* parent, wx bSizer185->Add( bSizer162, 0, 0, 5 ); + m_staticline381 = new wxStaticLine( m_panelStatistics, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ); + bSizer185->Add( m_staticline381, 0, wxEXPAND, 5 ); + + + bSizer185->Add( 0, 0, 1, 0, 5 ); + + + bSizer185->Add( 40, 0, 0, 0, 5 ); + m_panelStatistics->SetSizer( bSizer185 ); m_panelStatistics->Layout(); diff --git a/FreeFileSync/Source/ui/gui_generated.h b/FreeFileSync/Source/ui/gui_generated.h index e87529b1..1135b594 100644 --- a/FreeFileSync/Source/ui/gui_generated.h +++ b/FreeFileSync/Source/ui/gui_generated.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 8 2012) +// C++ code generated with wxFormBuilder (version Nov 6 2013) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -89,6 +89,7 @@ class MainDialogGenerated : public wxFrame zen::BitmapTextButton* m_buttonCompare; zen::BitmapTextButton* m_buttonCancel; wxBitmapButton* m_bpButtonCmpConfig; + wxBitmapButton* m_bpButtonFilter; wxBitmapButton* m_bpButtonSyncConfig; zen::BitmapTextButton* m_buttonSync; wxPanel* m_panelDirectoryPairs; @@ -140,28 +141,10 @@ class MainDialogGenerated : public wxFrame wxBitmapButton* m_bpButtonSave; wxBitmapButton* m_bpButtonBatchJob; wxListBox* m_listBoxHistory; - wxPanel* m_panelFilter; - wxBitmapButton* m_bpButtonFilter; - wxCheckBox* m_checkBoxHideExcluded; - wxPanel* m_panelStatistics; - wxBoxSizer* bSizer1801; - wxStaticBitmap* m_bitmapCreateLeft; - wxStaticText* m_staticTextCreateLeft; - wxStaticBitmap* m_bitmapUpdateLeft; - wxStaticText* m_staticTextUpdateLeft; - wxStaticBitmap* m_bitmapDeleteLeft; - wxStaticText* m_staticTextDeleteLeft; - wxStaticBitmap* m_bitmapData; - wxStaticText* m_staticTextData; - wxStaticBitmap* m_bitmapDeleteRight; - wxStaticText* m_staticTextDeleteRight; - wxStaticBitmap* m_bitmapUpdateRight; - wxStaticText* m_staticTextUpdateRight; - wxStaticBitmap* m_bitmapCreateRight; - wxStaticText* m_staticTextCreateRight; wxPanel* m_panelViewFilter; wxBoxSizer* bSizerViewFilter; ToggleButton* m_bpButtonViewTypeSyncAction; + ToggleButton* m_bpButtonShowExcluded; ToggleButton* m_bpButtonShowCreateLeft; ToggleButton* m_bpButtonShowUpdateLeft; ToggleButton* m_bpButtonShowDeleteLeft; @@ -176,6 +159,22 @@ class MainDialogGenerated : public wxFrame ToggleButton* m_bpButtonShowUpdateRight; ToggleButton* m_bpButtonShowCreateRight; ToggleButton* m_bpButtonShowConflict; + wxPanel* m_panelStatistics; + wxBoxSizer* bSizer1801; + wxStaticBitmap* m_bitmapCreateLeft; + wxStaticText* m_staticTextCreateLeft; + wxStaticBitmap* m_bitmapUpdateLeft; + wxStaticText* m_staticTextUpdateLeft; + wxStaticBitmap* m_bitmapDeleteLeft; + wxStaticText* m_staticTextDeleteLeft; + wxStaticBitmap* m_bitmapData; + wxStaticText* m_staticTextData; + wxStaticBitmap* m_bitmapDeleteRight; + wxStaticText* m_staticTextDeleteRight; + wxStaticBitmap* m_bitmapUpdateRight; + wxStaticText* m_staticTextUpdateRight; + wxStaticBitmap* m_bitmapCreateRight; + wxStaticText* m_staticTextCreateRight; // Virtual event handlers, overide them in your derived class virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } @@ -196,6 +195,8 @@ class MainDialogGenerated : public wxFrame virtual void OnMenuAbout( wxCommandEvent& event ) { event.Skip(); } virtual void OnCmpSettings( wxCommandEvent& event ) { event.Skip(); } virtual void OnCompSettingsContext( wxMouseEvent& event ) { event.Skip(); } + virtual void OnConfigureFilter( wxCommandEvent& event ) { event.Skip(); } + virtual void OnGlobalFilterContext( wxMouseEvent& event ) { event.Skip(); } virtual void OnSyncSettings( wxCommandEvent& event ) { event.Skip(); } virtual void OnSyncSettingsContext( wxMouseEvent& event ) { event.Skip(); } virtual void OnAddFolderPair( wxCommandEvent& event ) { event.Skip(); } @@ -207,9 +208,6 @@ class MainDialogGenerated : public wxFrame virtual void OnLoadFromHistory( wxCommandEvent& event ) { event.Skip(); } virtual void OnLoadFromHistoryDoubleClick( wxCommandEvent& event ) { event.Skip(); } virtual void OnCfgHistoryRightClick( wxMouseEvent& event ) { event.Skip(); } - virtual void OnConfigureFilter( wxCommandEvent& event ) { event.Skip(); } - virtual void OnGlobalFilterContext( wxMouseEvent& event ) { event.Skip(); } - virtual void OnShowExcluded( wxCommandEvent& event ) { event.Skip(); } virtual void OnToggleViewType( wxCommandEvent& event ) { event.Skip(); } virtual void OnToggleViewButton( wxCommandEvent& event ) { event.Skip(); } virtual void OnViewButtonRightClick( wxMouseEvent& event ) { event.Skip(); } @@ -414,6 +412,7 @@ class SyncConfirmationDlgGenerated : public wxDialog wxStaticText* m_staticTextDeleteRight; wxStaticText* m_staticTextUpdateRight; wxStaticText* m_staticTextCreateRight; + wxStaticLine* m_staticline381; wxStaticLine* m_staticline12; wxCheckBox* m_checkBoxDontShowAgain; wxBoxSizer* bSizerStdButtons; diff --git a/FreeFileSync/Source/ui/gui_status_handler.cpp b/FreeFileSync/Source/ui/gui_status_handler.cpp index ec856beb..0db000c4 100644 --- a/FreeFileSync/Source/ui/gui_status_handler.cpp +++ b/FreeFileSync/Source/ui/gui_status_handler.cpp @@ -214,7 +214,8 @@ SyncStatusHandler::~SyncStatusHandler() else try { - tryReportingError([&] { shellExecute2(expandMacros(utfCvrtTo<Zstring>(finalCommand)), EXEC_TYPE_SYNC); }, //throw FileError, throw X? + //use EXEC_TYPE_ASYNC until there is reason no to: https://sourceforge.net/p/freefilesync/discussion/help/thread/828dca52 + tryReportingError([&] { shellExecute2(expandMacros(utfCvrtTo<Zstring>(finalCommand)), EXEC_TYPE_ASYNC); }, //throw FileError, throw X? *this); } catch (...) {} diff --git a/FreeFileSync/Source/ui/main_dlg.cpp b/FreeFileSync/Source/ui/main_dlg.cpp index 2e78152e..9d7aa4c2 100644 --- a/FreeFileSync/Source/ui/main_dlg.cpp +++ b/FreeFileSync/Source/ui/main_dlg.cpp @@ -481,9 +481,7 @@ MainDialog::MainDialog(const xmlAccess::XmlGuiConfig& guiCfg, bSizerPanelHolder->Detach(m_gridNavi); bSizerPanelHolder->Detach(m_panelCenter); bSizerPanelHolder->Detach(m_panelConfig); - bSizerPanelHolder->Detach(m_panelFilter); bSizerPanelHolder->Detach(m_panelViewFilter); - bSizerPanelHolder->Detach(m_panelStatistics); auiMgr.SetManagedWindow(this); auiMgr.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_LIVE_RESIZE); @@ -492,39 +490,33 @@ MainDialog::MainDialog(const xmlAccess::XmlGuiConfig& guiCfg, //caption required for all panes that can be manipulated by the users => used by context menu auiMgr.AddPane(m_panelCenter, - wxAuiPaneInfo().Name(L"Panel3").CenterPane().PaneBorder(false)); + wxAuiPaneInfo().Name(L"PanelCenter").CenterPane().PaneBorder(false)); auiMgr.AddPane(m_panelDirectoryPairs, - wxAuiPaneInfo().Name(L"Panel2").Layer(2).Top().Caption(_("Folder Pairs")).CaptionVisible(false).PaneBorder(false).Gripper()); + wxAuiPaneInfo().Name(L"PanelFolders").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()); + wxAuiPaneInfo().Name(L"PanelFind").Layer(2).Bottom().Row(2).Caption(_("Find")).CaptionVisible(false).PaneBorder(false).Gripper().MinSize(200, m_bpButtonHideSearch->GetSize().GetHeight()).Hide()); + + auiMgr.AddPane(m_panelViewFilter, + wxAuiPaneInfo().Name(L"PanelView").Layer(2).Bottom().Row(1).Caption(_("Select View")).CaptionVisible(false).PaneBorder(false).Gripper().MinSize(m_bpButtonViewTypeSyncAction->GetSize().GetWidth(), m_panelViewFilter->GetSize().GetHeight())); 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 + wxAuiPaneInfo().Name(L"PanelOverview").Layer(3).Left().Position(1).Caption(_("Overview")).MinSize(300, m_gridNavi->GetSize().GetHeight())); //MinSize(): just default size, see comment below auiMgr.AddPane(m_panelConfig, - wxAuiPaneInfo().Name(L"Panel4").Layer(3).Left().Position(2).Caption(_("Configuration")).MinSize(m_listBoxHistory->GetSize().GetWidth(), m_panelConfig->GetSize().GetHeight())); + wxAuiPaneInfo().Name(L"PanelConfig").Layer(3).Left().Position(2).Caption(_("Configuration")).MinSize(m_listBoxHistory->GetSize().GetWidth(), m_panelConfig->GetSize().GetHeight())); //set comparison button label tentatively for m_panelTopButtons to receive final height: updateTopButton(*m_buttonCompare, getResourceImage(L"compare"), L"Dummy", false); m_panelTopButtons->GetSizer()->SetSizeHints(m_panelTopButtons); //~=Fit() + SetMinSize() auiMgr.AddPane(m_panelTopButtons, - wxAuiPaneInfo().Name(L"Panel1").Layer(4).Top().Row(1).Caption(_("Main Bar")).CaptionVisible(false).PaneBorder(false).Gripper().MinSize(-1, m_panelTopButtons->GetSize().GetHeight())); + wxAuiPaneInfo().Name(L"PanelTop").Layer(4).Top().Row(1).Caption(_("Main Bar")).CaptionVisible(false).PaneBorder(false).Gripper().MinSize(-1, m_panelTopButtons->GetSize().GetHeight())); //note: min height is calculated incorrectly by wxAuiManager if panes with and without caption are in the same row => use smaller min-size auiMgr.AddPane(compareStatus->getAsWindow(), - wxAuiPaneInfo().Name(L"Panel9").Layer(4).Top().Row(2).CaptionVisible(false).PaneBorder(false).Hide()); - - auiMgr.AddPane(m_panelFilter, - wxAuiPaneInfo().Name(L"Panel5").Layer(4).Bottom().Position(1).Caption(_("Filter Files")).MinSize(m_bpButtonFilter->GetSize().GetWidth(), m_panelFilter->GetSize().GetHeight())); - - auiMgr.AddPane(m_panelViewFilter, - wxAuiPaneInfo().Name(L"Panel6").Layer(4).Bottom().Position(2).Caption(_("Select View")).MinSize(m_bpButtonShowDoNothing->GetSize().GetWidth(), m_panelViewFilter->GetSize().GetHeight())); - - auiMgr.AddPane(m_panelStatistics, - wxAuiPaneInfo().Name(L"Panel7").Layer(4).Bottom().Position(3).Caption(_("Statistics")).MinSize(m_bitmapData->GetSize().GetWidth() + m_staticTextData->GetSize().GetWidth(), m_panelStatistics->GetSize().GetHeight())); + wxAuiPaneInfo().Name(L"PanelProgress").Layer(4).Top().Row(2).CaptionVisible(false).PaneBorder(false).Hide()); auiMgr.Update(); @@ -548,9 +540,7 @@ MainDialog::MainDialog(const xmlAccess::XmlGuiConfig& guiCfg, //register view layout context menu m_panelTopButtons->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSetLayout), nullptr, this); m_panelConfig ->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSetLayout), nullptr, this); - m_panelFilter ->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSetLayout), nullptr, this); m_panelViewFilter->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSetLayout), nullptr, this); - m_panelStatistics->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSetLayout), nullptr, this); m_panelStatusBar ->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainDialog::OnContextSetLayout), nullptr, this); //---------------------------------------------------------------------------------- @@ -582,8 +572,8 @@ MainDialog::MainDialog(const xmlAccess::XmlGuiConfig& guiCfg, m_bpButtonSave ->SetToolTip(_("Save") + L" (Ctrl+S)"); 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)"); + m_bpButtonSyncConfig->SetToolTip(_("Synchronization settings") + L" (F8)"); + m_buttonSync ->SetToolTip(_("Start synchronization") + L" (F9)"); gridDataView = std::make_shared<GridView>(); treeDataView = std::make_shared<TreeView>(); @@ -701,11 +691,9 @@ MainDialog::MainDialog(const xmlAccess::XmlGuiConfig& guiCfg, //dynamically change sizer direction depending on size m_panelConfig ->Connect(wxEVT_SIZE, wxEventHandler(MainDialog::OnResizeConfigPanel), nullptr, this); m_panelViewFilter->Connect(wxEVT_SIZE, wxEventHandler(MainDialog::OnResizeViewPanel), nullptr, this); - m_panelStatistics->Connect(wxEVT_SIZE, wxEventHandler(MainDialog::OnResizeStatisticsPanel), nullptr, this); wxSizeEvent dummy3; OnResizeConfigPanel (dummy3); //call once on window creation OnResizeViewPanel (dummy3); // - OnResizeStatisticsPanel(dummy3); // //event handler for manual (un-)checking of rows and setting of sync direction m_gridMainC->Connect(EVENT_GRID_CHECK_ROWS, CheckRowsEventHandler (MainDialog::onCheckRows), nullptr, this); @@ -902,8 +890,8 @@ void MainDialog::setGlobalCfgOnInit(const xmlAccess::XmlGlobalSettings& globalSe auiMgr.LoadPerspective(globalSettings.gui.guiPerspectiveLast); //restore original captions - for (auto it = captionNameMap.begin(); it != captionNameMap.end(); ++it) - auiMgr.GetPane(it->second).Caption(it->first); + for (const auto& item : captionNameMap) + auiMgr.GetPane(item.second).Caption(item.first); //if MainDialog::onQueryEndSession() is called while comparison is active, this panel is saved and restored as "visible" auiMgr.GetPane(compareStatus->getAsWindow()).Hide(); @@ -986,13 +974,11 @@ void MainDialog::setSyncDirManually(const std::vector<FileSystemObject*>& select { if (!selection.empty()) { - std::for_each(selection.begin(), selection.end(), - [&](FileSystemObject* fsObj) + for (FileSystemObject* fsObj : selection) { setSyncDirectionRec(direction, *fsObj); //set new direction (recursively) zen::setActiveStatus(true, *fsObj); //works recursively for directories - }); - + } updateGui(); } } @@ -1001,21 +987,21 @@ void MainDialog::setSyncDirManually(const std::vector<FileSystemObject*>& select void MainDialog::setFilterManually(const std::vector<FileSystemObject*>& selection, bool setIncluded) { //if hidefiltered is active, there should be no filtered elements on screen => current element was filtered out - assert(!currentCfg.hideExcludedItems || !setIncluded); + assert(m_bpButtonShowExcluded->isActive() || !setIncluded); if (!selection.empty()) { - std::for_each(selection.begin(), selection.end(), - [&](FileSystemObject* fsObj) { zen::setActiveStatus(setIncluded, *fsObj); }); //works recursively for directories + for (FileSystemObject* fsObj : selection) + zen::setActiveStatus(setIncluded, *fsObj); //works recursively for directories - updateGuiDelayedIf(currentCfg.hideExcludedItems); //show update GUI before removing rows + updateGuiDelayedIf(!m_bpButtonShowExcluded->isActive()); //show update GUI before removing rows } } namespace { -//perf: wxString doesn't model exponential growth and so is unusable for large data sets +//perf: wxString doesn't model exponential growth and is unsuitable for large data sets typedef Zbase<wchar_t> zxString; //guaranteed exponential growth } @@ -1032,10 +1018,7 @@ void MainDialog::copySelectionToClipboard(const std::vector<const Grid*>& gridRe std::vector<Grid::ColumnAttribute> colAttr = grid.getColumnConfig(); vector_remove_if(colAttr, [](const Grid::ColumnAttribute& ca) { return !ca.visible_; }); if (!colAttr.empty()) - { - const std::vector<size_t> selection = grid.getSelectedRows(); - std::for_each(selection.begin(), selection.end(), - [&](size_t row) + for (size_t row : grid.getSelectedRows()) { std::for_each(colAttr.begin(), colAttr.end() - 1, [&](const Grid::ColumnAttribute& ca) @@ -1045,8 +1028,7 @@ void MainDialog::copySelectionToClipboard(const std::vector<const Grid*>& gridRe }); clipboardString += copyStringTo<zxString>(prov->getValue(row, colAttr.back().type_)); clipboardString += L'\n'; - }); - } + } } }; @@ -1092,10 +1074,7 @@ std::vector<FileSystemObject*> MainDialog::getTreeSelection() const { std::vector<FileSystemObject*> output; - const std::vector<size_t>& sel = m_gridNavi->getSelectedRows(); - std::for_each(sel.begin(), sel.end(), - [&](size_t row) - { + for (size_t row : m_gridNavi->getSelectedRows()) if (std::unique_ptr<TreeView::Node> node = treeDataView->getLine(row)) { if (auto root = dynamic_cast<const TreeView::RootNode*>(node.get())) @@ -1109,8 +1088,8 @@ std::vector<FileSystemObject*> MainDialog::getTreeSelection() const output.push_back(&(dir->dirObj_)); else if (auto file = dynamic_cast<const TreeView::FilesNode*>(node.get())) output.insert(output.end(), file->filesAndLinks_.begin(), file->filesAndLinks_.end()); + else assert(false); } - }); return output; } @@ -1445,7 +1424,7 @@ void MainDialog::setStatusBarFileStatistics(size_t filesOnLeftView, wxString statusMiddleNew; if (gridDataView->rowsTotal() > 0) { - statusMiddleNew = _P("%y of 1 row in view", "%y of %x rows in view", gridDataView->rowsTotal()); + statusMiddleNew = _P("Showing %y of 1 row", "Showing %y of %x rows", gridDataView->rowsTotal()); replace(statusMiddleNew, L"%y", toGuiString(gridDataView->rowsOnView()), false); //%x is already used as plural form placeholder! } @@ -1540,9 +1519,7 @@ void MainDialog::disableAllElements(bool enableAbort) m_panelDirectoryPairs->Disable(); m_splitterMain ->Disable(); //includes m_panelCenter, but not m_panelStatusBar! m_panelViewFilter ->Disable(); - m_panelFilter ->Disable(); m_panelConfig ->Disable(); - m_panelStatistics ->Disable(); m_gridNavi ->Disable(); if (enableAbort) @@ -1576,9 +1553,7 @@ void MainDialog::enableAllElements() m_panelDirectoryPairs->Enable(); m_splitterMain ->Enable(); m_panelViewFilter ->Enable(); - m_panelFilter ->Enable(); m_panelConfig ->Enable(); - m_panelStatistics ->Enable(); m_gridNavi ->Enable(); //show compare button @@ -1618,21 +1593,10 @@ void MainDialog::OnResizeConfigPanel(wxEvent& event) void MainDialog::OnResizeViewPanel(wxEvent& event) { - updateSizerOrientation(*bSizerViewFilter, *m_panelViewFilter, 1.0); - event.Skip(); -} - - -void MainDialog::OnResizeStatisticsPanel(wxEvent& event) -{ - //updateSizerOrientation(*bSizerStatistics, *m_panelStatistics); - - //we need something more fancy: - const int parentOrient = m_panelStatistics->GetSize().GetWidth() > m_panelStatistics->GetSize().GetHeight() ? wxHORIZONTAL : wxVERTICAL; //check window NOT sizer width! - if (bSizerStatistics->GetOrientation() != parentOrient) + //we need something more fancy for the statistics: + const int parentOrient = m_panelViewFilter->GetSize().GetWidth() > m_panelViewFilter->GetSize().GetHeight() ? wxHORIZONTAL : wxVERTICAL; //check window NOT sizer width! + if (bSizerViewFilter->GetOrientation() != parentOrient) { - bSizerStatistics->SetOrientation(parentOrient); - //apply opposite orientation for child sizers const int childOrient = parentOrient == wxHORIZONTAL ? wxVERTICAL : wxHORIZONTAL; wxSizerItemList& sl = bSizerStatistics->GetChildren(); @@ -1643,6 +1607,10 @@ void MainDialog::OnResizeStatisticsPanel(wxEvent& event) if (sizerChild->GetOrientation() != childOrient) sizerChild->SetOrientation(childOrient); } + + bSizerStatistics->SetOrientation(parentOrient); + bSizerViewFilter->SetOrientation(parentOrient); + m_panelViewFilter->Layout(); m_panelStatistics->Layout(); } @@ -1885,23 +1853,23 @@ void MainDialog::OnGlobalKeyEvent(wxKeyEvent& event) //process key events withou case WXK_F7: { wxCommandEvent dummy2(wxEVT_COMMAND_BUTTON_CLICKED); //simulate button click - if (wxEvtHandler* evtHandler = m_bpButtonSyncConfig->GetEventHandler()) + if (wxEvtHandler* evtHandler = m_bpButtonFilter->GetEventHandler()) evtHandler->ProcessEvent(dummy2); //synchronous call } return; //-> swallow event! - case WXK_F9: - setViewTypeSyncAction(!m_bpButtonViewTypeSyncAction->isActive()); - return; //-> swallow event! - - case WXK_F10: + case WXK_F8: { wxCommandEvent dummy2(wxEVT_COMMAND_BUTTON_CLICKED); //simulate button click - if (wxEvtHandler* evtHandler = m_bpButtonFilter->GetEventHandler()) + if (wxEvtHandler* evtHandler = m_bpButtonSyncConfig->GetEventHandler()) evtHandler->ProcessEvent(dummy2); //synchronous call } return; //-> swallow event! + case WXK_F10: + setViewTypeSyncAction(!m_bpButtonViewTypeSyncAction->isActive()); + return; //-> swallow event! + //redirect certain (unhandled) keys directly to grid! case WXK_UP: case WXK_DOWN: @@ -2104,22 +2072,25 @@ void MainDialog::onMainGridContextC(GridClickEvent& event) menu.addItem(_("Exclude all"), [&] { zen::setActiveStatus(false, folderCmp); - updateGuiDelayedIf(currentCfg.hideExcludedItems); //show update GUI before removing rows + updateGuiDelayedIf(!m_bpButtonShowExcluded->isActive()); //show update GUI before removing rows }, nullptr, gridDataView->rowsTotal() > 0); menu.popup(*this); } + void MainDialog::onMainGridContextL(GridClickEvent& event) { onMainGridContextRim(true); } + void MainDialog::onMainGridContextR(GridClickEvent& event) { onMainGridContextRim(false); } + void MainDialog::onMainGridContextRim(bool leftSide) { const auto& selection = getGridSelection(); //referenced by lambdas! @@ -2333,11 +2304,9 @@ void MainDialog::onGridLabelContextC(GridClickEvent& event) ContextMenu menu; const bool actionView = m_bpButtonViewTypeSyncAction->isActive(); - menu.addRadio(_("Category") + (actionView ? L"\tF9" : L""), [&] { setViewTypeSyncAction(false); }, !actionView); - menu.addRadio(_("Action") + (!actionView ? L"\tF9" : L""), [&] { setViewTypeSyncAction(true ); }, actionView); + menu.addRadio(_("Category") + (actionView ? L"\tF10" : L""), [&] { setViewTypeSyncAction(false); }, !actionView); + menu.addRadio(_("Action") + (!actionView ? L"\tF10" : L""), [&] { setViewTypeSyncAction(true ); }, actionView); - //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); } @@ -2413,7 +2382,7 @@ void MainDialog::onGridLabelContext(Grid& grid, ColumnTypeRim type, const std::v if (showSelectTimespanDlg(this, manualTimeSpanFrom, manualTimeSpanTo) == ReturnSmallDlg::BUTTON_OKAY) { applyTimeSpanFilter(folderCmp, manualTimeSpanFrom, manualTimeSpanTo); //overwrite current active/inactive settings - //updateGuiDelayedIf(currentCfg.hideExcludedItems); //show update GUI before removing rows + //updateGuiDelayedIf(!m_bpButtonShowExcluded->isActive()); //show update GUI before removing rows updateGui(); } }; @@ -3172,8 +3141,6 @@ void MainDialog::setConfig(const xmlAccess::XmlGuiConfig& newGuiCfg, const std:: setAddFolderPairs(currentCfg.mainCfg.additionalPairs); //read GUI layout - m_checkBoxHideExcluded->SetValue(currentCfg.hideExcludedItems); - setViewTypeSyncAction(currentCfg.highlightSyncAction); clearGrid(); //+ update GUI! @@ -3243,17 +3210,6 @@ void MainDialog::updateGuiDelayedIf(bool condition) } -void MainDialog::OnShowExcluded(wxCommandEvent& event) -{ - //toggle showing filtered rows - currentCfg.hideExcludedItems = !currentCfg.hideExcludedItems; - //make sure, checkbox and value are in sync - m_checkBoxHideExcluded->SetValue(currentCfg.hideExcludedItems); - - updateGui(); -} - - void MainDialog::OnConfigureFilter(wxCommandEvent& event) { if (showFilterDialog(this, currentCfg.mainCfg.globalFilter, _("Filter")) == ReturnSmallDlg::BUTTON_OKAY) @@ -3356,6 +3312,8 @@ void MainDialog::initViewFilterButtons() initButton(*m_bpButtonShowUpdateLeft, "so_update_left", _("Show files that will be overwritten on left side")); initButton(*m_bpButtonShowUpdateRight, "so_update_right", _("Show files that will be overwritten on right side")); initButton(*m_bpButtonShowDoNothing, "so_none", _("Show files that won't be copied")); + + initButton(*m_bpButtonShowExcluded, "checkboxFalse", _("Show filtered or temporarily excluded files")); } @@ -3364,13 +3322,15 @@ void MainDialog::setViewFilterDefault() auto setButton = [](ToggleButton* tb, bool value) { tb->setActive(value); }; const auto& def = globalCfg.gui.viewFilterDefault; + setButton(m_bpButtonShowExcluded, def.excluded); + setButton(m_bpButtonShowEqual, def.equal); + setButton(m_bpButtonShowConflict, def.conflict); + setButton(m_bpButtonShowLeftOnly, def.leftOnly); setButton(m_bpButtonShowRightOnly, def.rightOnly); setButton(m_bpButtonShowLeftNewer, def.leftNewer); setButton(m_bpButtonShowRightNewer, def.rightNewer); - setButton(m_bpButtonShowEqual, def.equal); setButton(m_bpButtonShowDifferent, def.different); - setButton(m_bpButtonShowConflict, def.conflict); setButton(m_bpButtonShowCreateLeft, def.createLeft); setButton(m_bpButtonShowCreateRight,def.createRight); @@ -3390,16 +3350,18 @@ void MainDialog::OnViewButtonRightClick(wxMouseEvent& event) defaultValue = tb->isActive(); }; - auto setDefault = [&] + auto saveDefault = [&] { auto& def = globalCfg.gui.viewFilterDefault; + setButtonDefault(m_bpButtonShowExcluded, def.excluded); + setButtonDefault(m_bpButtonShowEqual, def.equal); + setButtonDefault(m_bpButtonShowConflict, def.conflict); + setButtonDefault(m_bpButtonShowLeftOnly, def.leftOnly); setButtonDefault(m_bpButtonShowRightOnly, def.rightOnly); setButtonDefault(m_bpButtonShowLeftNewer, def.leftNewer); setButtonDefault(m_bpButtonShowRightNewer, def.rightNewer); - setButtonDefault(m_bpButtonShowEqual, def.equal); setButtonDefault(m_bpButtonShowDifferent, def.different); - setButtonDefault(m_bpButtonShowConflict, def.conflict); setButtonDefault(m_bpButtonShowCreateLeft, def.createLeft); setButtonDefault(m_bpButtonShowCreateRight, def.createRight); @@ -3411,7 +3373,7 @@ void MainDialog::OnViewButtonRightClick(wxMouseEvent& event) }; ContextMenu menu; - menu.addItem( _("Set as default"), setDefault); + menu.addItem( _("Set as default"), saveDefault); menu.popup(*this); } @@ -3422,12 +3384,12 @@ void MainDialog::updateGlobalFilterButton() if (!isNullFilter(currentCfg.mainCfg.globalFilter)) { setImage(*m_bpButtonFilter, getResourceImage(L"filter")); - m_bpButtonFilter->SetToolTip(_("Filter") + L" (F10) (" + _("Active") + L")"); + m_bpButtonFilter->SetToolTip(_("Filter") + L" (F7) (" + _("Active") + L")"); } else { setImage(*m_bpButtonFilter, greyScale(getResourceImage(L"filter"))); - m_bpButtonFilter->SetToolTip(_("Filter") + L" (F10) (" + _("None") + L")"); + m_bpButtonFilter->SetToolTip(_("Filter") + L" (F7) (" + _("None") + L")"); } } @@ -3729,11 +3691,14 @@ void MainDialog::onGridDoubleClickL(GridClickEvent& event) { onGridDoubleClickRim(event.row_, true); } + + void MainDialog::onGridDoubleClickR(GridClickEvent& event) { onGridDoubleClickRim(event.row_, false); } + void MainDialog::onGridDoubleClickRim(size_t row, bool leftSide) { if (!globalCfg.gui.externelApplications.empty()) @@ -3768,6 +3733,8 @@ void MainDialog::onGridLabelLeftClickL(GridClickEvent& event) { onGridLabelLeftClick(true, static_cast<ColumnTypeRim>(event.colType_)); } + + void MainDialog::onGridLabelLeftClickR(GridClickEvent& event) { onGridLabelLeftClick(false, static_cast<ColumnTypeRim>(event.colType_)); @@ -3837,26 +3804,15 @@ void MainDialog::updateGridViewData() zen::UInt64 filesizeLeftView; zen::UInt64 filesizeRightView; - //disable all buttons per default - m_bpButtonShowLeftOnly ->Show(false); - m_bpButtonShowRightOnly ->Show(false); - m_bpButtonShowLeftNewer ->Show(false); - m_bpButtonShowRightNewer->Show(false); - m_bpButtonShowDifferent ->Show(false); - m_bpButtonShowEqual ->Show(false); - m_bpButtonShowConflict ->Show(false); - - m_bpButtonShowCreateLeft ->Show(false); - m_bpButtonShowCreateRight->Show(false); - m_bpButtonShowDeleteLeft ->Show(false); - m_bpButtonShowDeleteRight->Show(false); - m_bpButtonShowUpdateLeft ->Show(false); - m_bpButtonShowUpdateRight->Show(false); - m_bpButtonShowDoNothing ->Show(false); + auto updateVisibility = [](ToggleButton* btn, bool shown) + { + if (btn->IsShown() != shown) + btn->Show(shown); + }; if (m_bpButtonViewTypeSyncAction->isActive()) { - const GridView::StatusSyncPreview result = gridDataView->updateSyncPreview(currentCfg.hideExcludedItems, + const GridView::StatusSyncPreview result = gridDataView->updateSyncPreview(m_bpButtonShowExcluded ->isActive(), m_bpButtonShowCreateLeft ->isActive(), m_bpButtonShowCreateRight->isActive(), m_bpButtonShowDeleteLeft ->isActive(), @@ -3864,8 +3820,8 @@ void MainDialog::updateGridViewData() m_bpButtonShowUpdateLeft ->isActive(), m_bpButtonShowUpdateRight->isActive(), m_bpButtonShowDoNothing ->isActive(), - m_bpButtonShowEqual ->isActive(), - m_bpButtonShowConflict ->isActive()); + m_bpButtonShowEqual ->isActive(), + m_bpButtonShowConflict ->isActive()); filesOnLeftView = result.filesOnLeftView; foldersOnLeftView = result.foldersOnLeftView; filesOnRightView = result.filesOnRightView; @@ -3873,40 +3829,28 @@ void MainDialog::updateGridViewData() filesizeLeftView = result.filesizeLeftView; filesizeRightView = result.filesizeRightView; - //sync preview buttons - m_bpButtonShowCreateLeft ->Show(result.existsSyncCreateLeft); - m_bpButtonShowCreateRight ->Show(result.existsSyncCreateRight); - m_bpButtonShowDeleteLeft ->Show(result.existsSyncDeleteLeft); - m_bpButtonShowDeleteRight ->Show(result.existsSyncDeleteRight); - m_bpButtonShowUpdateLeft ->Show(result.existsSyncDirLeft); - m_bpButtonShowUpdateRight ->Show(result.existsSyncDirRight); - m_bpButtonShowDoNothing ->Show(result.existsSyncDirNone); - m_bpButtonShowEqual ->Show(result.existsSyncEqual); - m_bpButtonShowConflict ->Show(result.existsConflict); - - const bool anyViewFilterButtonShown = m_bpButtonShowCreateLeft ->IsShown() || - m_bpButtonShowCreateRight->IsShown() || - m_bpButtonShowDeleteLeft ->IsShown() || - m_bpButtonShowDeleteRight->IsShown() || - m_bpButtonShowUpdateLeft ->IsShown() || - m_bpButtonShowUpdateRight->IsShown() || - m_bpButtonShowDoNothing ->IsShown() || - m_bpButtonShowEqual ->IsShown() || - m_bpButtonShowConflict ->IsShown(); - m_bpButtonViewTypeSyncAction->Show(anyViewFilterButtonShown); - - if (anyViewFilterButtonShown) - { - m_panelViewFilter->Show(); - m_panelViewFilter->Layout(); - } - else - m_panelViewFilter->Hide(); + updateVisibility(m_bpButtonShowExcluded , result.existsExcluded); + updateVisibility(m_bpButtonShowEqual , result.existsEqual); + updateVisibility(m_bpButtonShowConflict , result.existsConflict); + + updateVisibility(m_bpButtonShowCreateLeft , result.existsSyncCreateLeft); + updateVisibility(m_bpButtonShowCreateRight, result.existsSyncCreateRight); + updateVisibility(m_bpButtonShowDeleteLeft , result.existsSyncDeleteLeft); + updateVisibility(m_bpButtonShowDeleteRight, result.existsSyncDeleteRight); + updateVisibility(m_bpButtonShowUpdateLeft , result.existsSyncDirLeft); + updateVisibility(m_bpButtonShowUpdateRight, result.existsSyncDirRight); + updateVisibility(m_bpButtonShowDoNothing , result.existsSyncDirNone); + + updateVisibility(m_bpButtonShowLeftOnly , false); + updateVisibility(m_bpButtonShowRightOnly , false); + updateVisibility(m_bpButtonShowLeftNewer , false); + updateVisibility(m_bpButtonShowRightNewer, false); + updateVisibility(m_bpButtonShowDifferent , false); } else { - const GridView::StatusCmpResult result = gridDataView->updateCmpResult(currentCfg.hideExcludedItems, + const GridView::StatusCmpResult result = gridDataView->updateCmpResult(m_bpButtonShowExcluded ->isActive(), m_bpButtonShowLeftOnly ->isActive(), m_bpButtonShowRightOnly ->isActive(), m_bpButtonShowLeftNewer ->isActive(), @@ -3922,37 +3866,59 @@ void MainDialog::updateGridViewData() filesizeRightView = result.filesizeRightView; //comparison result view buttons - m_bpButtonShowLeftOnly ->Show(result.existsLeftOnly); - m_bpButtonShowRightOnly ->Show(result.existsRightOnly); - m_bpButtonShowLeftNewer ->Show(result.existsLeftNewer); - m_bpButtonShowRightNewer->Show(result.existsRightNewer); - m_bpButtonShowDifferent ->Show(result.existsDifferent); - m_bpButtonShowEqual ->Show(result.existsEqual); - m_bpButtonShowConflict ->Show(result.existsConflict); - - const bool anyViewFilterButtonShown = m_bpButtonShowLeftOnly ->IsShown() || - m_bpButtonShowRightOnly ->IsShown() || - m_bpButtonShowLeftNewer ->IsShown() || - m_bpButtonShowRightNewer->IsShown() || - m_bpButtonShowDifferent ->IsShown() || - m_bpButtonShowEqual ->IsShown() || - m_bpButtonShowConflict ->IsShown(); - m_bpButtonViewTypeSyncAction->Show(anyViewFilterButtonShown); - - if (anyViewFilterButtonShown) - { - m_panelViewFilter->Show(); - m_panelViewFilter->Layout(); - } - else - m_panelViewFilter->Hide(); + updateVisibility(m_bpButtonShowExcluded , result.existsExcluded); + updateVisibility(m_bpButtonShowEqual , result.existsEqual); + updateVisibility(m_bpButtonShowConflict , result.existsConflict); + + updateVisibility(m_bpButtonShowCreateLeft , false); + updateVisibility(m_bpButtonShowCreateRight, false); + updateVisibility(m_bpButtonShowDeleteLeft , false); + updateVisibility(m_bpButtonShowDeleteRight, false); + updateVisibility(m_bpButtonShowUpdateLeft , false); + updateVisibility(m_bpButtonShowUpdateRight, false); + updateVisibility(m_bpButtonShowDoNothing , false); + + updateVisibility(m_bpButtonShowLeftOnly , result.existsLeftOnly); + updateVisibility(m_bpButtonShowRightOnly , result.existsRightOnly); + updateVisibility(m_bpButtonShowLeftNewer , result.existsLeftNewer); + updateVisibility(m_bpButtonShowRightNewer, result.existsRightNewer); + updateVisibility(m_bpButtonShowDifferent , result.existsDifferent); } + + const bool anyViewFilterButtonShown = m_bpButtonShowExcluded ->IsShown() || + m_bpButtonShowEqual ->IsShown() || + m_bpButtonShowConflict ->IsShown() || + + m_bpButtonShowCreateLeft ->IsShown() || + m_bpButtonShowCreateRight->IsShown() || + m_bpButtonShowDeleteLeft ->IsShown() || + m_bpButtonShowDeleteRight->IsShown() || + m_bpButtonShowUpdateLeft ->IsShown() || + m_bpButtonShowUpdateRight->IsShown() || + m_bpButtonShowDoNothing ->IsShown() || + + m_bpButtonShowLeftOnly ->IsShown() || + m_bpButtonShowRightOnly ->IsShown() || + m_bpButtonShowLeftNewer ->IsShown() || + m_bpButtonShowRightNewer->IsShown() || + m_bpButtonShowDifferent ->IsShown(); + m_bpButtonViewTypeSyncAction->Show(anyViewFilterButtonShown); + + if (anyViewFilterButtonShown) + { + m_panelViewFilter->Show(); + m_panelViewFilter->Layout(); + } + else + m_panelViewFilter->Hide(); + + //all three grids retrieve their data directly via gridDataView gridview::refresh(*m_gridMainL, *m_gridMainC, *m_gridMainR); //navigation tree if (m_bpButtonViewTypeSyncAction->isActive()) - treeDataView->updateSyncPreview(currentCfg.hideExcludedItems, + treeDataView->updateSyncPreview(m_bpButtonShowExcluded ->isActive(), m_bpButtonShowCreateLeft ->isActive(), m_bpButtonShowCreateRight->isActive(), m_bpButtonShowDeleteLeft ->isActive(), @@ -3963,7 +3929,7 @@ void MainDialog::updateGridViewData() m_bpButtonShowEqual ->isActive(), m_bpButtonShowConflict ->isActive()); else - treeDataView->updateCmpResult(currentCfg.hideExcludedItems, + treeDataView->updateCmpResult(m_bpButtonShowExcluded ->isActive(), m_bpButtonShowLeftOnly ->isActive(), m_bpButtonShowRightOnly ->isActive(), m_bpButtonShowLeftNewer ->isActive(), @@ -4561,7 +4527,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" (F9)"); + m_bpButtonViewTypeSyncAction->SetToolTip((value ? _("Action") : _("Category")) + L" (F10)"); //toggle display of sync preview in middle grid gridview::highlightSyncAction(*m_gridMainC, value); diff --git a/FreeFileSync/Source/ui/main_dlg.h b/FreeFileSync/Source/ui/main_dlg.h index 110f42b6..7600edc4 100644 --- a/FreeFileSync/Source/ui/main_dlg.h +++ b/FreeFileSync/Source/ui/main_dlg.h @@ -205,8 +205,6 @@ private: void OnResizeLeftFolderWidth(wxEvent& event); void OnResizeConfigPanel (wxEvent& event); void OnResizeViewPanel (wxEvent& event); - void OnResizeStatisticsPanel(wxEvent& 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; diff --git a/FreeFileSync/Source/ui/progress_indicator.cpp b/FreeFileSync/Source/ui/progress_indicator.cpp index cec13836..972ea820 100644 --- a/FreeFileSync/Source/ui/progress_indicator.cpp +++ b/FreeFileSync/Source/ui/progress_indicator.cpp @@ -721,7 +721,7 @@ private: if (event.ControlDown()) switch (keyCode) { - //case 'A': -> "select all" is already implemented by Grid! + //case 'A': -> "select all" is already implemented by Grid! case 'C': case WXK_INSERT: //CTRL + C || CTRL + INS @@ -729,6 +729,14 @@ private: return; // -> swallow event! don't allow default grid commands! } + //else + //switch (keyCode) + //{ + // case WXK_RETURN: + // case WXK_NUMPAD_ENTER: + // return; + //} + event.Skip(); //unknown keypress: propagate } @@ -784,7 +792,7 @@ private: else switch (keyCode) { - //redirect certain (unhandled) keys directly to grid! + //redirect certain (unhandled) keys directly to grid! case WXK_UP: case WXK_DOWN: case WXK_LEFT: @@ -1082,9 +1090,10 @@ struct LabelFormatterTimeElapsed : public LabelFormatter virtual wxString formatText(double timeElapsed, double optimalBlockSize) const { - if (!drawLabel_) return wxString(); + if (!drawLabel_) + return wxString(); return timeElapsed < 60 ? - _P("1 sec", "%x sec", numeric::round(timeElapsed)) : + wxString(_P("1 sec", "%x sec", numeric::round(timeElapsed))) : timeElapsed < 3600 ? wxTimeSpan::Seconds(timeElapsed).Format( L"%M:%S") : wxTimeSpan::Seconds(timeElapsed).Format(L"%H:%M:%S"); @@ -1869,8 +1878,8 @@ void SyncProgressDialogImpl<TopLevelDialog>::processHasFinished(SyncResult resul //set overall speed (instead of current speed) const int64_t timeDelta = timeElapsed.timeMs() - phaseStartMs; //we need to consider "time within current phase" not total "timeElapsed"! - const wxString overallBytesPerSecond = timeDelta == 0 ? wxString() : filesizeToShortString(dataCurrent * 1000 / timeDelta) + _("/sec"); - const wxString overallItemsPerSecond = timeDelta == 0 ? wxString() : replaceCpy(_("%x items/sec"), L"%x", formatThreeDigitPrecision(itemsCurrent * 1000.0 / timeDelta)); + const wxString overallBytesPerSecond = timeDelta == 0 ? std::wstring() : filesizeToShortString(dataCurrent * 1000 / timeDelta) + _("/sec"); + const wxString overallItemsPerSecond = timeDelta == 0 ? std::wstring() : replaceCpy(_("%x items/sec"), L"%x", formatThreeDigitPrecision(itemsCurrent * 1000.0 / timeDelta)); pnl.m_panelGraphBytes->setAttributes(pnl.m_panelGraphBytes->getAttributes().setCornerText(overallBytesPerSecond, Graph2D::CORNER_TOP_LEFT)); pnl.m_panelGraphItems->setAttributes(pnl.m_panelGraphItems->getAttributes().setCornerText(overallItemsPerSecond, Graph2D::CORNER_TOP_LEFT)); diff --git a/FreeFileSync/Source/ui/small_dlgs.cpp b/FreeFileSync/Source/ui/small_dlgs.cpp index 785f558d..6630c405 100644 --- a/FreeFileSync/Source/ui/small_dlgs.cpp +++ b/FreeFileSync/Source/ui/small_dlgs.cpp @@ -603,9 +603,9 @@ CompareCfgDialog::CompareCfgDialog(wxWindow* parent, SetTitle(title); enumDescrHandleSyml. - add(SYMLINK_EXCLUDE, _("Exclude")). - add(SYMLINK_USE_DIRECTLY, _("Direct")). - add(SYMLINK_FOLLOW_LINK, _("Follow")); + add(SYMLINK_EXCLUDE, _("Exclude")). + add(SYMLINK_DIRECT, _("Direct")). + add(SYMLINK_FOLLOW, _("Follow")); setEnumVal(enumDescrHandleSyml, *m_choiceHandleSymlinks, cmpConfig.handleSymlinks); @@ -719,6 +719,8 @@ GlobalSettingsDlg::GlobalSettingsDlg(wxWindow* parent, xmlAccess::XmlGlobalSetti //setMainInstructionFont(*m_staticTextHeader); + m_gridCustomCommand->SetTabBehaviour(wxGrid::Tab_Leave); + m_bitmapSettings ->SetBitmap (getResourceImage(L"settings")); m_bpButtonAddRow ->SetBitmapLabel(getResourceImage(L"item_add")); m_bpButtonRemoveRow ->SetBitmapLabel(getResourceImage(L"item_remove")); diff --git a/FreeFileSync/Source/ui/tree_view.cpp b/FreeFileSync/Source/ui/tree_view.cpp index f3c728c4..04da8827 100644 --- a/FreeFileSync/Source/ui/tree_view.cpp +++ b/FreeFileSync/Source/ui/tree_view.cpp @@ -550,7 +550,7 @@ ptrdiff_t TreeView::getParent(size_t row) const } -void TreeView::updateCmpResult(bool hideFiltered, +void TreeView::updateCmpResult(bool showExcluded, bool leftOnlyFilesActive, bool rightOnlyFilesActive, bool leftNewerFilesActive, @@ -559,7 +559,7 @@ void TreeView::updateCmpResult(bool hideFiltered, bool equalFilesActive, bool conflictFilesActive) { - updateView([hideFiltered, //make sure the predicate can be stored safely! + updateView([showExcluded, //make sure the predicate can be stored safely! leftOnlyFilesActive, rightOnlyFilesActive, leftNewerFilesActive, @@ -568,7 +568,7 @@ void TreeView::updateCmpResult(bool hideFiltered, equalFilesActive, conflictFilesActive](const FileSystemObject& fsObj) -> bool { - if (hideFiltered && !fsObj.isActive()) + if (!fsObj.isActive() && !showExcluded) return false; switch (fsObj.getCategory()) @@ -595,7 +595,7 @@ void TreeView::updateCmpResult(bool hideFiltered, } -void TreeView::updateSyncPreview(bool hideFiltered, +void TreeView::updateSyncPreview(bool showExcluded, bool syncCreateLeftActive, bool syncCreateRightActive, bool syncDeleteLeftActive, @@ -606,7 +606,7 @@ void TreeView::updateSyncPreview(bool hideFiltered, bool syncEqualActive, bool conflictFilesActive) { - updateView([hideFiltered, //make sure the predicate can be stored safely! + updateView([showExcluded, //make sure the predicate can be stored safely! syncCreateLeftActive, syncCreateRightActive, syncDeleteLeftActive, @@ -617,7 +617,7 @@ void TreeView::updateSyncPreview(bool hideFiltered, syncEqualActive, conflictFilesActive](const FileSystemObject& fsObj) -> bool { - if (hideFiltered && !fsObj.isActive()) + if (!fsObj.isActive() && !showExcluded) return false; switch (fsObj.getSyncOperation()) diff --git a/FreeFileSync/Source/ui/tree_view.h b/FreeFileSync/Source/ui/tree_view.h index d42d898f..1c648171 100644 --- a/FreeFileSync/Source/ui/tree_view.h +++ b/FreeFileSync/Source/ui/tree_view.h @@ -26,7 +26,7 @@ public: void setData(FolderComparison& newData); //set data, taking (partial) ownership //apply view filter: comparison results - void updateCmpResult(bool hideFiltered, + void updateCmpResult(bool showExcluded, bool leftOnlyFilesActive, bool rightOnlyFilesActive, bool leftNewerFilesActive, @@ -36,7 +36,7 @@ public: bool conflictFilesActive); //apply view filter: synchronization preview - void updateSyncPreview(bool hideFiltered, + void updateSyncPreview(bool showExcluded, bool syncCreateLeftActive, bool syncCreateRightActive, bool syncDeleteLeftActive, diff --git a/FreeFileSync/Source/version/version.h b/FreeFileSync/Source/version/version.h index b3dca56b..fa50d479 100644 --- a/FreeFileSync/Source/version/version.h +++ b/FreeFileSync/Source/version/version.h @@ -3,7 +3,7 @@ namespace zen { -const wchar_t currentVersion[] = L"5.23"; //internal linkage! +const wchar_t currentVersion[] = L"6.0"; //internal linkage! } #endif diff --git a/wx+/grid.cpp b/wx+/grid.cpp index 87f81dda..95baaf3b 100644 --- a/wx+/grid.cpp +++ b/wx+/grid.cpp @@ -246,7 +246,7 @@ public: Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(SubWindow::onEraseBackGround), nullptr, this); //SetDoubleBuffered(true); slow as hell! - + SetBackgroundStyle(wxBG_STYLE_PAINT); Connect(wxEVT_SET_FOCUS, wxFocusEventHandler(SubWindow::onFocus), nullptr, this); @@ -263,8 +263,6 @@ public: Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(SubWindow::onMouseWheel ), nullptr, this); Connect(wxEVT_MOUSE_CAPTURE_LOST, wxMouseCaptureLostEventHandler(SubWindow::onMouseCaptureLost), nullptr, this); - Connect(wxEVT_CHAR, wxKeyEventHandler(SubWindow::onChar ), nullptr, this); - Connect(wxEVT_KEY_UP, wxKeyEventHandler(SubWindow::onKeyUp ), nullptr, this); Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(SubWindow::onKeyDown), nullptr, this); assert(GetClientAreaOrigin() == wxPoint()); //generally assumed when dealing with coordinates below @@ -297,7 +295,7 @@ protected: SetToolTip(new wxToolTip(L"a b\n\ a b")); //ugly, but is working (on Windows) tt = GetToolTip(); //should be bound by now - assert(tt); + assert(tt); if (tt) tt->SetTip(text); } @@ -318,9 +316,12 @@ private: virtual void onMouseMovement (wxMouseEvent& event) { event.Skip(); } virtual void onLeaveWindow (wxMouseEvent& event) { event.Skip(); } virtual void onMouseCaptureLost(wxMouseCaptureLostEvent& event) { event.Skip(); } - virtual void onChar (wxKeyEvent& event) { event.Skip(); } - virtual void onKeyUp (wxKeyEvent& event) { event.Skip(); } - virtual void onKeyDown(wxKeyEvent& event) { event.Skip(); } + + void onKeyDown(wxKeyEvent& event) + { + if (!sendEventNow(event)) //let parent collect all key events + event.Skip(); + } void onMouseWheel(wxMouseEvent& event) { @@ -332,10 +333,8 @@ private: On OS X there is no such propagation! => we need a redirection (the same wxGrid implements) */ - if (wxEvtHandler* evtHandler = parent_.GetEventHandler()) - if (evtHandler->ProcessEvent(event)) - return; - event.Skip(); + if (!sendEventNow(event)) + event.Skip(); } void onPaintEvent(wxPaintEvent& event) @@ -844,53 +843,15 @@ public: ~MainWin() { assert(!gridUpdatePending); } - void makeRowVisible(size_t row) - { - const wxRect labelRect = rowLabelWin_.getRowLabelArea(row); //returns empty rect if column not found - if (labelRect.height > 0) - { - int scrollPosX = 0; - refParent().GetViewStart(&scrollPosX, nullptr); - - int pixelsPerUnitY = 0; - refParent().GetScrollPixelsPerUnit(nullptr, &pixelsPerUnitY); - if (pixelsPerUnitY <= 0) return; - - const int clientPosY = refParent().CalcScrolledPosition(labelRect.GetTopLeft()).y; - if (clientPosY < 0) - { - const int scrollPosY = labelRect.GetTopLeft().y / pixelsPerUnitY; - refParent().Scroll(scrollPosX, scrollPosY); - refParent().updateWindowSizes(); //may show horizontal scroll bar - } - else if (clientPosY + labelRect.GetHeight() > rowLabelWin_.GetClientSize().GetHeight()) - { - auto execScroll = [&](int clientHeight) - { - const int scrollPosY = std::ceil((labelRect.GetTopLeft().y - clientHeight + - labelRect.GetHeight()) / static_cast<double>(pixelsPerUnitY)); - refParent().Scroll(scrollPosX, scrollPosY); - refParent().updateWindowSizes(); //may show horizontal scroll bar - }; - - const int clientHeightBefore = rowLabelWin_.GetClientSize().GetHeight(); - execScroll(clientHeightBefore); - - //client height may decrease after scroll due to a new horizontal scrollbar, resulting in a partially visible last row - const int clientHeightAfter = rowLabelWin_.GetClientSize().GetHeight(); - if (clientHeightAfter < clientHeightBefore) - execScroll(clientHeightAfter); - } - } - } + size_t getCursor() const { return cursorRow; } + size_t getAnchor() const { return selectionAnchor; } - void setCursor(size_t row) + void setCursor(size_t newCursorRow, size_t newAnchorRow) { - cursorRow = row; + cursorRow = newCursorRow; + selectionAnchor = newAnchorRow; activeSelection.reset(); //e.g. user might search with F3 while holding down left mouse button - selectionAnchor = row; } - size_t getCursor() const { return cursorRow; } private: virtual void render(wxDC& dc, const wxRect& rect) @@ -923,12 +884,13 @@ private: if (auto prov = refParent().getDataProvider()) { + RecursiveDcClipper dummy2(dc, rect); //do NOT draw background on cells outside of invalidated rect invalidating foreground text! + //draw background lines for (int row = rowFirst; row < rowLast; ++row) { const wxRect rowRect(cellAreaTL + wxPoint(0, row * rowHeight), wxSize(totalWidth, rowHeight)); - RecursiveDcClipper dummy2(dc, rowRect); //solve issues with drawBackground() painting in area outside of rect - //(which is not also refreshed by renderCell()) -> keep small scope! + RecursiveDcClipper dummy3(dc, rowRect); prov->renderRowBackgound(dc, rowRect, row, refParent().IsThisEnabled(), drawAsSelected(row)); } @@ -942,8 +904,7 @@ private: for (int row = rowFirst; row < rowLast; ++row) { const wxRect cellRect(cellAreaTL.x, cellAreaTL.y + row * rowHeight, cw.width_, rowHeight); - RecursiveDcClipper clip(dc, cellRect); - + RecursiveDcClipper dummy3(dc, cellRect); prov->renderCell(dc, cellRect, row, cw.type_, drawAsSelected(row)); } cellAreaTL.x += cw.width_; @@ -1095,144 +1056,6 @@ private: event.Skip(); } - virtual void onKeyDown(wxKeyEvent& event) - { - int keyCode = event.GetKeyCode(); - if (GetLayoutDirection() == wxLayout_RightToLeft) - { - if (keyCode == WXK_LEFT) - keyCode = WXK_RIGHT; - else if (keyCode == WXK_RIGHT) - keyCode = WXK_LEFT; - else if (keyCode == WXK_NUMPAD_LEFT) - keyCode = WXK_NUMPAD_RIGHT; - else if (keyCode == WXK_NUMPAD_RIGHT) - keyCode = WXK_NUMPAD_LEFT; - } - - const ptrdiff_t rowCount = refParent().getRowCount(); - if (rowCount <= 0) - { - event.Skip(); - return; - } - - auto setSingleSelection = [&](ptrdiff_t row) - { - numeric::confine<ptrdiff_t>(row, 0, rowCount - 1); - refParent().setGridCursor(row); //behave like an "external" set cursor! - }; - - auto setSelectionRange = [&](ptrdiff_t row) - { - //unlike "setSingleSelection" this function doesn't seem to belong into Grid: management of selectionAnchor should be local - - numeric::confine<ptrdiff_t>(row, 0, rowCount - 1); - - refParent().selection.clear(); //clear selection, do NOT fire event - refParent().selectRangeAndNotify(selectionAnchor, row); //set new selection + fire event - - cursorRow = row; //don't call setCursor() since it writes to "selectionAnchor"! - this->makeRowVisible(row); - refParent().Refresh(); - }; - - switch (keyCode) - { - case WXK_UP: - case WXK_NUMPAD_UP: - if (event.ShiftDown()) - setSelectionRange(cursorRow - 1); - else if (event.ControlDown()) - refParent().scrollDelta(0, -1); - else - setSingleSelection(cursorRow - 1); - return; //swallow event: wxScrolledWindow, wxWidgets 2.9.3 on Kubuntu x64 processes arrow keys: prevent this! - - case WXK_DOWN: - case WXK_NUMPAD_DOWN: - if (event.ShiftDown()) - setSelectionRange(cursorRow + 1); - else if (event.ControlDown()) - refParent().scrollDelta(0, 1); - else - setSingleSelection(cursorRow + 1); - return; //swallow event - - case WXK_LEFT: - case WXK_NUMPAD_LEFT: - if (event.ControlDown()) - refParent().scrollDelta(-1, 0); - else if (event.ShiftDown()) - ; - else - setSingleSelection(cursorRow); - return; - - case WXK_RIGHT: - case WXK_NUMPAD_RIGHT: - if (event.ControlDown()) - refParent().scrollDelta(1, 0); - else if (event.ShiftDown()) - ; - else - setSingleSelection(cursorRow); - return; - - case WXK_HOME: - case WXK_NUMPAD_HOME: - if (event.ShiftDown()) - setSelectionRange(0); - else if (event.ControlDown()) - setSingleSelection(0); - else - setSingleSelection(0); - return; - - case WXK_END: - case WXK_NUMPAD_END: - if (event.ShiftDown()) - setSelectionRange(rowCount - 1); - else if (event.ControlDown()) - setSingleSelection(rowCount - 1); - else - setSingleSelection(rowCount - 1); - return; - - case WXK_PAGEUP: - case WXK_NUMPAD_PAGEUP: - if (event.ShiftDown()) - setSelectionRange(cursorRow - GetClientSize().GetHeight() / rowLabelWin_.getRowHeight()); - else if (event.ControlDown()) - ; - else - setSingleSelection(cursorRow - GetClientSize().GetHeight() / rowLabelWin_.getRowHeight()); - return; - - case WXK_PAGEDOWN: - case WXK_NUMPAD_PAGEDOWN: - if (event.ShiftDown()) - setSelectionRange(cursorRow + GetClientSize().GetHeight() / rowLabelWin_.getRowHeight()); - else if (event.ControlDown()) - ; - else - setSingleSelection(cursorRow + GetClientSize().GetHeight() / rowLabelWin_.getRowHeight()); - return; - - case 'A': //Ctrl + A - select all - if (event.ControlDown()) - refParent().selectRangeAndNotify(0, rowCount); - break; - - case WXK_NUMPAD_ADD: //CTRL + '+' - auto-size all - if (event.ControlDown()) - refParent().autoSizeColumns(ALLOW_GRID_EVENT); - return; - } - - event.Skip(); - } - virtual void onFocus(wxFocusEvent& event) { Refresh(); event.Skip(); } class MouseSelection : private wxEvtHandler @@ -1402,16 +1225,18 @@ Grid::Grid(wxWindow* parent, return labelFont.GetPixelSize().GetHeight(); }(); - Connect(wxEVT_PAINT, wxPaintEventHandler(Grid::onPaintEvent ), nullptr, this); - Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(Grid::onEraseBackGround), nullptr, this); - Connect(wxEVT_SIZE, wxSizeEventHandler (Grid::onSizeEvent ), nullptr, this); - SetTargetWindow(mainWin_); SetInitialSize(size); //"Most controls will use this to set their initial size" -> why not assert(GetClientSize() == GetSize()); //borders are NOT allowed for Grid //reason: updateWindowSizes() wants to use "GetSize()" as a "GetClientSize()" including scrollbars + + Connect(wxEVT_PAINT, wxPaintEventHandler(Grid::onPaintEvent ), nullptr, this); + Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(Grid::onEraseBackGround), nullptr, this); + Connect(wxEVT_SIZE, wxSizeEventHandler (Grid::onSizeEvent ), nullptr, this); + + Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(Grid::onKeyDown), nullptr, this); } @@ -1574,6 +1399,144 @@ wxSize Grid::GetSizeAvailableForScrollTarget(const wxSize& size) void Grid::onPaintEvent(wxPaintEvent& event) { wxPaintDC dc(this); } +void Grid::onKeyDown(wxKeyEvent& event) +{ + int keyCode = event.GetKeyCode(); + if (GetLayoutDirection() == wxLayout_RightToLeft) + { + if (keyCode == WXK_LEFT) + keyCode = WXK_RIGHT; + else if (keyCode == WXK_RIGHT) + keyCode = WXK_LEFT; + else if (keyCode == WXK_NUMPAD_LEFT) + keyCode = WXK_NUMPAD_RIGHT; + else if (keyCode == WXK_NUMPAD_RIGHT) + keyCode = WXK_NUMPAD_LEFT; + } + + const ptrdiff_t rowCount = getRowCount(); + const ptrdiff_t cursorRow = mainWin_->getCursor(); + + auto moveCursorTo = [&](ptrdiff_t row) + { + if (rowCount > 0) + { + numeric::confine<ptrdiff_t>(row, 0, rowCount - 1); + setGridCursor(row); + } + }; + + auto selectWithCursorTo = [&](ptrdiff_t row) + { + if (rowCount > 0) + { + numeric::confine<ptrdiff_t>(row, 0, rowCount - 1); + selectWithCursor(row); + } + }; + + switch (keyCode) + { + //case WXK_TAB: + // if (Navigate(event.ShiftDown() ? wxNavigationKeyEvent::IsBackward : wxNavigationKeyEvent::IsForward)) + // return; + // break; + + case WXK_UP: + case WXK_NUMPAD_UP: + if (event.ShiftDown()) + selectWithCursorTo(cursorRow - 1); + else if (event.ControlDown()) + scrollDelta(0, -1); + else + moveCursorTo(cursorRow - 1); + return; //swallow event: wxScrolledWindow, wxWidgets 2.9.3 on Kubuntu x64 processes arrow keys: prevent this! + + case WXK_DOWN: + case WXK_NUMPAD_DOWN: + if (event.ShiftDown()) + selectWithCursorTo(cursorRow + 1); + else if (event.ControlDown()) + scrollDelta(0, 1); + else + moveCursorTo(cursorRow + 1); + return; //swallow event + + case WXK_LEFT: + case WXK_NUMPAD_LEFT: + if (event.ControlDown()) + scrollDelta(-1, 0); + else if (event.ShiftDown()) + ; + else + moveCursorTo(cursorRow); + return; + + case WXK_RIGHT: + case WXK_NUMPAD_RIGHT: + if (event.ControlDown()) + scrollDelta(1, 0); + else if (event.ShiftDown()) + ; + else + moveCursorTo(cursorRow); + return; + + case WXK_HOME: + case WXK_NUMPAD_HOME: + if (event.ShiftDown()) + selectWithCursorTo(0); + else if (event.ControlDown()) + moveCursorTo(0); + else + moveCursorTo(0); + return; + + case WXK_END: + case WXK_NUMPAD_END: + if (event.ShiftDown()) + selectWithCursorTo(rowCount - 1); + else if (event.ControlDown()) + moveCursorTo(rowCount - 1); + else + moveCursorTo(rowCount - 1); + return; + + case WXK_PAGEUP: + case WXK_NUMPAD_PAGEUP: + if (event.ShiftDown()) + selectWithCursorTo(cursorRow - GetClientSize().GetHeight() / rowLabelWin_->getRowHeight()); + else if (event.ControlDown()) + ; + else + moveCursorTo(cursorRow - GetClientSize().GetHeight() / rowLabelWin_->getRowHeight()); + return; + + case WXK_PAGEDOWN: + case WXK_NUMPAD_PAGEDOWN: + if (event.ShiftDown()) + selectWithCursorTo(cursorRow + GetClientSize().GetHeight() / rowLabelWin_->getRowHeight()); + else if (event.ControlDown()) + ; + else + moveCursorTo(cursorRow + GetClientSize().GetHeight() / rowLabelWin_->getRowHeight()); + return; + + case 'A': //Ctrl + A - select all + if (event.ControlDown()) + selectRangeAndNotify(0, rowCount); + break; + + case WXK_NUMPAD_ADD: //CTRL + '+' - auto-size all + if (event.ControlDown()) + autoSizeColumns(ALLOW_GRID_EVENT); + return; + } + + event.Skip(); +} + + void Grid::setColumnLabelHeight(int height) { colLabelHeight = std::max(0, height); @@ -1939,8 +1902,8 @@ wxRect Grid::getCellArea(size_t row, ColumnType colType) const void Grid::setGridCursor(size_t row) { - mainWin_->setCursor(row); - mainWin_->makeRowVisible(row); + mainWin_->setCursor(row, row); + makeRowVisible(row); selection.clear(); //clear selection, do NOT fire event selectRangeAndNotify(row, row); //set new selection + fire event @@ -1950,6 +1913,62 @@ void Grid::setGridCursor(size_t row) } +void Grid::selectWithCursor(ptrdiff_t row) +{ + const size_t anchorRow = mainWin_->getAnchor(); + + mainWin_->setCursor(row, anchorRow); + makeRowVisible(row); + + selection.clear(); //clear selection, do NOT fire event + selectRangeAndNotify(anchorRow, row); //set new selection + fire event + + mainWin_->Refresh(); + rowLabelWin_->Refresh(); +} + + +void Grid::makeRowVisible(size_t row) +{ + const wxRect labelRect = rowLabelWin_->getRowLabelArea(row); //returns empty rect if column not found + if (labelRect.height > 0) + { + int scrollPosX = 0; + GetViewStart(&scrollPosX, nullptr); + + int pixelsPerUnitY = 0; + GetScrollPixelsPerUnit(nullptr, &pixelsPerUnitY); + if (pixelsPerUnitY <= 0) return; + + const int clientPosY = CalcScrolledPosition(labelRect.GetTopLeft()).y; + if (clientPosY < 0) + { + const int scrollPosY = labelRect.GetTopLeft().y / pixelsPerUnitY; + Scroll(scrollPosX, scrollPosY); + updateWindowSizes(); //may show horizontal scroll bar + } + else if (clientPosY + labelRect.GetHeight() > rowLabelWin_->GetClientSize().GetHeight()) + { + auto execScroll = [&](int clientHeight) + { + const int scrollPosY = std::ceil((labelRect.GetTopLeft().y - clientHeight + + labelRect.GetHeight()) / static_cast<double>(pixelsPerUnitY)); + Scroll(scrollPosX, scrollPosY); + updateWindowSizes(); //may show horizontal scroll bar + }; + + const int clientHeightBefore = rowLabelWin_->GetClientSize().GetHeight(); + execScroll(clientHeightBefore); + + //client height may decrease after scroll due to a new horizontal scrollbar, resulting in a partially visible last row + const int clientHeightAfter = rowLabelWin_->GetClientSize().GetHeight(); + if (clientHeightAfter < clientHeightBefore) + execScroll(clientHeightAfter); + } + } +} + + void Grid::selectRangeAndNotify(ptrdiff_t rowFrom, ptrdiff_t rowTo, bool positive) { //sort + convert to half-open range @@ -199,9 +199,13 @@ private: void onPaintEvent(wxPaintEvent& event); void onEraseBackGround(wxEraseEvent& event) {} //[!] void onSizeEvent(wxSizeEvent& event) { updateWindowSizes(); event.Skip(); } + void onKeyDown(wxKeyEvent& event); void updateWindowSizes(bool updateScrollbar = true); + void selectWithCursor(ptrdiff_t row); + void makeRowVisible(size_t row); + void redirectRowLabelEvent(wxMouseEvent& event); virtual wxSize GetSizeAvailableForScrollTarget(const wxSize& size); //required since wxWidgets 2.9 if SetTargetWindow() is used diff --git a/wx+/image_resources.cpp b/wx+/image_resources.cpp index 6da12c17..7b74c161 100644 --- a/wx+/image_resources.cpp +++ b/wx+/image_resources.cpp @@ -62,6 +62,8 @@ private: void GlobalResources::init(const Zstring& filename) { + assert(bitmaps.empty() && anims.empty()); + wxFFileInputStream input(utfCvrtTo<wxString>(filename)); if (input.IsOk()) //if not... we don't want to react too harsh here { diff --git a/wx+/popup_dlg.cpp b/wx+/popup_dlg.cpp index 2c7887fa..d7d1960e 100644 --- a/wx+/popup_dlg.cpp +++ b/wx+/popup_dlg.cpp @@ -62,11 +62,11 @@ void setBestInitialSize(wxTextCtrl& ctrl, const wxString& text, wxSize maxSize) } #if defined ZEN_WIN || defined ZEN_LINUX - const int rowGap = 0; + const int rowGap = 0; #elif defined ZEN_MAC - const int rowGap = 1; + const int rowGap = 1; #endif - const wxSize bestSize(bestWidth + scrollbarWidth, std::min(rowCount * (rowHeight + rowGap), maxSize.y)); + const wxSize bestSize(bestWidth + scrollbarWidth, std::min(rowCount * (rowHeight + rowGap), maxSize.y)); ctrl.SetMinSize(bestSize); //alas, SetMinClientSize() is just not working! } } diff --git a/zen/assert_static.h b/zen/assert_static.h index 469e0299..17d5c370 100644 --- a/zen/assert_static.h +++ b/zen/assert_static.h @@ -1,6 +1,6 @@ // ************************************************************************** -// * This file is part of the zen::Xml project. It is distributed under the * -// * Boost Software License: http://www.boost.org/LICENSE_1_0.txt * +// * 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 * // ************************************************************************** diff --git a/zen/file_handling.cpp b/zen/file_handling.cpp index 621c2b1b..8c5584db 100644 --- a/zen/file_handling.cpp +++ b/zen/file_handling.cpp @@ -511,7 +511,9 @@ private: }; -void removeDirectoryImpl(const Zstring& directory, CallbackRemoveDir* callback) //throw FileError +void removeDirectoryImpl(const Zstring& directory, //throw FileError + const std::function<void (const Zstring& filename)>& onBeforeFileDeletion, + const std::function<void (const Zstring& dirname)>& onBeforeDirDeletion) { assert(somethingExists(directory)); //[!] @@ -525,7 +527,8 @@ void removeDirectoryImpl(const Zstring& directory, CallbackRemoveDir* callback) //attention: check if directory is a symlink! Do NOT traverse into it deleting contained files!!! if (symlinkExists(directory)) //remove symlink directly { - if (callback) callback->onBeforeDirDeletion(directory); //once per symlink + if (onBeforeDirDeletion) + onBeforeDirDeletion(directory); //once per symlink #ifdef ZEN_WIN const wchar_t functionName[] = L"RemoveDirectory"; if (!::RemoveDirectory(directoryFmt.c_str())) @@ -546,22 +549,20 @@ void removeDirectoryImpl(const Zstring& directory, CallbackRemoveDir* callback) } //delete directories recursively - std::for_each(dirList.begin(), dirList.end(), - [&](const Zstring& dirname) - { - removeDirectoryImpl(dirname, callback); //throw FileError; call recursively to correctly handle symbolic links - }); + for (const Zstring& dirname : dirList) + removeDirectoryImpl(dirname, onBeforeFileDeletion, onBeforeDirDeletion); //throw FileError; call recursively to correctly handle symbolic links //delete files - std::for_each(fileList.begin(), fileList.end(), - [&](const Zstring& filename) + for (const Zstring& filename : fileList) { - if (callback) callback->onBeforeFileDeletion(filename); //call once per file + if (onBeforeFileDeletion) + onBeforeFileDeletion(filename); //call once per file removeFile(filename); //throw FileError - }); + } //parent directory is deleted last - if (callback) callback->onBeforeDirDeletion(directory); //and once per folder + if (onBeforeDirDeletion) + onBeforeDirDeletion(directory); //and once per folder #ifdef ZEN_WIN const wchar_t functionName[] = L"RemoveDirectory"; if (!::RemoveDirectory(directoryFmt.c_str())) @@ -647,7 +648,7 @@ void setFileTimeRaw(const Zstring& filename, const FILETIME& creationTime, const nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | //needed to open a directory - (procSl == SYMLINK_DIRECT ? FILE_FLAG_OPEN_REPARSE_POINT : 0), //process symlinks + (procSl == ProcSymlink::DIRECT ? FILE_FLAG_OPEN_REPARSE_POINT : 0), //process symlinks nullptr); }; @@ -805,7 +806,7 @@ void setFileTimeRaw(const Zstring& filename, const FILETIME& creationTime, const nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | //needed to open a directory - (procSl == SYMLINK_DIRECT ? FILE_FLAG_OPEN_REPARSE_POINT : 0), + (procSl == ProcSymlink::DIRECT ? FILE_FLAG_OPEN_REPARSE_POINT : 0), nullptr); assert(hFile != INVALID_HANDLE_VALUE); ZEN_ON_SCOPE_EXIT(::CloseHandle(hFile)); @@ -823,12 +824,14 @@ void setFileTimeRaw(const Zstring& filename, const FILETIME& creationTime, const } -void zen::removeDirectory(const Zstring& directory, CallbackRemoveDir* callback) +void zen::removeDirectory(const Zstring& directory, //throw FileError + const std::function<void (const Zstring& filename)>& onBeforeFileDeletion, + const std::function<void (const Zstring& dirname)>& onBeforeDirDeletion) { //no error situation if directory is not existing! manual deletion relies on it! if (!somethingExists(directory)) return; //neither directory nor any other object (e.g. broken symlink) with that name existing - removeDirectoryImpl(directory, callback); + removeDirectoryImpl(directory, onBeforeFileDeletion, onBeforeDirDeletion); } @@ -865,7 +868,7 @@ void zen::setFileTime(const Zstring& filename, const Int64& modTime, ProcSymlink newTimes[0].tv_sec = ::time(nullptr); //access time (seconds) newTimes[1].tv_sec = to<time_t>(modTime); //modification time (seconds) - const int rv = procSl == SYMLINK_FOLLOW ? + const int rv = procSl == ProcSymlink::FOLLOW ? :: utimes(filename.c_str(), newTimes) : //utimensat() not yet implemented on OS X ::lutimes(filename.c_str(), newTimes); if (rv != 0) @@ -960,8 +963,8 @@ void copyObjectPermissions(const Zstring& source, const Zstring& target, ProcSym //CAVEAT: if a file system does not support ACLs, GetFileSecurity() will return successfully with a *valid* security descriptor containing *no* ACL entries! //NOTE: ::GetFileSecurity()/::SetFileSecurity() do NOT follow Symlinks! getResolvedFilePath() requires Vista or later! - const Zstring sourceResolved = procSl == SYMLINK_FOLLOW && symlinkExists(source) ? getResolvedFilePath(source) : source; //throw FileError - const Zstring targetResolved = procSl == SYMLINK_FOLLOW && symlinkExists(target) ? getResolvedFilePath(target) : target; // + const Zstring sourceResolved = procSl == ProcSymlink::FOLLOW && symlinkExists(source) ? getResolvedFilePath(source) : source; //throw FileError + const Zstring targetResolved = procSl == ProcSymlink::FOLLOW && symlinkExists(target) ? getResolvedFilePath(target) : target; // //setting privileges requires admin rights! try @@ -1111,7 +1114,7 @@ void copyObjectPermissions(const Zstring& source, const Zstring& target, ProcSym #endif struct stat fileInfo = {}; - if (procSl == SYMLINK_FOLLOW) + if (procSl == ProcSymlink::FOLLOW) { if (::stat(source.c_str(), &fileInfo) != 0) throw FileError(replaceCpy(_("Cannot read permissions of %x."), L"%x", fmtFileName(source)), formatSystemError(L"stat", getLastError())); @@ -1339,7 +1342,7 @@ void zen::makeDirectoryPlain(const Zstring& directory, //throw FileError, ErrorT //enforce copying file permissions: it's advertized on GUI... if (copyFilePermissions) - copyObjectPermissions(templateDir, directory, SYMLINK_FOLLOW); //throw FileError + copyObjectPermissions(templateDir, directory, ProcSymlink::FOLLOW); //throw FileError guardNewDir.dismiss(); //target has been created successfully! } @@ -1397,18 +1400,18 @@ void zen::copySymlink(const Zstring& sourceLink, const Zstring& targetLink, bool &sourceAttr)) //__out LPVOID lpFileInformation throw FileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(sourceLink)), formatSystemError(L"GetFileAttributesEx", getLastError())); - setFileTimeRaw(targetLink, sourceAttr.ftCreationTime, sourceAttr.ftLastWriteTime, SYMLINK_DIRECT); //throw FileError + setFileTimeRaw(targetLink, sourceAttr.ftCreationTime, sourceAttr.ftLastWriteTime, ProcSymlink::DIRECT); //throw FileError #elif defined ZEN_LINUX || defined ZEN_MAC struct ::stat srcInfo = {}; if (::lstat(sourceLink.c_str(), &srcInfo) != 0) throw FileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(sourceLink)), formatSystemError(L"lstat", getLastError())); - setFileTime(targetLink, Int64(srcInfo.st_mtime), SYMLINK_DIRECT); //throw FileError + setFileTime(targetLink, Int64(srcInfo.st_mtime), ProcSymlink::DIRECT); //throw FileError #endif if (copyFilePermissions) - copyObjectPermissions(sourceLink, targetLink, SYMLINK_DIRECT); //throw FileError + copyObjectPermissions(sourceLink, targetLink, ProcSymlink::DIRECT); //throw FileError guardNewLink.dismiss(); //target has been created successfully! } @@ -1516,7 +1519,7 @@ bool canCopyAsSparse(const Zstring& sourceFile, const Zstring& targetFile) //thr //precondition: canCopyAsSparse() must return "true"! void copyFileWindowsSparse(const Zstring& sourceFile, const Zstring& targetFile, - CallbackCopyFile* callback, + const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus, InSyncAttributes* newAttrib) //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked { assert(canCopyAsSparse(sourceFile, targetFile)); @@ -1701,8 +1704,8 @@ void copyFileWindowsSparse(const Zstring& sourceFile, //total bytes transferred may be larger than file size! context information + ADS or smaller (sparse, compressed)! //invoke callback method to update progress indicators - if (callback) - callback->updateCopyStatus(Int64(bytesRead)); //throw X! + if (onUpdateCopyStatus) + onUpdateCopyStatus(Int64(bytesRead)); //throw X! if (bytesRead > 0) someBytesWritten = true; @@ -1764,12 +1767,12 @@ DEFINE_NEW_FILE_ERROR(ErrorShouldCopyAsSparse); class ErrorHandling { public: - ErrorHandling() : shouldCopyAsSparse(false), exceptionInUserCallback(nullptr) {} + ErrorHandling() : shouldCopyAsSparse(false) {} //call context: copyCallbackInternal() void reportErrorShouldCopyAsSparse() { shouldCopyAsSparse = true; } - void reportUserException(CallbackCopyFile& userCallback) { exceptionInUserCallback = &userCallback; } + void reportUserException(const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus) { exceptionInUserCallback = onUpdateCopyStatus; } void reportError(const std::wstring& msg, const std::wstring& description) { errorMsg = std::make_pair(msg, description); } @@ -1780,7 +1783,12 @@ public: throw ErrorShouldCopyAsSparse(L"sparse dummy value"); if (exceptionInUserCallback) - exceptionInUserCallback->updateCopyStatus(0); //rethrow (hopefully!) + try + { + exceptionInUserCallback(0); //should throw again!!! + assert(false); + } + catch (...) { throw; } if (!errorMsg.first.empty()) throw FileError(errorMsg.first, errorMsg.second); @@ -1789,25 +1797,25 @@ public: private: bool shouldCopyAsSparse; // std::pair<std::wstring, std::wstring> errorMsg; //these are exclusive! - CallbackCopyFile* exceptionInUserCallback; // + std::function<void(Int64 bytesDelta)> exceptionInUserCallback; // -> optional }; struct CallbackData { - CallbackData(CallbackCopyFile* cb, //may be nullptr + CallbackData(const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus, const Zstring& sourceFile, const Zstring& targetFile) : sourceFile_(sourceFile), targetFile_(targetFile), - userCallback(cb), + onUpdateCopyStatus_(onUpdateCopyStatus), fileInfoSrc(), fileInfoTrg() {} const Zstring& sourceFile_; const Zstring& targetFile_; + const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus_; - CallbackCopyFile* const userCallback; //optional! ErrorHandling errorHandler; BY_HANDLE_FILE_INFORMATION fileInfoSrc; //modified by CopyFileEx() at beginning BY_HANDLE_FILE_INFORMATION fileInfoTrg; // @@ -1899,18 +1907,17 @@ DWORD CALLBACK copyCallbackInternal(LARGE_INTEGER totalFileSize, //called after copy operation is finished - note: for 0-sized files this callback is invoked just ONCE! //if (totalFileSize.QuadPart == totalBytesTransferred.QuadPart && dwStreamNumber == 1) {} - if (cbd.userCallback && - totalBytesTransferred.QuadPart >= 0) //should be always true, but let's still check + if (cbd.onUpdateCopyStatus_ && totalBytesTransferred.QuadPart >= 0) //should be always true, but let's still check try { - cbd.userCallback->updateCopyStatus(totalBytesTransferred.QuadPart - cbd.bytesReported); //throw X! + cbd.onUpdateCopyStatus_(totalBytesTransferred.QuadPart - cbd.bytesReported); //throw X! cbd.bytesReported = totalBytesTransferred.QuadPart; } catch (...) { //#warning migrate to std::exception_ptr when available - cbd.errorHandler.reportUserException(*cbd.userCallback); + cbd.errorHandler.reportUserException(cbd.onUpdateCopyStatus_); return PROGRESS_CANCEL; } return PROGRESS_CONTINUE; @@ -1924,7 +1931,7 @@ const bool supportNonEncryptedDestination = winXpOrLater(); //encrypted destinat void copyFileWindowsDefault(const Zstring& sourceFile, const Zstring& targetFile, - CallbackCopyFile* callback, + const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus, InSyncAttributes* newAttrib) //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked, ErrorShouldCopyAsSparse { //try to get backup read and write privileges: who knows, maybe this helps solve some obscure "access denied" errors @@ -1947,7 +1954,7 @@ void copyFileWindowsDefault(const Zstring& sourceFile, //documentation on CopyFile2() even states: "It is not recommended to pause copies that are using this flag." How dangerous is this thing, why offer it at all??? //perf advantage: ~15% faster - CallbackData cbd(callback, sourceFile, targetFile); + CallbackData cbd(onUpdateCopyStatus, sourceFile, targetFile); const bool success = ::CopyFileEx( //same performance like CopyFile() applyLongPathPrefix(sourceFile).c_str(), //__in LPCTSTR lpExistingFileName, @@ -2051,7 +2058,7 @@ void copyFileWindowsDefault(const Zstring& sourceFile, } //####################################### DST hack ########################################### - setFileTimeRaw(targetFile, creationTimeOut, lastWriteTimeOut, SYMLINK_FOLLOW); //throw FileError + setFileTimeRaw(targetFile, creationTimeOut, lastWriteTimeOut, ProcSymlink::FOLLOW); //throw FileError } guardTarget.dismiss(); //target has been created successfully! @@ -2060,26 +2067,29 @@ void copyFileWindowsDefault(const Zstring& sourceFile, //another layer to support copying sparse files inline -void copyFileWindowsSelectRoutine(const Zstring& sourceFile, const Zstring& targetFile, CallbackCopyFile* callback, InSyncAttributes* sourceAttr) +void copyFileWindowsSelectRoutine(const Zstring& sourceFile, const Zstring& targetFile, const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus, InSyncAttributes* sourceAttr) { try { - copyFileWindowsDefault(sourceFile, targetFile, callback, sourceAttr); //throw ErrorShouldCopyAsSparse et al. + copyFileWindowsDefault(sourceFile, targetFile, onUpdateCopyStatus, sourceAttr); //throw ErrorShouldCopyAsSparse et al. } catch (ErrorShouldCopyAsSparse&) //we cheaply check for this condition within callback of ::CopyFileEx()! { - copyFileWindowsSparse(sourceFile, targetFile, callback, sourceAttr); + copyFileWindowsSparse(sourceFile, targetFile, onUpdateCopyStatus, sourceAttr); } } //another layer of indirection solving 8.3 name clashes inline -void copyFileWindows(const Zstring& sourceFile, const Zstring& targetFile, CallbackCopyFile* callback, InSyncAttributes* sourceAttr) +void copyFileWindows(const Zstring& sourceFile, + const Zstring& targetFile, + const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus, + InSyncAttributes* sourceAttr) { try { - copyFileWindowsSelectRoutine(sourceFile, targetFile, callback, sourceAttr); //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked + copyFileWindowsSelectRoutine(sourceFile, targetFile, onUpdateCopyStatus, sourceAttr); //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked } catch (const ErrorTargetExisting&) { @@ -2087,7 +2097,7 @@ void copyFileWindows(const Zstring& sourceFile, const Zstring& targetFile, Callb if (have8dot3NameClash(targetFile)) { Fix8Dot3NameClash dummy(targetFile); //throw FileError; move clashing filename to the side - copyFileWindowsSelectRoutine(sourceFile, targetFile, callback, sourceAttr); //throw FileError; the short filename name clash is solved, this should work now + copyFileWindowsSelectRoutine(sourceFile, targetFile, onUpdateCopyStatus, sourceAttr); //throw FileError; the short filename name clash is solved, this should work now return; } throw; @@ -2098,7 +2108,7 @@ void copyFileWindows(const Zstring& sourceFile, const Zstring& targetFile, Callb #elif defined ZEN_LINUX || defined ZEN_MAC void copyFileLinuxMac(const Zstring& sourceFile, const Zstring& targetFile, - CallbackCopyFile* callback, + const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus, InSyncAttributes* newAttrib) //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting { //open sourceFile for reading @@ -2123,8 +2133,8 @@ void copyFileLinuxMac(const Zstring& sourceFile, fileOut.write(&buffer[0], bytesRead); //throw FileError //invoke callback method to update progress indicators - if (callback) - callback->updateCopyStatus(Int64(bytesRead)); //throw X! + if (onUpdateCopyStatus) + onUpdateCopyStatus(Int64(bytesRead)); //throw X! } while (!fileIn.eof()); @@ -2155,7 +2165,7 @@ void copyFileLinuxMac(const Zstring& sourceFile, //http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=340236 //http://comments.gmane.org/gmane.linux.file-systems.cifs/2854 //on the other hand we thereby have to reopen https://sourceforge.net/p/freefilesync/bugs/230/ - setFileTime(targetFile, sourceInfo.st_mtime, SYMLINK_FOLLOW); //throw FileError + setFileTime(targetFile, sourceInfo.st_mtime, ProcSymlink::FOLLOW); //throw FileError guardTarget.dismiss(); //target has been created successfully! } @@ -2190,13 +2200,16 @@ copyFileWindowsDefault(::CopyFileEx) copyFileWindowsSparse(::BackupRead/::Backu */ inline -void copyFileSelectOs(const Zstring& sourceFile, const Zstring& targetFile, CallbackCopyFile* callback, InSyncAttributes* sourceAttr) +void copyFileSelectOs(const Zstring& sourceFile, + const Zstring& targetFile, + const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus, + InSyncAttributes* sourceAttr) { #ifdef ZEN_WIN - copyFileWindows(sourceFile, targetFile, callback, sourceAttr); //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked + copyFileWindows(sourceFile, targetFile, onUpdateCopyStatus, sourceAttr); //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked #elif defined ZEN_LINUX || defined ZEN_MAC - copyFileLinuxMac(sourceFile, targetFile, callback, sourceAttr); //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting + copyFileLinuxMac(sourceFile, targetFile, onUpdateCopyStatus, sourceAttr); //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting #endif } } @@ -2206,7 +2219,8 @@ void zen::copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPath const Zstring& targetFile, bool copyFilePermissions, bool transactionalCopy, - CallbackCopyFile* callback, + const std::function<void()>& onDeleteTargetFile, + const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus, InSyncAttributes* sourceAttr) { if (transactionalCopy) @@ -2216,7 +2230,7 @@ void zen::copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPath //raw file copy try { - copyFileSelectOs(sourceFile, temporary, callback, sourceAttr); //throw FileError: ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked + copyFileSelectOs(sourceFile, temporary, onUpdateCopyStatus, sourceAttr); //throw FileError: ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked } catch (ErrorTargetExisting&) { @@ -2225,15 +2239,15 @@ void zen::copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPath temporary = findUnusedTempName(targetFile); //retry - copyFileSelectOs(sourceFile, temporary, callback, sourceAttr); //throw FileError + copyFileSelectOs(sourceFile, temporary, onUpdateCopyStatus, 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); //throw X + if (onDeleteTargetFile) + onDeleteTargetFile(); //throw X //rename temporary file: //perf: this call is REALLY expensive on unbuffered volumes! ~40% performance decrease on FAT USB stick! @@ -2264,9 +2278,10 @@ void zen::copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPath } else { - if (callback) callback->deleteTargetFile(targetFile); + if (onDeleteTargetFile) + onDeleteTargetFile(); - copyFileSelectOs(sourceFile, targetFile, callback, sourceAttr); //throw FileError: ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked + copyFileSelectOs(sourceFile, targetFile, onUpdateCopyStatus, sourceAttr); //throw FileError: ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked } /* Note: non-transactional file copy solves at least four problems: @@ -2281,7 +2296,7 @@ void zen::copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPath { zen::ScopeGuard guardTargetFile = zen::makeGuard([&] { try { removeFile(targetFile); } catch (FileError&) {}}); - copyObjectPermissions(sourceFile, targetFile, SYMLINK_FOLLOW); //throw FileError + copyObjectPermissions(sourceFile, targetFile, ProcSymlink::FOLLOW); //throw FileError guardTargetFile.dismiss(); //target has been created successfully! } diff --git a/zen/file_handling.h b/zen/file_handling.h index b3d5ca1a..48a762d7 100644 --- a/zen/file_handling.h +++ b/zen/file_handling.h @@ -7,6 +7,7 @@ #ifndef FILE_HANDLING_H_8017341345614857 #define FILE_HANDLING_H_8017341345614857 +#include <functional> #include "zstring.h" #include "file_error.h" #include "file_id_def.h" @@ -14,19 +15,15 @@ namespace zen { -struct CallbackRemoveDir; -struct CallbackCopyFile; - - 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 +enum class ProcSymlink { - SYMLINK_DIRECT, - SYMLINK_FOLLOW + DIRECT, + FOLLOW }; void setFileTime(const Zstring& filename, const Int64& modificationTime, ProcSymlink procSl); //throw FileError @@ -37,7 +34,9 @@ UInt64 getFreeDiskSpace(const Zstring& path); //throw FileError //file handling bool removeFile(const Zstring& filename); //throw FileError; return "false" if file is not existing -void removeDirectory(const Zstring& directory, CallbackRemoveDir* callback = nullptr); //throw FileError +void removeDirectory(const Zstring& directory, //throw FileError + const std::function<void (const Zstring& filename)>& onBeforeFileDeletion = nullptr, //optional; + const std::function<void (const Zstring& dirname)>& onBeforeDirDeletion = nullptr); //one call for each *existing* object! //rename file or directory: no copying!!! void renameFile(const Zstring& oldName, const Zstring& newName); //throw FileError, ErrorDifferentVolume, ErrorTargetExisting @@ -64,37 +63,21 @@ void copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPathMissi const Zstring& targetFile, //symlink handling: dereference source bool copyFilePermissions, bool transactionalCopy, - CallbackCopyFile* callback, //may be nullptr + //if target is existing user needs to implement deletion: copyFile() NEVER overwrites target if already existing! + //if transactionalCopy == true, full read access on source had been proven at this point, so it's safe to delete it. + const std::function<void()>& onDeleteTargetFile, //may be nullptr; throw X! + //Linux: unconditionally + //Windows: first exception is swallowed, updateCopyStatus() is then called again where it should throw again and the exception will propagate as expected + //accummulated delta != file size! consider ADS, sparse, compressed files + const std::function<void(Int64 bytesDelta)>& onUpdateCopyStatus, //may be nullptr; throw X! + InSyncAttributes* newAttrib = nullptr); //return current attributes at the time of copy + //Note: it MAY happen that copyFile() leaves temp files behind, e.g. temporary network drop. // => clean them up at an appropriate time (automatically set sync directions to delete them). They have the following ending: const Zstring TEMP_FILE_ENDING = Zstr(".ffs_tmp"); void copySymlink(const Zstring& sourceLink, const Zstring& targetLink, bool copyFilePermissions); //throw FileError - - - -//----------- callbacks --------------- -struct CallbackRemoveDir -{ - virtual ~CallbackRemoveDir() {} - virtual void onBeforeFileDeletion(const Zstring& filename) = 0; //one call for each *existing* object! - virtual void onBeforeDirDeletion (const Zstring& dirname ) = 0; // -}; - -struct CallbackCopyFile -{ - virtual ~CallbackCopyFile() {} - - //if target is existing user needs to implement deletion: copyFile() NEVER overwrites target if already existing! - //if transactionalCopy == true, full read access on source had been proven at this point, so it's safe to delete it. - virtual void deleteTargetFile(const Zstring& targetFile) = 0; //may throw exceptions - - //may throw: - //Linux: unconditionally - //Windows: first exception is swallowed, updateCopyStatus() is then called again where it should throw again and the exception will propagate as expected - virtual void updateCopyStatus(Int64 bytesDelta) = 0; //accummulated delta != file size! consider ADS, sparse, compressed files -}; } #endif //FILE_HANDLING_H_8017341345614857 diff --git a/zen/file_traverser.cpp b/zen/file_traverser.cpp index 0e06d6c5..9c1b01a4 100644 --- a/zen/file_traverser.cpp +++ b/zen/file_traverser.cpp @@ -452,7 +452,7 @@ private: try { //set modification time including DST hack: this function is too clever to not introduce this dependency - setFileTime(it->first, it->second, SYMLINK_FOLLOW); //throw FileError + setFileTime(it->first, it->second, ProcSymlink::FOLLOW); //throw FileError } catch (FileError&) { diff --git a/zen/osx_throw_exception.h b/zen/osx_throw_exception.h index 018e9456..07e3af3e 100644 --- a/zen/osx_throw_exception.h +++ b/zen/osx_throw_exception.h @@ -35,9 +35,9 @@ inline void throwSysError(NSException* e) //throw SysError { std::string msg; -if (const char* name = [[e name ] cStringUsingEncoding:NSUTF8StringEncoding]) //"const char*" NOT owned by us! + if (const char* name = [[e name ] cStringUsingEncoding:NSUTF8StringEncoding]) //"const char*" NOT owned by us! msg += name; -if (const char* descr = [[e reason] cStringUsingEncoding:NSUTF8StringEncoding]) + if (const char* descr = [[e reason] cStringUsingEncoding:NSUTF8StringEncoding]) { msg += "\n"; msg += descr; diff --git a/zen/recycler.cpp b/zen/recycler.cpp index a1353f0b..16c2ac11 100644 --- a/zen/recycler.cpp +++ b/zen/recycler.cpp @@ -49,22 +49,23 @@ const bool useIFileOperation = vistaOrLater(); //caveat: function scope static i struct CallbackData { - CallbackData(CallbackRecycling* cb) : - userCallback(cb), + CallbackData(const std::function<void (const Zstring& currentItem)>& notifyDeletionStatus) : + notifyDeletionStatus_(notifyDeletionStatus), exceptionInUserCallback(false) {} - CallbackRecycling* const userCallback; //optional! + const std::function<void (const Zstring& currentItem)>& notifyDeletionStatus_; //optional! bool exceptionInUserCallback; }; + bool recyclerCallback(const wchar_t* filename, void* sink) { CallbackData& cbd = *static_cast<CallbackData*>(sink); //sink is NOT optional here - if (cbd.userCallback) + if (cbd.notifyDeletionStatus_) try { - cbd.userCallback->updateStatus(filename); //throw ? + cbd.notifyDeletionStatus_(filename); //throw ? } catch (...) { @@ -75,7 +76,7 @@ bool recyclerCallback(const wchar_t* filename, void* sink) } } -void zen::recycleOrDelete(const std::vector<Zstring>& filenames, CallbackRecycling* callback) +void zen::recycleOrDelete(const std::vector<Zstring>& filenames, const std::function<void (const Zstring& currentItem)>& notifyDeletionStatus) { if (filenames.empty()) return; @@ -95,14 +96,20 @@ void zen::recycleOrDelete(const std::vector<Zstring>& filenames, CallbackRecycli replaceCpy(_("Cannot load file %x."), L"%x", fmtFileName(getDllName()))); std::vector<const wchar_t*> cNames; - for (auto it = filenames.begin(); it != filenames.end(); ++it) //CAUTION: to not create temporary strings here!! + for (auto it = filenames.begin(); it != filenames.end(); ++it) //CAUTION: do not create temporary strings here!! cNames.push_back(it->c_str()); - CallbackData cbd(callback); + CallbackData cbd(notifyDeletionStatus); if (!moveToRecycler(&cNames[0], cNames.size(), recyclerCallback, &cbd)) { - if (cbd.exceptionInUserCallback) //now we may throw... - callback->updateStatus(Zstring()); //should throw again! + if (cbd.exceptionInUserCallback) + try + { + assert(notifyDeletionStatus); + notifyDeletionStatus(Zstring()); //should throw again!!! + assert(false); + } + catch (...) { throw; } std::wstring filenameFmt = fmtFileName(filenames[0]); //probably not the correct file name for file lists larger than 1! if (filenames.size() > 1) diff --git a/zen/recycler.h b/zen/recycler.h index f55971ac..80b31160 100644 --- a/zen/recycler.h +++ b/zen/recycler.h @@ -7,6 +7,7 @@ #ifndef RECYCLER_H_INCLUDED #define RECYCLER_H_INCLUDED +#include <functional> #include <vector> #include <zen/file_error.h> #include <zen/zstring.h> @@ -44,16 +45,9 @@ enum StatusRecycler StatusRecycler recycleBinStatus(const Zstring& pathName); //test existence of Recycle Bin API for certain path //Win: blocks heavily if recycle bin is really full and drive is slow!!! -struct CallbackRecycling -{ - virtual ~CallbackRecycling() {} - - //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) = 0; //currentItem may be empty -}; - void recycleOrDelete(const std::vector<Zstring>& filenames, //throw FileError, return "true" if file/dir was actually deleted - CallbackRecycling* callback); //optional + //may throw: first exception is swallowed, updateStatus() is then called again where it should throw again and the exception will propagate as expected + const std::function<void (const Zstring& currentItem)>& notifyDeletionStatus); //optional; currentItem may be empty #endif } diff --git a/zen/scope_guard.h b/zen/scope_guard.h index 000853fd..d48eb922 100644 --- a/zen/scope_guard.h +++ b/zen/scope_guard.h @@ -1,6 +1,6 @@ // ************************************************************************** -// * This file is part of the zen::Xml project. It is distributed under the * -// * Boost Software License: http://www.boost.org/LICENSE_1_0.txt * +// * 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 * // ************************************************************************** diff --git a/zen/stl_tools.h b/zen/stl_tools.h index bf47bb1c..2bb4fd3f 100644 --- a/zen/stl_tools.h +++ b/zen/stl_tools.h @@ -1,6 +1,6 @@ // ************************************************************************** -// * This file is part of the zen::Xml project. It is distributed under the * -// * Boost Software License: http://www.boost.org/LICENSE_1_0.txt * +// * 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 * // ************************************************************************** diff --git a/zen/string_base.h b/zen/string_base.h index 31a09e63..c828b240 100644 --- a/zen/string_base.h +++ b/zen/string_base.h @@ -60,7 +60,7 @@ template <typename Char, //Character Type */ template <class Char, //Character Type - class AP> //Allocator Policy + class AP> //Allocator Policy class StorageDeepCopy : public AP { protected: @@ -113,7 +113,7 @@ private: template <class Char, //Character Type - class AP> //Allocator Policy + class AP> //Allocator Policy class StorageRefCountThreadSafe : public AP { protected: @@ -188,8 +188,8 @@ private: //perf note: interestingly StorageDeepCopy and StorageRefCountThreadSafe show same performance in FFS comparison template <class Char, //Character Type - template <class, class> class SP = StorageRefCountThreadSafe, //Storage Policy - class AP = AllocatorOptimalSpeed> //Allocator Policy + template <class, class> class SP = StorageRefCountThreadSafe, //Storage Policy + class AP = AllocatorOptimalSpeed> //Allocator Policy class Zbase : public SP<Char, AP> { public: diff --git a/zen/string_tools.h b/zen/string_tools.h index 35e5af2b..1dd5905d 100644 --- a/zen/string_tools.h +++ b/zen/string_tools.h @@ -1,6 +1,6 @@ // ************************************************************************** -// * This file is part of the zen::Xml project. It is distributed under the * -// * Boost Software License: http://www.boost.org/LICENSE_1_0.txt * +// * 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 * // ************************************************************************** diff --git a/zen/string_traits.h b/zen/string_traits.h index eb79831e..887752c0 100644 --- a/zen/string_traits.h +++ b/zen/string_traits.h @@ -1,6 +1,6 @@ // ************************************************************************** -// * This file is part of the zen::Xml project. It is distributed under the * -// * Boost Software License: http://www.boost.org/LICENSE_1_0.txt * +// * 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 * // ************************************************************************** diff --git a/zen/type_tools.h b/zen/type_tools.h index 76a12a5a..1f782a2d 100644 --- a/zen/type_tools.h +++ b/zen/type_tools.h @@ -1,6 +1,6 @@ // ************************************************************************** -// * This file is part of the zen::Xml project. It is distributed under the * -// * Boost Software License: http://www.boost.org/LICENSE_1_0.txt * +// * 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 * // ************************************************************************** diff --git a/zen/type_traits.h b/zen/type_traits.h index a90b9793..b6e05871 100644 --- a/zen/type_traits.h +++ b/zen/type_traits.h @@ -1,6 +1,6 @@ // ************************************************************************** -// * This file is part of the zen::Xml project. It is distributed under the * -// * Boost Software License: http://www.boost.org/LICENSE_1_0.txt * +// * 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 * // ************************************************************************** @@ -1,6 +1,6 @@ // ************************************************************************** -// * This file is part of the zen::Xml project. It is distributed under the * -// * Boost Software License: http://www.boost.org/LICENSE_1_0.txt * +// * 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 * // ************************************************************************** diff --git a/zenXml/Changelog.txt b/zenXml/Changelog.txt index 8fb65daa..5f54e062 100644 --- a/zenXml/Changelog.txt +++ b/zenXml/Changelog.txt @@ -4,11 +4,13 @@ zen::Xml 2.0 ------------ +zen library update Skip XML comments while parsing Added move constructor for XmlDoc zen::parse and zen::load directly return XmlDoc New macros to specify platform: ZEN_WIN, ZEN_LINUX, ZEN_MAC Support serializing all integer limits (INT_MIN, INT_MAX, ect.) +Moved license from Boost Software License 1.0 to GPL v3 zen::Xml 1.9 diff --git a/zenXml/License.txt b/zenXml/License.txt new file mode 100644 index 00000000..94a04532 --- /dev/null +++ b/zenXml/License.txt @@ -0,0 +1,621 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS diff --git a/zenxml/LICENSE_1_0.txt b/zenxml/LICENSE_1_0.txt deleted file mode 100644 index 36b7cd93..00000000 --- a/zenxml/LICENSE_1_0.txt +++ /dev/null @@ -1,23 +0,0 @@ -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/zenxml/zenxml/bind.h b/zenxml/zenxml/bind.h index abeff452..e66d841b 100644 --- a/zenxml/zenxml/bind.h +++ b/zenxml/zenxml/bind.h @@ -1,6 +1,6 @@ // ************************************************************************** -// * This file is part of the zen::Xml project. It is distributed under the * -// * Boost Software License: http://www.boost.org/LICENSE_1_0.txt * +// * 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 * // ************************************************************************** diff --git a/zenxml/zenxml/cvrt_struc.h b/zenxml/zenxml/cvrt_struc.h index 690edacb..ceb4297d 100644 --- a/zenxml/zenxml/cvrt_struc.h +++ b/zenxml/zenxml/cvrt_struc.h @@ -1,6 +1,6 @@ // ************************************************************************** -// * This file is part of the zen::Xml project. It is distributed under the * -// * Boost Software License: http://www.boost.org/LICENSE_1_0.txt * +// * 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 * // ************************************************************************** diff --git a/zenxml/zenxml/cvrt_text.h b/zenxml/zenxml/cvrt_text.h index 80664317..43272d48 100644 --- a/zenxml/zenxml/cvrt_text.h +++ b/zenxml/zenxml/cvrt_text.h @@ -1,6 +1,6 @@ // ************************************************************************** -// * This file is part of the zen::Xml project. It is distributed under the * -// * Boost Software License: http://www.boost.org/LICENSE_1_0.txt * +// * 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 * // ************************************************************************** diff --git a/zenxml/zenxml/dom.h b/zenxml/zenxml/dom.h index a2ed78f7..cb5e5aab 100644 --- a/zenxml/zenxml/dom.h +++ b/zenxml/zenxml/dom.h @@ -1,6 +1,6 @@ // ************************************************************************** -// * This file is part of the zen::Xml project. It is distributed under the * -// * Boost Software License: http://www.boost.org/LICENSE_1_0.txt * +// * 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 * // ************************************************************************** @@ -124,8 +124,8 @@ public: } template < class IterTy, //underlying iterator type - class T, //target object type - class AccessPolicy > //access policy: see AccessPtrMap + class T, //target object type + class AccessPolicy > //access policy: see AccessPtrMap class PtrIter : public std::iterator<std::input_iterator_tag, T>, private AccessPolicy //get rid of shared_ptr indirection { public: diff --git a/zenxml/zenxml/error.h b/zenxml/zenxml/error.h index bea04520..645f24f7 100644 --- a/zenxml/zenxml/error.h +++ b/zenxml/zenxml/error.h @@ -1,6 +1,6 @@ // ************************************************************************** -// * This file is part of the zen::Xml project. It is distributed under the * -// * Boost Software License: http://www.boost.org/LICENSE_1_0.txt * +// * 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 * // ************************************************************************** diff --git a/zenxml/zenxml/io.h b/zenxml/zenxml/io.h index 596d7acf..09bb7358 100644 --- a/zenxml/zenxml/io.h +++ b/zenxml/zenxml/io.h @@ -1,6 +1,6 @@ // ************************************************************************** -// * This file is part of the zen::Xml project. It is distributed under the * -// * Boost Software License: http://www.boost.org/LICENSE_1_0.txt * +// * 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 * // ************************************************************************** diff --git a/zenxml/zenxml/parser.h b/zenxml/zenxml/parser.h index 51779852..19d36ed5 100644 --- a/zenxml/zenxml/parser.h +++ b/zenxml/zenxml/parser.h @@ -1,6 +1,6 @@ // ************************************************************************** -// * This file is part of the zen::Xml project. It is distributed under the * -// * Boost Software License: http://www.boost.org/LICENSE_1_0.txt * +// * 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 * // ************************************************************************** diff --git a/zenxml/zenxml/unit_test.cpp b/zenxml/zenxml/unit_test.cpp index 8f49de6f..084e764b 100644 --- a/zenxml/zenxml/unit_test.cpp +++ b/zenxml/zenxml/unit_test.cpp @@ -1,6 +1,6 @@ // ************************************************************************** -// * This file is part of the zen::Xml project. It is distributed under the * -// * Boost Software License: http://www.boost.org/LICENSE_1_0.txt * +// * 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 * // ************************************************************************** diff --git a/zenxml/zenxml/xml.h b/zenxml/zenxml/xml.h index 3a01b1a1..411593e7 100644 --- a/zenxml/zenxml/xml.h +++ b/zenxml/zenxml/xml.h @@ -1,6 +1,6 @@ // ************************************************************************** -// * This file is part of the zen::Xml project. It is distributed under the * -// * Boost Software License: http://www.boost.org/LICENSE_1_0.txt * +// * 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 * // ************************************************************************** |