diff options
127 files changed, 6874 insertions, 2393 deletions
diff --git a/Application.cpp b/Application.cpp index e579c1c7..04b687b8 100644 --- a/Application.cpp +++ b/Application.cpp @@ -20,6 +20,9 @@ #include "shared/standardPaths.h" #include "shared/localization.h" #include "shared/appMain.h" +#include <wx/sound.h> +#include "shared/fileHandling.h" +#include "shared/stringConv.h" #ifdef FFS_LINUX #include <gtk/gtk.h> @@ -70,6 +73,15 @@ void Application::OnStartApplication(wxIdleEvent&) ::gtk_rc_parse("styles.rc"); //remove inner border from bitmap buttons #endif + //initialize help controller + helpController.reset(new wxHelpController); + helpController->Initialize(FreeFileSync::getInstallationDir() + +#ifdef FFS_WIN + wxT("FreeFileSync.chm")); +#elif defined FFS_LINUX + wxT("Help/FreeFileSync.hhp")); +#endif + //test if FFS is to be started on UI with config file passed as commandline parameter //try to set config/batch-filename set by %1 parameter @@ -180,13 +192,16 @@ int Application::OnExit() wxMessageBox(error.show(), _("Error"), wxOK | wxICON_ERROR); } + //delete help provider: "Cross-Platform GUI Programming with wxWidgets" says this should be done here... + helpController.reset(); + return 0; } void Application::runGuiMode(const wxString& cfgFileName, xmlAccess::XmlGlobalSettings& settings) { - MainDialog* frame = new MainDialog(NULL, cfgFileName, settings); + MainDialog* frame = new MainDialog(NULL, cfgFileName, settings, *helpController); frame->SetIcon(*GlobalResources::getInstance().programIcon); //set application icon frame->Show(); @@ -251,12 +266,18 @@ void Application::runBatchMode(const wxString& filename, xmlAccess::XmlGlobalSet batchCfg.mainCfg.hidden.traverseDirectorySymlinks, globSettings.optDialogs, batchCfg.mainCfg.hidden.verifyFileCopy, + globSettings.copyLockedFiles, *statusHandler); const std::vector<FreeFileSync::FolderPairSyncCfg> syncProcessCfg = FreeFileSync::extractSyncCfg(batchCfg.mainCfg); assert(syncProcessCfg.size() == folderCmp.size()); synchronization.startSynchronizationProcess(syncProcessCfg, folderCmp); + + //play (optional) sound notification after sync has completed (GUI and batch mode) + const wxString soundFile = FreeFileSync::getInstallationDir() + wxT("Sync_Complete.wav"); + if (FreeFileSync::fileExists(FreeFileSync::wxToZ(soundFile))) + wxSound::Play(soundFile, wxSOUND_ASYNC); } catch (FreeFileSync::AbortThisProcess&) //exit used by statusHandler { diff --git a/Application.h b/Application.h index 55d6e02d..8d5a0fcf 100644 --- a/Application.h +++ b/Application.h @@ -10,6 +10,7 @@ #include <wx/app.h> #include "library/processXml.h" +#include <wx/help.h> class Application : public wxApp @@ -27,6 +28,7 @@ private: xmlAccess::XmlGlobalSettings globalSettings; //settings used by GUI, batch mode or both + boost::shared_ptr<wxHelpController> helpController; //global help controller int returnValue; }; diff --git a/BUILD/Changelog.txt b/BUILD/Changelog.txt index 25e4e56b..efd4697e 100644 --- a/BUILD/Changelog.txt +++ b/BUILD/Changelog.txt @@ -2,6 +2,27 @@ |FreeFileSync| -------------- +Changelog v3.2 +-------------- +Native Windows 64-Bit version (including Volume Shadow Copy Service) +Harmonized filter handling: global and local file filters +Unified handling of first folder pair: all pairs now semantically equal +Use environment variables within directory names (e.g. %USERNAME%) +New keyboard shortcuts to set sync-direction: ALT + <arrow key> +Allow copying to non-encrypted target directory +Fixed sort by filename +Fixed GDI resource leak when scrolling large grids +Fixed string comparison for 'ß' and 'ss' (Windows >= Vista) +Faster file icon loading +Remove elements in folder dropdown list via DEL key +New integrated help file +Play optional sound after synchronization: "Sync_Complete.wav" +Several GUI/usability improvements +Created package for PortableApps.com +Added Finnish translation +Updated translation files + + Changelog v3.1 -------------- Support for multiple datasources in Automatic mode @@ -385,7 +406,7 @@ New function to delete files (or move them to recycle bin) manually on the UI (w while catching error situations and allowing to resolve them Improved manual filtering of rows: If folders are marked all dependent subfolders and files are marked as well (keeping sort sequence when "hide filtered elements" is marked) -Comprehensive performance optimization of the two features above (manual filtering, deletion) for large grids (> 200.000 rows) +Comprehensive performance optimization of the two features above (manual filtering, deletion) for large grids (> 200,000 rows) Improved usability: resizable borders, keyboard shortcuts, default buttons, dialog standard focus Main window will remember restored position even if maximized Updated sources to become more Linux and Unicode friendly diff --git a/BUILD/FreeFileSync.chm b/BUILD/FreeFileSync.chm Binary files differnew file mode 100644 index 00000000..3cf06742 --- /dev/null +++ b/BUILD/FreeFileSync.chm diff --git a/BUILD/Help/FreeFileSync.hhp b/BUILD/Help/FreeFileSync.hhp new file mode 100644 index 00000000..a59f966c --- /dev/null +++ b/BUILD/Help/FreeFileSync.hhp @@ -0,0 +1,32 @@ +[OPTIONS] +Compatibility=1.1 or later +Compiled file=..\FreeFileSync.chm +Contents file=Table of Contents.hhc +Default topic=html\Overview.html +Display compile progress=No +Full-text search=Yes +Language=0x409 Englisch (USA) +Title=FreeFileSync - Help + + +[FILES] +html\Features.html +html\Links.html +html\advanced\CompareFileSize.html +html\advanced\DragDrop.html +html\advanced\ExcludeSubfolder.html +html\advanced\ExternalApp.html +html\advanced\Ftp.html +html\advanced\ScheduleBatch.html +html\advanced\SendMail.html +html\advanced\SymbolicLinks.html +html\advanced\TimeStamped.html +html\advanced\VariableDrive.html +html\Overview.html +html\advanced\DaylightSavingTime.html +html\advanced\EnvironmentVariables.html +html\advanced\RealtimeSync.html +html\advanced\ShadowCopy.html + +[INFOTYPES] + diff --git a/BUILD/Help/Table of Contents.hhc b/BUILD/Help/Table of Contents.hhc new file mode 100644 index 00000000..01f73ef5 --- /dev/null +++ b/BUILD/Help/Table of Contents.hhc @@ -0,0 +1,89 @@ +<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> +<HTML> +<HEAD> +<meta name="GENERATOR" content="Microsoft® HTML Help Workshop 4.1"> +<!-- Sitemap 1.0 --> +</HEAD><BODY> +<OBJECT type="text/site properties"> + <param name="Window Styles" value="0x800025"> + <param name="ImageType" value="Folder"> +</OBJECT> +<UL> + <LI> <OBJECT type="text/sitemap"> + <param name="Name" value="Overview"> + <param name="Local" value="html\Overview.html"> + <param name="ImageNumber" value="17"> + </OBJECT> + <LI> <OBJECT type="text/sitemap"> + <param name="Name" value="Features"> + <param name="Local" value="html\Features.html"> + <param name="ImageNumber" value="11"> + </OBJECT> + <LI> <OBJECT type="text/sitemap"> + <param name="Name" value="Links"> + <param name="Local" value="html\Links.html"> + <param name="ImageNumber" value="19"> + </OBJECT> + <LI> <OBJECT type="text/sitemap"> + <param name="Name" value="Advanced"> + </OBJECT> + <UL> + <LI> <OBJECT type="text/sitemap"> + <param name="Name" value="Compare by filesize"> + <param name="Local" value="html\advanced\CompareFileSize.html"> + </OBJECT> + <LI> <OBJECT type="text/sitemap"> + <param name="Name" value="Daylight saving time"> + <param name="Local" value="html\advanced\DaylightSavingTime.html"> + </OBJECT> + <LI> <OBJECT type="text/sitemap"> + <param name="Name" value="Drag & drop support"> + <param name="Local" value="html\advanced\DragDrop.html"> + </OBJECT> + <LI> <OBJECT type="text/sitemap"> + <param name="Name" value="Environment Variables"> + <param name="Local" value="html\advanced\EnvironmentVariables.html"> + </OBJECT> + <LI> <OBJECT type="text/sitemap"> + <param name="Name" value="Error notification"> + <param name="Local" value="html\advanced\SendMail.html"> + </OBJECT> + <LI> <OBJECT type="text/sitemap"> + <param name="Name" value="Exclude subfolders"> + <param name="Local" value="html\advanced\ExcludeSubfolder.html"> + </OBJECT> + <LI> <OBJECT type="text/sitemap"> + <param name="Name" value="External applications"> + <param name="Local" value="html\advanced\ExternalApp.html"> + </OBJECT> + <LI> <OBJECT type="text/sitemap"> + <param name="Name" value="RealtimeSync"> + <param name="Local" value="html\advanced\RealtimeSync.html"> + </OBJECT> + <LI> <OBJECT type="text/sitemap"> + <param name="Name" value="Schedule a Batch Job"> + <param name="Local" value="html\advanced\ScheduleBatch.html"> + </OBJECT> + <LI> <OBJECT type="text/sitemap"> + <param name="Name" value="Symbolic link handling"> + <param name="Local" value="html\advanced\SymbolicLinks.html"> + </OBJECT> + <LI> <OBJECT type="text/sitemap"> + <param name="Name" value="Synchronize with FTP"> + <param name="Local" value="html\advanced\Ftp.html"> + </OBJECT> + <LI> <OBJECT type="text/sitemap"> + <param name="Name" value="Time-stamped directories"> + <param name="Local" value="html\advanced\TimeStamped.html"> + </OBJECT> + <LI> <OBJECT type="text/sitemap"> + <param name="Name" value="Variable drive letters"> + <param name="Local" value="html\advanced\VariableDrive.html"> + </OBJECT> + <LI> <OBJECT type="text/sitemap"> + <param name="Name" value="Volume Shadow Copy"> + <param name="Local" value="html\advanced\ShadowCopy.html"> + </OBJECT> + </UL> +</UL> +</BODY></HTML> diff --git a/BUILD/Help/html/Features.html b/BUILD/Help/html/Features.html new file mode 100644 index 00000000..75aea41d --- /dev/null +++ b/BUILD/Help/html/Features.html @@ -0,0 +1,114 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)"> + <META NAME="CREATED" CONTENT="20091206;16574000"> + <META NAME="CHANGED" CONTENT="20091207;23033200"> + <STYLE TYPE="text/css"> + <!-- + @page { margin: 2cm } + P { margin-bottom: 0.21cm } + H3 { margin-bottom: 0.21cm } + H3.western { font-family: "Arial", sans-serif } + H3.cjk { font-family: "MS Mincho" } + A:link { so-language: zxx } + --> + </STYLE> +</HEAD> +<BODY LANG="de-DE" DIR="LTR"> +<H3 CLASS="western"><FONT FACE="Tahoma, sans-serif">Key Features</FONT></H3> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<OL> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Compare + files (bytewise or by date) and synchronize them.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">No + limitations: An arbitrary number of files can be synchronized.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Unicode + support.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Network + support.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Synchronization + database for propagation of deleted files and conflict detection</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Support + for multiple folder pairs with distinct configuration</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Full + support for Windows/Linux Symbolic Links and Windows Junction + Points.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Lean + & easily accessible UI: Highly optimized for speed and huge sets + of data.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Algorithms + coded in C++ completely.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">All + progress indicators optimized for maximum performance!</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Create + Batch Jobs for automated synchronization with or without GUI.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Focus + on usability:</FONT></P> + <OL TYPE=a> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Only + necessary functionality on UI: no overloaded menus or icon jungle.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Select + all folders via drag & drop.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Last + used configuration and screen settings are saved automatically.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Maintain + and load different configurations by drag & drop, load-button + or commandline.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Double-click + to start external application (e.g. show file in Windows Explorer)</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Copy + & paste all grid data as text</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Delete + superfluous/temporary files directly on main grid.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Right-click + context menu.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Status + information and error reporting</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Sort + file-lists by name, size or date.</FONT></P> + </OL> +</OL> +<OL START=14> + <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Support + for filesizes larger than 4 GB.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Option + to move files to Recycle Bin instead of deleting/overwriting them.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Ignore + directories "\RECYCLER" and "\System Volume + Information" with default Filter. (Windows only)</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Localized + versions are available for many languages.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Delete + before copy: Avoid disc space shortages for large sync-jobs.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Filter + functionality to include/exclude files from synchronization (without + requiring a re-compare!).</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Include/exclude + specific files from synchronization temporarily.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Create + sync jobs via GUI to synchronize automatically (can be scheduled or + executed via double-click).</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Handle + daylight saving time changes on FAT/FAT32 volumes correctly.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Portable + version (.zip) available.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Native + 64-Bit version.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Support + for \\?\ path prefix for unrestricted path length. (Windows only)</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Check + for updates from within FreeFileSync automatically.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Copy + locked files using Windows Volume Shadow Copy Service. (Windows + only)</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Create + regular backups with macros %time%, %date% within directory names</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"> <FONT FACE="Tahoma, sans-serif">Copy + file and folder create/access/modification times when synchronizing</FONT></P> +</OL> +</BODY> +</HTML>
\ No newline at end of file diff --git a/BUILD/Help/html/Links.html b/BUILD/Help/html/Links.html new file mode 100644 index 00000000..daca1990 --- /dev/null +++ b/BUILD/Help/html/Links.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)"> + <META NAME="CREATED" CONTENT="20091206;16574000"> + <META NAME="CHANGED" CONTENT="20091207;23063000"> + <STYLE TYPE="text/css"> + <!-- + @page { margin: 2cm } + P { margin-bottom: 0.21cm } + H3 { margin-bottom: 0.21cm } + H3.western { font-family: "Arial", sans-serif } + H3.cjk { font-family: "MS Mincho" } + A:link { so-language: zxx } + --> + </STYLE> +</HEAD> +<BODY LANG="de-DE" DIR="LTR"> +<H3 CLASS="western"><FONT FACE="Tahoma, sans-serif">Links</FONT></H3> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">FreeFileSync +on SourceForge:<BR><A HREF="http://sourceforge.net/projects/freefilesync">http://sourceforge.net/projects/freefilesync</A></FONT></P> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">For +feedback, suggestions or bug-reports you can write an email +to:<BR><A HREF="mailto:zhnmju123@gmx.de">zhnmju123 [at] gmx [dot] de</A></FONT></P> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Or +report directly to:<BR><A HREF="http://sourceforge.net/tracker/?group_id=234430">http://sourceforge.net/tracker/?group_id=234430</A></FONT></P> +</BODY> +</HTML>
\ No newline at end of file diff --git a/BUILD/Help/html/Overview.html b/BUILD/Help/html/Overview.html new file mode 100644 index 00000000..7f9a7aef --- /dev/null +++ b/BUILD/Help/html/Overview.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)"> + <META NAME="CREATED" CONTENT="20091206;16574000"> + <META NAME="CHANGED" CONTENT="20091213;16160300"> + <STYLE TYPE="text/css"> + <!-- + @page { margin: 2cm } + P { margin-bottom: 0.21cm } + H3 { margin-bottom: 0.21cm } + H3.western { font-family: "Arial", sans-serif } + H3.cjk { font-family: "MS Mincho" } + A:link { so-language: zxx } + --> + </STYLE> +</HEAD> +<BODY LANG="de-DE" DIR="LTR"> +<H3 CLASS="western" ALIGN=CENTER><FONT SIZE=4 STYLE="font-size: 16pt">FreeFileSync<BR><FONT SIZE=3><I><SPAN STYLE="font-weight: normal">- +Folder Comparison and Synchronization -</SPAN></I></FONT></FONT></H3> +<H3 CLASS="western" ALIGN=LEFT>Usage:</H3> +<OL> + <LI VALUE=1><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Choose + left and right directories.<BR></FONT><IMG SRC="overview_html_m7391eb10.gif" NAME="Grafik4" ALIGN=TEXTTOP WIDTH=449 HEIGHT=49 BORDER=0></P> + <P STYLE="margin-bottom: 0cm"></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">"</FONT><FONT FACE="Tahoma, sans-serif"><I>Compare</I></FONT><FONT FACE="Tahoma, sans-serif">" + them.<BR></FONT><IMG SRC="overview_html_m67668fb2.gif" NAME="Grafik1" ALIGN=BOTTOM WIDTH=178 HEIGHT=40 BORDER=0></P> + <P STYLE="margin-bottom: 0cm"></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Select + synchronization settings.<BR></FONT><IMG SRC="overview_html_mbb6ab4a.gif" NAME="Grafik3" ALIGN=BOTTOM WIDTH=46 HEIGHT=40 BORDER=0></P> + <P STYLE="margin-bottom: 0cm"></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Press + "</FONT><FONT FACE="Tahoma, sans-serif"><I>Synchronize...</I></FONT><FONT FACE="Tahoma, sans-serif">" + to begin synchronization.<BR></FONT><IMG SRC="overview_html_m11e8dbdc.gif" NAME="Grafik2" ALIGN=BOTTOM WIDTH=198 HEIGHT=40 BORDER=0></P> +</OL> +</BODY> +</HTML>
\ No newline at end of file diff --git a/BUILD/Help/html/advanced/CompareFileSize.html b/BUILD/Help/html/advanced/CompareFileSize.html new file mode 100644 index 00000000..54744b51 --- /dev/null +++ b/BUILD/Help/html/advanced/CompareFileSize.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)"> + <META NAME="CREATED" CONTENT="20091206;16574000"> + <META NAME="CHANGED" CONTENT="20091209;21185800"> + <META NAME="Info 1" CONTENT=""> + <META NAME="Info 2" CONTENT=""> + <META NAME="Info 3" CONTENT=""> + <META NAME="Info 4" CONTENT=""> + <STYLE TYPE="text/css"> + <!-- + @page { margin: 2cm } + P { margin-bottom: 0.21cm } + H3 { margin-bottom: 0.21cm } + H3.western { font-family: "Arial", sans-serif } + H3.cjk { font-family: "MS Mincho" } + A:link { so-language: zxx } + --> + </STYLE> +</HEAD> +<BODY LANG="de-DE" DIR="LTR"> +<H3 CLASS="western"><FONT FACE="Tahoma, sans-serif">Compare by +filesize</FONT></H3> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Sometimes +you might want to compare both sides by filesize only, ignoring last +modification timestamps.</FONT></P> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Instructions:</B></FONT></P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Open +your *.ffs_gui configuration file and change the value of XML node +</FONT><FONT FACE="Courier New, monospace"><FileTimeTolerance></FONT> +<FONT FACE="Tahoma, sans-serif">to some sufficiently large number of +seconds. Changed files will now be detected as a conflict (same date, +different filesize) and the default synchronization direction for +conflics can be used.</FONT></P> +</BODY> +</HTML>
\ No newline at end of file diff --git a/BUILD/Help/html/advanced/DaylightSavingTime.html b/BUILD/Help/html/advanced/DaylightSavingTime.html new file mode 100644 index 00000000..4fffe036 --- /dev/null +++ b/BUILD/Help/html/advanced/DaylightSavingTime.html @@ -0,0 +1,69 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)"> + <META NAME="CREATED" CONTENT="20091208;20054200"> + <META NAME="CHANGED" CONTENT="20091211;18381300"> + <META NAME="Info 1" CONTENT=""> + <META NAME="Info 2" CONTENT=""> + <META NAME="Info 3" CONTENT=""> + <META NAME="Info 4" CONTENT=""> + <STYLE TYPE="text/css"> + <!-- + @page { margin: 2cm } + P { margin-bottom: 0.21cm } + H2 { margin-bottom: 0.21cm } + H2.western { font-family: "Arial", sans-serif; font-size: 14pt; font-style: italic } + H2.cjk { font-family: "MS Mincho"; font-size: 14pt; font-style: italic } + H2.ctl { font-size: 14pt; font-style: italic } + A:link { so-language: zxx } + --> + </STYLE> +</HEAD> +<BODY LANG="de-DE" DIR="LTR"> +<H2 CLASS="western" STYLE="font-style: normal"><FONT FACE="Tahoma, sans-serif">Daylight +saving time</FONT></H2> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">The +Windows operating system exhibits quite a unique behavior when +handling timestamps on NTFS file systems. This leads to a well-known +issue that all file synchronization software has to handle:</FONT></P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">During +daylight saving time switching, (local) file times are shifted by one +hour on NTFS file systems, while NO shift occurs on FAT/FAT32 drives +(as used by most USB sticks)! Thus when synchronizing an NTFS against +a FAT32 volume file times become asynchronous twice a year!</FONT></P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">For a +comprehensive discussion about this issue refer +to:<BR><A HREF="http://www.codeproject.com/KB/datetime/dstbugs.aspx">http://www.codeproject.com/KB/datetime/dstbugs.aspx</A></FONT></P> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Solution:</B></FONT></P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">In +order to avoid re-copying files that have a modification time +difference of +-1h FreeFileSync offers a global option: <I>Menu -> +Advanced -> Global settings: Ignore 1-hour file time difference</I>.</FONT></P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">If +"<I>Ignore 1-hour file time difference</I>" is checked, all +files with a +-1h difference are treated as having the same time. +This also handles different file time precisions (NTFS: 100ns, +FAT/FAT32: 2 seconds) by allowing a 2 second tolerance .</FONT></P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Files +that have a deviation of less than one hour are categorized as +conflicts. The reasoning is that these files surely have been +modified on at least one side since last synchronization. But during +one of the two daylight saving time switches per year the older file +is shown pretending a newer date which can lead to data loss (when +using the rule to overwrite older with newer files).</FONT></P> +<P STYLE="margin-left: 1.46cm; margin-bottom: 0cm"><SPAN ID="Rahmen1" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: 1px solid #000080; padding: 0.05cm; background: #ccccff"> + <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-right: 0.98cm; margin-bottom: 0cm"> + <FONT FACE="Tahoma, sans-serif"><B>Note:</B><BR>If synchronization + takes place between NTFS ↔ NTFS or FAT32 ↔ FAT32 this + checkbox provides no advantage and can be left unchecked.</FONT></P> +</SPAN><BR CLEAR=LEFT><BR> +</P> +</BODY> +</HTML>
\ No newline at end of file diff --git a/BUILD/Help/html/advanced/DragDrop.html b/BUILD/Help/html/advanced/DragDrop.html new file mode 100644 index 00000000..e9e580ca --- /dev/null +++ b/BUILD/Help/html/advanced/DragDrop.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)"> + <META NAME="CREATED" CONTENT="20091206;16574000"> + <META NAME="CHANGED" CONTENT="20091209;21062300"> + <STYLE TYPE="text/css"> + <!-- + @page { margin: 2cm } + P { margin-bottom: 0.21cm } + H3 { margin-bottom: 0.21cm } + H3.western { font-family: "Arial", sans-serif } + H3.cjk { font-family: "MS Mincho" } + A:link { so-language: zxx } + --> + </STYLE> +</HEAD> +<BODY LANG="de-DE" DIR="LTR"> +<H3 CLASS="western"><FONT FACE="Tahoma, sans-serif">Drag & drop +support</FONT></H3> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">FreeFileSync +takes usability very seriously. Therefore drag & drop is +supported in various situations:</FONT></P> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Example:</B></FONT></P> +<UL> + <UL> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">drag + & drop a directory onto the main window to set the directory + for comparison</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">drag + & drop a file onto the main window to set the directory for + comparison</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">drag + & drop *.ffs_gui files onto the main window to load the + configuration contained</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">drag + & drop *.ffs_batch files onto the main window to display and + edit the batch configuration</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">drag + & drop *.ffs_batch files onto the batch dialog to display and + edit the batch configuration</FONT></P> + </UL> +</UL> +</BODY> +</HTML>
\ No newline at end of file diff --git a/BUILD/Help/html/advanced/EnvironmentVariables.html b/BUILD/Help/html/advanced/EnvironmentVariables.html new file mode 100644 index 00000000..2d4f6069 --- /dev/null +++ b/BUILD/Help/html/advanced/EnvironmentVariables.html @@ -0,0 +1,93 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)"> + <META NAME="CREATED" CONTENT="20091206;16574000"> + <META NAME="CHANGED" CONTENT="20091213;15581900"> + <META NAME="Info 1" CONTENT=""> + <META NAME="Info 2" CONTENT=""> + <META NAME="Info 3" CONTENT=""> + <META NAME="Info 4" CONTENT=""> + <STYLE TYPE="text/css"> + <!-- + @page { margin: 2cm } + P { margin-bottom: 0.21cm } + H3 { margin-bottom: 0.21cm } + H3.western { font-family: "Arial", sans-serif } + H3.cjk { font-family: "MS Mincho" } + A:link { so-language: zxx } + --> + </STYLE> +</HEAD> +<BODY LANG="de-DE" DIR="LTR"> +<H3 CLASS="western"><FONT FACE="Tahoma, sans-serif">Environment +Variables</FONT></H3> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">All +directory names may contain macros that are expanded during +synchronization. Begin and end of each macro is marked by a '%' +character. Besides special macros handling time and date (see +"Time-stamped directories"), the operating system's +environment variables can also be used.</FONT></P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Example:</B></FONT></P> +<UL> + <P STYLE="margin-bottom: 0cm"><SPAN ID="Rahmen1" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: none; padding: 0cm; background: #e6e6e6"> + <UL> + <LI><P ALIGN=LEFT STYLE="margin-right: 0.98cm; margin-bottom: 0cm"> + <FONT FACE="Tahoma, sans-serif"><FONT FACE="Courier New, monospace">C:\Backup\%USERNAME%_Config </FONT>expands + to<FONT FACE="Courier New, monospace"><BR>C:\Backup\ZenJu_Config</FONT></FONT></P> + <LI><P ALIGN=LEFT STYLE="margin-right: 0.98cm; margin-bottom: 0cm"> + <FONT FACE="Tahoma, sans-serif"><FONT FACE="Courier New, monospace">%USERPROFILE%\Application + Data\FreeFileSync </FONT>expands to<FONT FACE="Courier New, monospace"><BR>C:\Documents + and Settings\ZenJu\Application Data\FreeFileSync</FONT></FONT></P> + </UL> + </SPAN><BR CLEAR=LEFT> + </P> +</UL> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Hint:</B></FONT></P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">You can +add a great amount of flexibility to Batch Synchronization +(*.ffs_batch) by creating new temporary environment variables in a +*.bat/*.cmd file that are evaluated by FreeFileSync at runtime!</FONT></P> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Example:</B></FONT></P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">The +batch configuration file <FONT FACE="Courier New, monospace">C:\SyncJob.ffs_batch +</FONT>contains macro <FONT FACE="Courier New, monospace">%MyVar% +</FONT>instead of an absolute target directory and is invoked by a +*.cmd file:</FONT></P> +<UL> + <P STYLE="margin-bottom: 0cm"><SPAN ID="Rahmen2" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: none; padding: 0cm; background: #e6e6e6"> + <UL> + <P ALIGN=LEFT STYLE="margin-right: 0.98cm; margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><FONT FACE="Courier New, monospace">set + MyVar=C:\Target<BR>cd "C:\Program + files\FreeFileSync"<BR>FreeFileSync.exe C:\SyncJob.ffs_batch + </FONT>(-><FONT FACE="Courier New, monospace">%MyVar% </FONT>is + replaced with <FONT FACE="Courier New, monospace">C:\Target </FONT>during + execution)</FONT></P> + </UL> + </SPAN><BR CLEAR=LEFT> + </P> +</UL> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<UL> + <P STYLE="margin-bottom: 0cm"><SPAN ID="Rahmen3" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: 1px solid #000080; padding: 0.05cm; background: #ccccff"> + <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-right: 0.98cm; margin-bottom: 0cm"> + <FONT FACE="Tahoma, sans-serif"><B>Note:</B><BR>Temporary + environment variables created with the "<FONT FACE="Courier New, monospace">set</FONT>" + command are only valid if the batch job is started by calling the + executable directly! Using "<FONT FACE="Courier New, monospace">start + /wait</FONT>" or relying on Shell Execute creates a new + program context without these temporal variables.</FONT></P> + </SPAN><BR CLEAR=LEFT> + </P> +</UL> +</BODY> +</HTML>
\ No newline at end of file diff --git a/BUILD/Help/html/advanced/ExcludeSubfolder.html b/BUILD/Help/html/advanced/ExcludeSubfolder.html new file mode 100644 index 00000000..550ba633 --- /dev/null +++ b/BUILD/Help/html/advanced/ExcludeSubfolder.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)"> + <META NAME="CREATED" CONTENT="20091206;16574000"> + <META NAME="CHANGED" CONTENT="20091209;20394400"> + <META NAME="Info 1" CONTENT=""> + <META NAME="Info 2" CONTENT=""> + <META NAME="Info 3" CONTENT=""> + <META NAME="Info 4" CONTENT=""> + <STYLE TYPE="text/css"> + <!-- + @page { margin: 2cm } + P { margin-bottom: 0.21cm } + H3 { margin-bottom: 0.21cm } + H3.western { font-family: "Arial", sans-serif } + H3.cjk { font-family: "MS Mincho" } + A:link { so-language: zxx } + --> + </STYLE> +</HEAD> +<BODY LANG="de-DE" DIR="LTR"> +<H3 CLASS="western"><FONT FACE="Tahoma, sans-serif">Exclude +subfolders from synchronization</FONT></H3> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">In +order to synchronize all files from base synchronization directories +excluding all subfolders, simply set up a filter like this:</FONT></P> +<P STYLE="margin-left: 1.46cm; margin-bottom: 0cm"><SPAN ID="Rahmen1" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: none; padding: 0cm; background: #e6e6e6"> + <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-right: 0.98cm; margin-bottom: 0cm"> + <FONT FACE="Tahoma, sans-serif">Include: <FONT FACE="Courier New, monospace">*</FONT><BR>Exclude: + <FONT FACE="Courier New, monospace">*\</FONT></FONT></P> +</SPAN><BR CLEAR=LEFT><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">This +will exclude all objects within the two directories that end with a +'<FONT FACE="Courier New, monospace">\</FONT>' character, which is +interpreted as the end of a directory name.</FONT></P> +</BODY> +</HTML>
\ No newline at end of file diff --git a/BUILD/Help/html/advanced/ExternalApp.html b/BUILD/Help/html/advanced/ExternalApp.html new file mode 100644 index 00000000..3994c96e --- /dev/null +++ b/BUILD/Help/html/advanced/ExternalApp.html @@ -0,0 +1,70 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)"> + <META NAME="CREATED" CONTENT="20091206;16574000"> + <META NAME="CHANGED" CONTENT="20091212;16500300"> + <META NAME="Info 1" CONTENT=""> + <META NAME="Info 2" CONTENT=""> + <META NAME="Info 3" CONTENT=""> + <META NAME="Info 4" CONTENT=""> + <STYLE TYPE="text/css"> + <!-- + @page { margin: 2cm } + P { margin-bottom: 0.21cm } + H3 { margin-bottom: 0.21cm } + H3.western { font-family: "Arial", sans-serif } + H3.cjk { font-family: "MS Mincho" } + A:link { so-language: zxx } + --> + </STYLE> +</HEAD> +<BODY LANG="de-DE" DIR="LTR"> +<H3 CLASS="western"><FONT FACE="Tahoma, sans-serif">Start an external +application via double-click</FONT></H3> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">FreeFileSync +opens the operating system's standard file browser per default on +each double-click e.g. by invoking "<FONT FACE="Courier New, monospace">explorer +/select, %name</FONT>" on Windows.</FONT></P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">If some +other application shall be started instead, just navigate to "</FONT><FONT FACE="Tahoma, sans-serif"><I>Menu +-> Advanced -> Global settings: External Applications</I></FONT><FONT FACE="Tahoma, sans-serif">" +and add or replace a command string. The first one is used when +double-clicking while all subsequent entries are still available in +right-click context menu on main dialog. The following macros are +available:</FONT></P> +<UL> + <P><SPAN ID="Rahmen2" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: none; padding: 0cm; background: #e6e6e6"> + <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-right: 0.98cm; margin-bottom: 0cm"> + <FONT FACE="Courier New, monospace">%name - full + file or directory name<BR>%dir - directory part + only<BR>%nameCo - Other side's counterpart to %name<BR>%dirCo - + Other side's counterpart to %dir</FONT></P> + </SPAN><BR CLEAR=LEFT> + </P> +</UL> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Example:</B></FONT></P> +<UL> + <UL> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Start + associated application: <FONT FACE="Courier New, monospace">cmd /c + start "" "%name"</FONT></FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Start + visual difference tool: <FONT FACE="Courier New, monospace">C:\Program + Files\WinMerge\WinMergeU.exe "%name" "%nameCo"</FONT></FONT></P> + </UL> +</UL> +<P STYLE="margin-left: 1.46cm; margin-bottom: 0cm"><SPAN ID="Rahmen1" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: 1px solid #000080; padding: 0.05cm; background: #ccccff"> + <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-right: 0.98cm; margin-bottom: 0cm"> + <FONT FACE="Tahoma, sans-serif"><B>Note:</B><BR>Don't forget to use + quotation marks if file names contain spaces!</FONT></P> +</SPAN><BR CLEAR=LEFT><BR> +</P> +</BODY> +</HTML>
\ No newline at end of file diff --git a/BUILD/Help/html/advanced/Ftp.html b/BUILD/Help/html/advanced/Ftp.html new file mode 100644 index 00000000..b55301be --- /dev/null +++ b/BUILD/Help/html/advanced/Ftp.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)"> + <META NAME="CREATED" CONTENT="20091206;16574000"> + <META NAME="CHANGED" CONTENT="20091209;21053000"> + <META NAME="Info 1" CONTENT=""> + <META NAME="Info 2" CONTENT=""> + <META NAME="Info 3" CONTENT=""> + <META NAME="Info 4" CONTENT=""> + <STYLE TYPE="text/css"> + <!-- + @page { margin: 2cm } + P { margin-bottom: 0.21cm } + H3 { margin-bottom: 0.21cm } + H3.western { font-family: "Arial", sans-serif } + H3.cjk { font-family: "MS Mincho" } + A:link { so-language: zxx } + --> + </STYLE> +</HEAD> +<BODY LANG="de-DE" DIR="LTR"> +<H3 CLASS="western"><FONT FACE="Tahoma, sans-serif">Synchronize with +FTP</FONT></H3> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">FreeFileSync +does not support FTP directly. But the FTP functionality can be +easily integrated by mapping the FTP webspace to a drive letter:</FONT></P> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Example:</B></FONT><FONT FACE="Tahoma, sans-serif"> +Use the free utility NetDrive (<A HREF="http://www.netdrive.net/">http://www.netdrive.net</A>)</FONT></P> +<UL> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Add + a "<I>New Site</I>" and specify site name, site URL, drive + letter, account and password.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Use + the newly created drive as if it were a regular hard disk.</FONT></P> +</UL> +<P STYLE="margin-left: 1.46cm; margin-bottom: 0cm"><SPAN ID="Rahmen1" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: 1px solid #000080; padding: 0.05cm; background: #ccccff"> + <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-right: 0.98cm; margin-bottom: 0cm"> + <FONT FACE="Tahoma, sans-serif"><B>Note:</B><BR>Most FTP drives set + a file's timestamp to the current time when synchronizing ignoring + the source file's time and date. As a workaround you can do a + "<I>compare by filesize</I>"; see corresponding section.</FONT></P> +</SPAN><BR CLEAR=LEFT><BR> +</P> +</BODY> +</HTML>
\ No newline at end of file diff --git a/BUILD/Help/html/advanced/RealtimeSync.html b/BUILD/Help/html/advanced/RealtimeSync.html new file mode 100644 index 00000000..7eac013c --- /dev/null +++ b/BUILD/Help/html/advanced/RealtimeSync.html @@ -0,0 +1,84 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)"> + <META NAME="CREATED" CONTENT="20091206;16574000"> + <META NAME="CHANGED" CONTENT="20091213;16073500"> + <META NAME="Info 1" CONTENT=""> + <META NAME="Info 2" CONTENT=""> + <META NAME="Info 3" CONTENT=""> + <META NAME="Info 4" CONTENT=""> + <STYLE TYPE="text/css"> + <!-- + @page { margin: 2cm } + P { margin-bottom: 0.21cm } + H3 { margin-bottom: 0.21cm } + H3.western { font-family: "Arial", sans-serif } + H3.cjk { font-family: "MS Mincho" } + A:link { so-language: zxx } + --> + </STYLE> +</HEAD> +<BODY LANG="de-DE" DIR="LTR"> +<H3 CLASS="western"><FONT FACE="Tahoma, sans-serif">RealtimeSync</FONT></H3> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">RealtimeSync's +primary function is to trigger synchronization immediately after +files in a source directory have changed. However its implementation +is much more flexible to cover an even broader range of use: A list +of directories provided by the user is monitored for changes. +Whenever a file or a subdirectory is modified, RealtimeSync responds +by executing the user-specified commandline.</FONT></P> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Example:</B></FONT> +<FONT FACE="Tahoma, sans-serif">(Real time synchronization - in +combination with FreeFileSync)</FONT></P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">First +specify all directories that shall be monitored. Instead of doing +this manually you can simply import a *.ffs_batch file via </FONT><FONT FACE="Tahoma, sans-serif"><I>Menu +-> File -> Load configuration</I></FONT><FONT FACE="Tahoma, sans-serif">. +This not only extracts all directories relevant for synchronization +but also sets up the commandline to execute the *.ffs_batch file +every time changes are detected. Then press start to begin +monitoring.</FONT></P> +<UL> + <P STYLE="margin-bottom: 0cm"><IMG SRC="RealtimeSync_html_72dda21b.gif" NAME="Grafik1" ALIGN=MIDDLE WIDTH=382 HEIGHT=395 BORDER=0></P> +</UL> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<UL> + <P STYLE="margin-bottom: 0cm"><SPAN ID="Rahmen3" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: 1px solid #000080; padding: 0.05cm; background: #ccccff"> + <UL> + <P ALIGN=LEFT STYLE="margin-right: 0.98cm; margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Note:</B></FONT></P> + <LI><P ALIGN=LEFT STYLE="margin-right: 0.98cm; margin-bottom: 0cm"> + <FONT FACE="Tahoma, sans-serif">Using RealtimeSync is not + restricted to starting FreeFileSync. It can also be used for other + scenarios, like sending an email whenever a certain directory is + modified.</FONT></P> + <LI><P ALIGN=LEFT STYLE="margin-right: 0.98cm; margin-bottom: 0cm"> + <FONT FACE="Tahoma, sans-serif">Starting the tool can be automated + by passing a RealtimeSync configuration file (*.ffs_real) OR a + FreeFileSync Batch file (*.ffs_batch) as first commandline + argument. This allows for integration with your operating system's + autostart facility:</FONT></P> + </UL> + </SPAN><BR CLEAR=LEFT> + </P> +</UL> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<UL> + <P><SPAN ID="Rahmen1" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: none; padding: 0cm; background: #e6e6e6"> + <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-right: 0.98cm; margin-bottom: 0cm"> + <FONT FACE="Courier New, monospace">C:\Program + Files\FreeFileSync\RealtimeSync.exe C:\MyConfig.ffs_real<BR>C:\Program + Files\FreeFileSync\RealtimeSync.exe C:\SyncJob.ffs_batch</FONT></P> + </SPAN><BR CLEAR=LEFT> + </P> +</UL> +</BODY> +</HTML>
\ No newline at end of file diff --git a/BUILD/Help/html/advanced/RealtimeSync_html_72dda21b.gif b/BUILD/Help/html/advanced/RealtimeSync_html_72dda21b.gif Binary files differnew file mode 100644 index 00000000..9da1bc3f --- /dev/null +++ b/BUILD/Help/html/advanced/RealtimeSync_html_72dda21b.gif diff --git a/BUILD/Help/html/advanced/ScheduleBatch.html b/BUILD/Help/html/advanced/ScheduleBatch.html new file mode 100644 index 00000000..4d1f3de0 --- /dev/null +++ b/BUILD/Help/html/advanced/ScheduleBatch.html @@ -0,0 +1,69 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)"> + <META NAME="CREATED" CONTENT="20091206;16574000"> + <META NAME="CHANGED" CONTENT="20091213;16291600"> + <STYLE TYPE="text/css"> + <!-- + @page { margin: 2cm } + P { margin-bottom: 0.21cm } + H3 { margin-bottom: 0.21cm } + H3.western { font-family: "Arial", sans-serif } + H3.cjk { font-family: "MS Mincho" } + A:link { so-language: zxx } + --> + </STYLE> +</HEAD> +<BODY LANG="de-DE" DIR="LTR"> +<H3 CLASS="western"><FONT FACE="Tahoma, sans-serif">Schedule Batch +Job in Windows Task Planner (Windows XP)</FONT></H3> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<OL> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Create + a new batch job via FreeFileSync's main + dialog:<BR><I>Menu->Advanced->Create batch job</I> and save + it, for example, as <FONT FACE="Courier New, monospace">"C:\SyncJob.ffs_batch</FONT>".</FONT></P> + <P STYLE="margin-bottom: 0cm"></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Make + sure you are using "<I>silent mode</I>" to prevent showing + a status dialog at the end of the process.</FONT></P> + <P STYLE="margin-bottom: 0cm"></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Start + Windows Task Scheduler: Go to <I>Start->Control Panel->Scheduled + Tasks</I> and select "<I>Add Scheduled Task</I>".</FONT></P> + <P STYLE="margin-bottom: 0cm"></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Follow + the wizard and choose "<FONT FACE="Courier New, monospace">C:\SyncJob.ffs_batch</FONT>" + as program to run.</FONT></P> + <UL> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">If + you are using the installer-based version of FreeFileSync, + </FONT><FONT FACE="Courier New, monospace">*.ffs_batch</FONT> <FONT FACE="Tahoma, sans-serif">files + are automatically associated with the tool and field "</FONT><FONT FACE="Tahoma, sans-serif"><I>Run:</I></FONT><FONT FACE="Tahoma, sans-serif">" + can be filled with the filename directly:<BR>"</FONT><FONT FACE="Courier New, monospace">C:\SyncJob.ffs_batch</FONT><FONT FACE="Tahoma, sans-serif">"<BR><IMG SRC="scheduleBatch_html_m22c860a2.gif" NAME="Grafik1" ALIGN=BOTTOM WIDTH=406 HEIGHT=455 BORDER=0></FONT></P> + <P STYLE="margin-bottom: 0cm"></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">If + file associations have not been set (portable/zip-version),</FONT> + "<FONT FACE="Tahoma, sans-serif"><I>Run:</I></FONT><FONT FACE="Tahoma, sans-serif">" + has to be prefixed with the + executable:<BR>"D</FONT><FONT FACE="Courier New, monospace">:\FreeFileSync\FreeFileSync.exe" + "C:\SyncJob.ffs_batch</FONT><FONT FACE="Tahoma, sans-serif">"<BR><IMG SRC="scheduleBatch_html_28bb3203.gif" NAME="Grafik2" ALIGN=BOTTOM WIDTH=406 HEIGHT=455 BORDER=0></FONT></P> + <P><SPAN ID="Rahmen1" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: 1px solid #000080; padding: 0.05cm; background: #ccccff"> + <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-right: 0.98cm; margin-bottom: 0cm"> + <FONT FACE="Tahoma, sans-serif"><B>Attention:</B><BR>The portable + version of FreeFileSync reads/writes all global settings from the + current working directory, while the installer based version uses + "<FONT FACE="Courier New, monospace">%appdata%\FreeFileSync</FONT>". + So in former case make sure the working directory is filled + appropriately in field "<I>Start in:</I>" to point to + the directory containing respective GlobalSettings.xml.</FONT></P> + </SPAN><BR CLEAR=LEFT> + </P> + </UL> +</OL> +</BODY> +</HTML>
\ No newline at end of file diff --git a/BUILD/Help/html/advanced/SendMail.html b/BUILD/Help/html/advanced/SendMail.html new file mode 100644 index 00000000..10ea0e4a --- /dev/null +++ b/BUILD/Help/html/advanced/SendMail.html @@ -0,0 +1,60 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)"> + <META NAME="CREATED" CONTENT="20091206;16574000"> + <META NAME="CHANGED" CONTENT="20091213;15581500"> + <META NAME="Info 1" CONTENT=""> + <META NAME="Info 2" CONTENT=""> + <META NAME="Info 3" CONTENT=""> + <META NAME="Info 4" CONTENT=""> + <STYLE TYPE="text/css"> + <!-- + @page { margin: 2cm } + P { margin-bottom: 0.21cm } + H3 { margin-bottom: 0.21cm } + H3.western { font-family: "Arial", sans-serif } + H3.cjk { font-family: "MS Mincho" } + A:link { so-language: zxx } + --> + </STYLE> +</HEAD> +<BODY LANG="de-DE" DIR="LTR"> +<H3 CLASS="western"><FONT FACE="Tahoma, sans-serif">Synchronize in +Batch Mode and send error notification via email</FONT></H3> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<OL> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Create + a FreeFileSync batch file using "<I>silent mode</I>".</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Set + error handling to "<I>Exit with Returncode < 0</I>" or + "<I>ignore errors</I>" to avoid having a popup stop the + program flow. In case errors occur FreeFileSync will abort with a + returncode < 0 which can be checked via the ERRORLEVEL batch + command.</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Create + a *.cmd or *.bat file to specify the location of FreeFileSync.exe + and pass the name of the FreeFileSync batch file as first argument; + e.g.:</FONT></P> +</OL> +<UL> + <P STYLE="margin-bottom: 0cm"><SPAN ID="Rahmen1" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: none; padding: 0cm; background: #e6e6e6"> + <UL> + <P ALIGN=LEFT STYLE="margin-right: 0.98cm; margin-bottom: 0cm"><FONT FACE="Courier New, monospace">C:\Program + Files\FreeFileSync\FreeFileSync.exe C:\SyncJob.ffs_batch<BR>if not + errorlevel 0 echo An error occured! && pause</FONT></P> + </UL> + </SPAN><BR CLEAR=LEFT> + </P> +</UL> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-left: 1.46cm; margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Instead +of displaying "An error occurred!" you can specify any +other command like sending an email notification (using a third party +tool).</FONT></P> +</BODY> +</HTML>
\ No newline at end of file diff --git a/BUILD/Help/html/advanced/ShadowCopy.html b/BUILD/Help/html/advanced/ShadowCopy.html new file mode 100644 index 00000000..374d2e15 --- /dev/null +++ b/BUILD/Help/html/advanced/ShadowCopy.html @@ -0,0 +1,68 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)"> + <META NAME="CREATED" CONTENT="20091206;16574000"> + <META NAME="CHANGED" CONTENT="20091213;16112500"> + <META NAME="Info 1" CONTENT=""> + <META NAME="Info 2" CONTENT=""> + <META NAME="Info 3" CONTENT=""> + <META NAME="Info 4" CONTENT=""> + <STYLE TYPE="text/css"> + <!-- + @page { margin: 2cm } + P { margin-bottom: 0.21cm } + H3 { margin-bottom: 0.21cm } + H3.western { font-family: "Arial", sans-serif } + H3.cjk { font-family: "MS Mincho" } + A:link { so-language: zxx } + --> + </STYLE> +</HEAD> +<BODY LANG="de-DE" DIR="LTR"> +<H3 CLASS="western"><FONT FACE="Tahoma, sans-serif">Volume Shadow +Copy Service <SPAN STYLE="font-weight: normal">(Windows only)</SPAN></FONT></H3> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">FreeFileSync +supports copying locked or shared files by creating a Volume Shadow +Copy of the source drive. To enable this feature go to </FONT><FONT FACE="Tahoma, sans-serif"><I>Menu +-> Advanced -> Global settings: Copy locked files</I></FONT><FONT FACE="Tahoma, sans-serif">.</FONT></P> +<UL> + <P><SPAN ID="Rahmen2" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: 1px solid #000080; padding: 0.05cm; background: #ccccff"> + <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-right: 0.98cm; margin-bottom: 0cm"> + <FONT FACE="Tahoma, sans-serif"><B>Note:</B><BR>This functionality + is applied to locked files only. Regular files will not use the + Volume Shadow Copy Service when being synchronized.</FONT></P> + </SPAN><BR CLEAR=LEFT> + </P> +</UL> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Troubleshooting</B></FONT></P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">If you +experience problems using the Volume Shadow Copy Service a renewal of +registration might help. Create and execute a *.cmd batch file with +the follow content or enter directly via commandline:</FONT></P> +<UL> + <P STYLE="margin-right: 0.98cm"><SPAN ID="Rahmen3" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: none; padding: 0cm; background: #e6e6e6"> + <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-right: 0.98cm; margin-bottom: 0cm"> + <FONT FACE="Courier New, monospace">cd /d %windir%\system32<BR>Net + stop vss<BR>Net stop swprv<BR>regsvr32 ole32.dll<BR>regsvr32 + oleaut32.dll<BR>regsvr32 vss_ps.dll<BR>Vssvc /register<BR>regsvr32 + /i swprv.dll<BR>regsvr32 /i eventcls.dll<BR>regsvr32 + es.dll<BR>regsvr32 stdprov.dll<BR>regsvr32 vssui.dll<BR>regsvr32 + msxml.dll<BR>regsvr32 msxml3.dll<BR>regsvr32 msxml4.dll</FONT></P> + </SPAN><BR CLEAR=LEFT> + </P> +</UL> +<P ALIGN=LEFT STYLE="margin-right: 0.98cm; margin-bottom: 0cm"><BR> +</P> +<P ALIGN=LEFT STYLE="margin-right: 0.98cm; margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">(Reference: +<A HREF="http://support.microsoft.com/kb/940032">http://support.microsoft.com/kb/940032</A>)</FONT></P> +</BODY> +</HTML>
\ No newline at end of file diff --git a/BUILD/Help/html/advanced/SymbolicLinks.html b/BUILD/Help/html/advanced/SymbolicLinks.html new file mode 100644 index 00000000..e3dd6ea2 --- /dev/null +++ b/BUILD/Help/html/advanced/SymbolicLinks.html @@ -0,0 +1,73 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)"> + <META NAME="CREATED" CONTENT="20091206;16574000"> + <META NAME="CHANGED" CONTENT="20091213;16130900"> + <META NAME="Info 1" CONTENT=""> + <META NAME="Info 2" CONTENT=""> + <META NAME="Info 3" CONTENT=""> + <META NAME="Info 4" CONTENT=""> + <STYLE TYPE="text/css"> + <!-- + @page { margin: 2cm } + P { margin-bottom: 0.21cm } + H3 { margin-bottom: 0.21cm } + H3.western { font-family: "Arial", sans-serif } + H3.cjk { font-family: "MS Mincho" } + A:link { so-language: zxx } + --> + </STYLE> +</HEAD> +<BODY LANG="de-DE" DIR="LTR"> +<H3 CLASS="western"><FONT FACE="Tahoma, sans-serif">Symbolic link +handling <SPAN STYLE="font-weight: normal">(Windows since Vista and +Linux)</SPAN></FONT></H3> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">FreeFileSync +offers the following two advanced options contained in each +*.ffs_gui/*.ffs_batch file to configure processing of Symbolic Links +(also called Symlinks or Soft Links):</FONT></P> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Default +Settings (View and edit these in the text editor of your choice):</FONT></P> +<UL> + <P><SPAN ID="Rahmen1" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: none; padding: 0cm; background: #e6e6e6"> + <UL> + <P ALIGN=LEFT STYLE="margin-right: 0.98cm; margin-bottom: 0cm"><FONT FACE="Courier New, monospace"><CopyFileSymlinks>true</CopyFileSymlinks><BR><TraverseDirectorySymlinks>false</TraverseDirectorySymlinks></FONT></P> + </UL> + </SPAN><BR CLEAR=LEFT> + </P> +</UL> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">"<I>CopyFileSymlinks</I>" +defines the behavior for copying Symbolic Links pointing to files:</FONT></P> +<P STYLE="margin-left: 2cm; margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">If +set to <I>true</I> it copies the Symbolik Link to its destination.<BR>If +set to <I>false</I> the target of the link, in this case a file, is +being copied instead.</FONT></P> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">"<I>TraverseDirectorySymlinks</I>" +specifies handling of Symbolic Links to directories:</FONT></P> +<P STYLE="margin-left: 2cm; margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">If +<I>true</I>, they are being traversed like ordinary directories +during comparison and are copied as if they were regular directories +(i.e. not as Symbolic Links) during synchronization.<BR>If <I>false</I> +is selected, these Symbolic Links are not traversed at all. During +synchronization copying them results in a direct copy of the Symbolic +Link, not the target directory.</FONT></P> +<P STYLE="margin-left: 2cm; margin-bottom: 0cm"><SPAN ID="Rahmen2" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: 1px solid #000080; padding: 0.05cm; background: #ccccff"> + <P ALIGN=LEFT STYLE="margin-left: 0.79cm; margin-right: 0.98cm; margin-bottom: 0cm"> + <FONT FACE="Tahoma, sans-serif"><B>Note:</B><BR>As the link's + content is not parsed by FreeFileSync, this usually only makes sense + when you use relative paths within your Symolic Links.</FONT></P> +</SPAN><BR CLEAR=LEFT><BR> +</P> +</BODY> +</HTML>
\ No newline at end of file diff --git a/BUILD/Help/html/advanced/TimeStamped.html b/BUILD/Help/html/advanced/TimeStamped.html new file mode 100644 index 00000000..6428243c --- /dev/null +++ b/BUILD/Help/html/advanced/TimeStamped.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)"> + <META NAME="CREATED" CONTENT="20091206;16574000"> + <META NAME="CHANGED" CONTENT="20091213;16013600"> + <META NAME="Info 1" CONTENT=""> + <META NAME="Info 2" CONTENT=""> + <META NAME="Info 3" CONTENT=""> + <META NAME="Info 4" CONTENT=""> + <STYLE TYPE="text/css"> + <!-- + @page { margin: 2cm } + P { margin-bottom: 0.21cm } + H3 { margin-bottom: 0.21cm } + H3.western { font-family: "Arial", sans-serif } + H3.cjk { font-family: "MS Mincho" } + A:link { so-language: zxx } + --> + </STYLE> +</HEAD> +<BODY LANG="de-DE" DIR="LTR"> +<H3 CLASS="western"><FONT FACE="Tahoma, sans-serif">Create regular +backups with time-stamped directory names</FONT></H3> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">You can +use macros <FONT FACE="Courier New, monospace">%time%</FONT>, <FONT FACE="Courier New, monospace">%date%</FONT> +within directory names you want to synchronize.</FONT></P> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif"><B>Example:</B></FONT></P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Let's +assume you have a directory "<FONT FACE="Courier New, monospace">C:\Source</FONT>" +which you want to backup each day into a time-stamped target +directory like "<FONT FACE="Courier New, monospace">C:\Target_2009-10-08</FONT>". +All that needs to be done is setting up base directories like these:</FONT></P> +<UL> + <P STYLE="margin-bottom: 0cm"><SPAN ID="Rahmen1" DIR="LTR" STYLE="float: left; width: 80%; height: 0.14cm; border: none; padding: 0cm; background: #e6e6e6"> + <UL> + <P ALIGN=LEFT STYLE="margin-right: 0.98cm; margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Source + folder: "<FONT FACE="Courier New, monospace">C:\Source</FONT>"<BR>Target + folder: "<FONT FACE="Courier New, monospace">C:\Target_%date%</FONT>"</FONT></P> + </UL> + </SPAN><BR CLEAR=LEFT> + </P> +</UL> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Latter +will be interactively replaced with the current date during +synchronization. In order to further automate this process, you can +create a *.ffs_batch file with this configuration and choose "<I>ignore +errors</I>" to avoid the warning that target directory is not +(yet) existing.</FONT></P> +</BODY> +</HTML>
\ No newline at end of file diff --git a/BUILD/Help/html/advanced/VariableDrive.html b/BUILD/Help/html/advanced/VariableDrive.html new file mode 100644 index 00000000..e46bbaad --- /dev/null +++ b/BUILD/Help/html/advanced/VariableDrive.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> + <TITLE></TITLE> + <META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)"> + <META NAME="CREATED" CONTENT="20091206;16574000"> + <META NAME="CHANGED" CONTENT="20091213;16011300"> + <STYLE TYPE="text/css"> + <!-- + @page { margin: 2cm } + P { margin-bottom: 0.21cm } + H3 { margin-bottom: 0.21cm } + H3.western { font-family: "Arial", sans-serif } + H3.cjk { font-family: "MS Mincho" } + A:link { so-language: zxx } + --> + </STYLE> +</HEAD> +<BODY LANG="de-DE" DIR="LTR"> +<H3 CLASS="western"><FONT FACE="Tahoma, sans-serif">Synchronize USB +sticks with variable drive letters</FONT></H3> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">USB +sticks often have different volume names assigned to them when +plugged into two distinct computers. In order to handle this +flexibility FreeFileSync is able to process directory names relative +to the current working directory.</FONT></P> +<P STYLE="margin-bottom: 0cm"><BR> +</P> +<P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Thus +the following workflow is possible:</FONT></P> +<UL> + <OL> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Replace + the absolute USB directory name in your configuration by a relative + one:<BR>E.g. "<FONT FACE="Courier New, monospace">E:\SyncDir</FONT>" + -> "<FONT FACE="Courier New, monospace">\SyncDir</FONT>"</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Save + and copy synchronization settings to the USB stick: + "<FONT FACE="Courier New, monospace">E:\settings.ffs_gui</FONT>"</FONT></P> + <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Start + FreeFileSync by double-clicking on "</FONT><FONT FACE="Courier New, monospace">E:\settings.ffs_gui</FONT><FONT FACE="Tahoma, sans-serif">"<BR>=> + Working directory automatically is set to "</FONT><FONT FACE="Courier New, monospace">E:\</FONT><FONT FACE="Tahoma, sans-serif">" + by the operating system so that "</FONT><FONT FACE="Courier New, monospace">\SyncDir</FONT><FONT FACE="Tahoma, sans-serif">" + is interpreted as "</FONT><FONT FACE="Courier New, monospace">E:\SyncDir</FONT><FONT FACE="Tahoma, sans-serif">" + during synchronization.</FONT></P> + </OL> +</UL> +</BODY> +</HTML>
\ No newline at end of file diff --git a/BUILD/Help/html/advanced/scheduleBatch_html_13615436.gif b/BUILD/Help/html/advanced/scheduleBatch_html_13615436.gif Binary files differnew file mode 100644 index 00000000..23d7bda9 --- /dev/null +++ b/BUILD/Help/html/advanced/scheduleBatch_html_13615436.gif diff --git a/BUILD/Help/html/advanced/scheduleBatch_html_28bb3203.gif b/BUILD/Help/html/advanced/scheduleBatch_html_28bb3203.gif Binary files differnew file mode 100644 index 00000000..45c8b1c2 --- /dev/null +++ b/BUILD/Help/html/advanced/scheduleBatch_html_28bb3203.gif diff --git a/BUILD/Help/html/advanced/scheduleBatch_html_m22c860a2.gif b/BUILD/Help/html/advanced/scheduleBatch_html_m22c860a2.gif Binary files differnew file mode 100644 index 00000000..1f8da914 --- /dev/null +++ b/BUILD/Help/html/advanced/scheduleBatch_html_m22c860a2.gif diff --git a/BUILD/Help/html/overview_html_m11e8dbdc.gif b/BUILD/Help/html/overview_html_m11e8dbdc.gif Binary files differnew file mode 100644 index 00000000..4fc6ea59 --- /dev/null +++ b/BUILD/Help/html/overview_html_m11e8dbdc.gif diff --git a/BUILD/Help/html/overview_html_m67668fb2.gif b/BUILD/Help/html/overview_html_m67668fb2.gif Binary files differnew file mode 100644 index 00000000..2b5a33ff --- /dev/null +++ b/BUILD/Help/html/overview_html_m67668fb2.gif diff --git a/BUILD/Help/html/overview_html_m7391eb10.gif b/BUILD/Help/html/overview_html_m7391eb10.gif Binary files differnew file mode 100644 index 00000000..d5831a44 --- /dev/null +++ b/BUILD/Help/html/overview_html_m7391eb10.gif diff --git a/BUILD/Help/html/overview_html_mbb6ab4a.gif b/BUILD/Help/html/overview_html_mbb6ab4a.gif Binary files differnew file mode 100644 index 00000000..499b00bd --- /dev/null +++ b/BUILD/Help/html/overview_html_mbb6ab4a.gif diff --git a/BUILD/Languages/chinese_simple.lng b/BUILD/Languages/chinese_simple.lng index 9b8ed25f..d73d300c 100644 --- a/BUILD/Languages/chinese_simple.lng +++ b/BUILD/Languages/chinese_simple.lng @@ -148,8 +148,6 @@ <多选> A newer version of FreeFileSync is available: FreeFileSync 有新版å¯ç”¨: -ATTENTION: Failed directory access can lead to file deletions! -请注æ„:失败的目录å˜å–ä¼šå¯¼è‡´æ–‡ä»¶åˆ é™¤! Abort requested: Waiting for current operation to finish... å–消请求: æ£åœ¨ç‰å¾…当å‰æ“作完æˆ... Aborted @@ -158,10 +156,14 @@ About 关于 Action 动作 +Activate filter +激活过滤器 Add folder æ·»åŠ æ–‡ä»¶å¤¹ Add folder pair æ·»åŠ æˆå¯¹æ–‡ä»¶å¤¹ +All directories in sync! +所有目录åŒæ¥! An exception occured! å‘生异常! As a result the files are separated into the following categories: @@ -198,10 +200,6 @@ Category 分类 Change direction 改å˜æ–¹å‘ -Check all -全选 -Choose to hide filtered files/directories from list -从列表ä¸é€‰æ‹©éšè—被过滤的文件/文件夹 Comma separated list 逗å·åˆ†éš”的列表 Commandline @@ -242,8 +240,6 @@ Configuration saved! é…置已ä¿å˜! Configure filter é…置过滤 -Configure filter... -设置过滤... Configure your own synchronization rules. é…ç½®ä½ è‡ªå·±çš„åŒæ¥è§„则. Confirm @@ -334,8 +330,6 @@ Directory 目录 Directory does not exist: 目录ä¸å˜åœ¨: -Do not display visual status information but write to a logfile instead -ä¸æ˜¾ç¤ºè§†è§‰çŠ¶æ€ä¿¡æ¯,使用写入日志文件代替。 Do not show this dialog again ä¸è¦å†æ˜¾ç¤ºæ¤å¯¹è¯æ¡† Do nothing @@ -406,12 +400,12 @@ Error writing file: 写入文件出错: Error writing to synchronization database: å‘åŒæ¥æ•°æ®åº“ä¸å†™å…¥æ—¶å‡ºé”™: -Source directory does not exist anymore: -æºç›®å½•å·²ç»ä¸å˜åœ¨: Example 例如 Exclude 排除 +Exclude all rows +排除所有行 Exclude temporarily 暂时排除 Exclude via filter: @@ -422,6 +416,8 @@ Exit with RC < 0 退出并设置返回ç <0 External applications å¤–éƒ¨åº”ç”¨ç¨‹åº +Fatal Error +致命错误 Feedback and suggestions are welcome at: 欢迎在下é¢æ出å馈æ„è§å’Œå»ºè®®: File %x has an invalid date! @@ -466,12 +462,14 @@ Files/folders that exist on right side only 仅在å³ä¾§å˜åœ¨çš„文件/文件夹 Filter 过滤 -Filter active: Press again to deactivate -过滤激活: å†æŒ‰ä¸€æ¬¡å¯å…³é—激活 Filter files 过滤文件 +Filter has been selected +过滤器已选择 Filter view 过滤查看 +Filtering is deactivated +过滤为éžæ´»è·ƒçŠ¶æ€ Folder Comparison and Synchronization 文件夹比较与åŒæ¥ Free disk space available: @@ -494,6 +492,8 @@ Generating database... æ£åœ¨ç”Ÿæˆæ•°æ®åº“... Generating file list... 生æˆæ–‡ä»¶åˆ—表... +Global filter +全局过滤器 Global settings 全局设置 Help @@ -504,6 +504,8 @@ Hide all error and warning messages éšè—所有错误与è¦å‘Šä¿¡æ¯ Hide conflicts éšè—å†²çª +Hide excluded items +éšè—已排除的项目 Hide files that are different éšè—ä¸åŒçš„文件 Hide files that are equal @@ -530,14 +532,16 @@ Hide files that will be overwritten on right side éšè—将在å³ä¾§è¢«è¦†ç›–的文件 Hide files that won't be copied éšè—å°†ä¸ä¼šè¢«å¤åˆ¶çš„文件 -Hide filtered items -éšè—已过滤的项目 +Hide filtered or temporarily excluded files +éšè—已过滤或临时排除的文件 Hide further error messages during the current process 在当å‰è¿›ç¨‹ä¸éšè—进一æ¥çš„é”™è¯¯ä¿¡æ¯ Hints: æ示: Homepage 主页 +Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically. +使用数æ®åº“æ¥è¯†åˆ«å’Œä¼ é€ä¸¤è¾¹çš„改å˜. è‡ªåŠ¨æ£€æµ‹åˆ é™¤å’Œå†²çªçŠ¶æ€. If you like FFS å¦‚æžœä½ å–œæ¬¢ FFS Ignore 1-hour file time difference @@ -552,6 +556,8 @@ Ignore this error, retry or abort? 忽略这个错误,é‡è¯•æˆ–å–消? Include 包括 +Include all rows +包括所有行 Include temporarily 暂时包括 Include: *.doc;*.zip;*.exe\nExclude: temp\\* @@ -562,8 +568,8 @@ Info ä¿¡æ¯ Information ä¿¡æ¯ -Initial synchronization. -åˆå§‹åŒ–åŒæ¥. +Initial synchronization: +åˆå§‹åŒ–åŒæ¥: Integrate external applications into context menu. The following macros are available: 集æˆå¤–部应用程åºåˆ°å³é”®èœå•. 如下å®å¯ç”¨: It was not possible to initialize the Recycle Bin!\n\nIt's likely that you are not using Windows.\nIf you want this feature included, please contact the author. :) @@ -578,6 +584,8 @@ Load configuration from file ä»Žæ–‡ä»¶åŠ è½½é…ç½® Load configuration history (press DEL to delete items) åŠ è½½é…置历å²è®°å½•(按DELé”®åˆ é™¤é¡¹ç›®) +Local filter +局部过滤器 Log-messages: 日志信æ¯: Logging @@ -602,8 +610,8 @@ Moving folder %x to user-defined directory %y 移动文件夹 %x 到用户定义目录 %y Multiple... å€æ•°... -No database file existing yet: -还没有数æ®åº“文件å˜åœ¨: +No filter selected +没有选定过滤器 Not enough free disk space available in: 没有足够的å¯ç”¨ç£ç›˜ç©ºé—´ç”¨äºŽ: Nothing to synchronize according to configuration! @@ -638,8 +646,8 @@ Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) i 请å¤åˆ¶é€‚当的\"Shadow.dll\"(ä½äºŽ\"Shadow.zip\"压缩包ä¸)到FreeFileSync安装目录以å¯ç”¨æ¤ç‰¹æ€§. Please fill all empty directory fields. 请填满所有空的目录区域. -Press button to activate filter -请按键以激活过滤 +Please run a Compare first before synchronizing! +åŒæ¥ä¹‹å‰è¯·å…ˆè¿›è¡Œå¯¹æ¯” Published under the GNU General Public License: 在GNU通用公共许å¯ä¸‹å‘布: Question @@ -660,12 +668,16 @@ Remove folder åˆ é™¤æ–‡ä»¶å¤¹ Remove folder pair åˆ é™¤æ–‡ä»¶å¤¹å¯¹ +Remove local filter settings +移除局部过滤器 Report translation error 报告翻译错误 Reset é‡ç½® Right å³ä¾§ +Run minimized and write status information to a logfile +最å°åŒ–è¿è¡Œå¹¶å°†çŠ¶æ€ä¿¡æ¯å†™åˆ°ä¸€ä¸ªè®°å½•æ–‡ä»¶ä¸ S&ave configuration ä¿å˜é…ç½®(&A) S&witch view @@ -680,14 +692,14 @@ Scanning: 扫æä¸: Select a folder 选择一个文件夹 -Select alternate filter settings -选择替æ¢è¿‡æ»¤è®¾ç½® Select alternate synchronization settings 选择替æ¢åŒæ¥è®¾ç½® Select logfile directory: 选择日志ä¿å˜ä½ç½®: Select variant: 选择å˜åŒ–çš„: +Setting default synchronization directions. Please check whether they are appropriate for you. +设置默认åŒæ¥æ–¹å‘. 请检查是å¦é€‚åˆ. Show conflicts æ˜¾ç¤ºå†²çª Show file icons @@ -732,6 +744,8 @@ Size å¤§å° Source code written completely in C++ utilizing: æºä»£ç 完全使用C++工具编写: +Source directory does not exist anymore: +æºç›®å½•å·²ç»ä¸å˜åœ¨: Speed: 速度: Start @@ -772,8 +786,12 @@ Target directory already existing! ç›®æ ‡ç›®å½•å·²ç»å˜åœ¨! Target file already existing! ç›®æ ‡æ–‡ä»¶å·²ç»å˜åœ¨! +The database file is not yet existing, but will be created during synchronization: +æ•°æ®åº“文件未å˜åœ¨, 但在åŒæ¥æœŸé—´ä¼šè¢«åˆ›å»º: The file does not contain a valid configuration: 该文件ä¸åŒ…å«æœ‰æ•ˆçš„é…ç½®: +The required database entry is not yet existing, but will be created during synchronization: +请求的数æ®åº“å…¥å£æœªå˜åœ¨, 但在åŒæ¥æœŸé—´ä¼šè¢«åˆ›å»º: This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. æ¤å˜åŒ–评估两个文件å相åŒçš„文件,åªæœ‰å½“他们有åŒæ ·çš„文件大å°å¹¶ä¸”最åŽä¿®æ”¹æ—¥æœŸå’Œæ—¶é—´ä¹Ÿç›¸åŒ\næ—¶æ‰è®¤ä¸ºå®ƒä»¬æ˜¯ç›¸åŒçš„. Time @@ -798,8 +816,6 @@ Unable to create logfile! æ— æ³•åˆ›å»ºæ—¥å¿—! Unable to initialize Recycle Bin! æ— æ³•åˆå§‹åŒ–回收站! -Uncheck all -全部å–æ¶ˆé€‰ä¸ Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization. å˜åœ¨ä¸å¯è§£å†³çš„冲çª!\n\nä½ å¯å¿½ç•¥å†²çªå¹¶ç»§ç»åŒæ¥. Update -> @@ -814,8 +830,6 @@ User-defined directory 用户定义目录 User-defined directory for deletion was not specified! ç”¨äºŽåˆ é™¤çš„ç”¨æˆ·å®šä¹‰ç›®å½•æ²¡æœ‰æŒ‡å®š! -Using default synchronization directions. Please recheck. -使用默认的åŒæ¥æ–¹å‘. 请é‡æ–°æ£€æŸ¥. Variant å˜åŒ– Verifying file %x diff --git a/BUILD/Languages/chinese_traditional.lng b/BUILD/Languages/chinese_traditional.lng index 9ff6db11..cc9abc57 100644 --- a/BUILD/Languages/chinese_traditional.lng +++ b/BUILD/Languages/chinese_traditional.lng @@ -148,8 +148,6 @@ <多é‡é¸æ“‡> A newer version of FreeFileSync is available: 有較新版本的 FreeFileSync å¯ç”¨ï¼š -ATTENTION: Failed directory access can lead to file deletions! -注æ„:目錄讀å–失敗å¯èƒ½æœƒå°Žè‡´æª”æ¡ˆåˆªé™¤ï¼ Abort requested: Waiting for current operation to finish... ä¸æ¢è«‹æ±‚:æ£åœ¨ç‰å¾…ç›®å‰æ“作完æˆ... Aborted @@ -158,10 +156,14 @@ About 關於 Action 動作 +Activate filter +啟動篩é¸å™¨ Add folder 新增資料夾 Add folder pair 新增兩個資料夾 +All directories in sync! +åŒæ¥æ‰€æœ‰ç›®éŒ„ï¼ An exception occured! ç™¼ç”Ÿç•°å¸¸ï¼ As a result the files are separated into the following categories: @@ -198,10 +200,6 @@ Category 分類 Change direction æ”¹è®Šæ–¹å‘ -Check all -å…¨é¸ -Choose to hide filtered files/directories from list -從清單ä¸é¸æ“‡éš±è—被篩é¸çš„檔案/目錄 Comma separated list 逗號分隔清單 Commandline @@ -242,8 +240,6 @@ Configuration saved! é…置已儲å˜ï¼ Configure filter é…ç½®ç¯©é¸ -Configure filter... -é…置篩é¸... Configure your own synchronization rules. é…ç½®ä½ è‡ªå·±çš„åŒæ¥è¦å‰‡ã€‚ Confirm @@ -334,8 +330,6 @@ Directory 目錄 Directory does not exist: 目錄ä¸å˜åœ¨ï¼š -Do not display visual status information but write to a logfile instead -ä¸é¡¯ç¤ºè¦–覺狀態資訊,使用寫入日誌檔代替。 Do not show this dialog again ä¸è¦å†é¡¯ç¤ºæ¤å°è©±æ¡† Do nothing @@ -406,12 +400,12 @@ Error writing file: 寫入檔案錯誤: Error writing to synchronization database: 寫入åŒæ¥è³‡æ–™åº«éŒ¯èª¤ï¼š -Source directory does not exist anymore: -來æºç›®éŒ„ä¸å˜åœ¨ï¼š Example 例如 Exclude 排除 +Exclude all rows +排除所有行 Exclude temporarily 暫時排除 Exclude via filter: @@ -422,6 +416,8 @@ Exit with RC < 0 çµæŸä¸¦è¨å®šè¿”回碼 <0 External applications å¤–éƒ¨æ‡‰ç”¨ç¨‹å¼ +Fatal Error +åš´é‡éŒ¯èª¤ Feedback and suggestions are welcome at: æ¡è¿Žåœ¨ä¸‹é¢æå‡ºå›žå ±å’Œå»ºè°ï¼š File %x has an invalid date! @@ -466,12 +462,14 @@ Files/folders that exist on right side only åªå˜åœ¨æ–¼å³é‚Šçš„檔案/資料夾 Filter 篩é¸å™¨ -Filter active: Press again to deactivate -篩é¸å™¨å•Ÿç”¨ï¼šå†æŒ‰ä¸€æ¬¡æœƒåœç”¨ Filter files 篩é¸æª”案 +Filter has been selected +å·²é¸æ“‡ç¯©é¸å™¨ Filter view 篩é¸æª¢è¦– +Filtering is deactivated +篩é¸å·²åœç”¨ Folder Comparison and Synchronization 資料夾比å°å’ŒåŒæ¥ Free disk space available: @@ -494,6 +492,8 @@ Generating database... 產生資料庫... Generating file list... 產生檔案清單... +Global filter +整體性篩é¸å™¨ Global settings æ•´é«”è¨å®š Help @@ -504,6 +504,8 @@ Hide all error and warning messages éš±è—所有錯誤和è¦å‘Šè¨Šæ¯ Hide conflicts éš±è—è¡çª +Hide excluded items +éš±è—è¢«æŽ’é™¤çš„é …ç›® Hide files that are different éš±è—ä¸åŒçš„檔案 Hide files that are equal @@ -530,14 +532,16 @@ Hide files that will be overwritten on right side éš±è—å³é‚Šå°‡è¢«è¦†è“‹çš„檔案 Hide files that won't be copied éš±è—å°‡ä¸æœƒè¢«è¤‡è£½çš„檔案 -Hide filtered items -éš±è—已篩é¸çš„é …ç›® +Hide filtered or temporarily excluded files +éš±è—篩é¸æˆ–暫時被排除的檔案 Hide further error messages during the current process 在目å‰é€²ç¨‹ä¸éš±è—進一æ¥çš„éŒ¯èª¤è¨Šæ¯ Hints: æ示: Homepage 首é +Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically. +å°å…©é‚Šä½¿ç”¨åŒä¸€å€‹è³‡æ–™åº«çš„è˜åˆ¥å’Œå‚³é€æ›´æ”¹ã€‚自動檢測刪除和è¡çªéƒ¨ä»½ã€‚ If you like FFS å¦‚æžœä½ å–œæ¡ FFS Ignore 1-hour file time difference @@ -552,6 +556,8 @@ Ignore this error, retry or abort? 忽略æ¤éŒ¯èª¤ã€é‡è©¦æˆ–ä¸æ¢å—Žï¼Ÿ Include 包括 +Include all rows +包括所有行 Include temporarily 暫時包括 Include: *.doc;*.zip;*.exe\nExclude: temp\\* @@ -562,8 +568,8 @@ Info è¨Šæ¯ Information è¨Šæ¯ -Initial synchronization. -åˆå§‹åŒ–åŒæ¥ã€‚ +Initial synchronization: +åˆå§‹åŒ–åŒæ¥: Integrate external applications into context menu. The following macros are available: æ•´åˆä¸Šä¸‹æ–‡åŠŸèƒ½è¡¨ä¸çš„外部應用程å¼ã€‚å¯ä»¥ä½¿ç”¨ä¸‹é¢çš„巨集: It was not possible to initialize the Recycle Bin!\n\nIt's likely that you are not using Windows.\nIf you want this feature included, please contact the author. :) @@ -578,6 +584,8 @@ Load configuration from file 從檔案載入é…ç½® Load configuration history (press DEL to delete items) 載入é…置的æ·å²è¨˜éŒ„(按DELéµåˆªé™¤é …ç›®) +Local filter +局部性篩é¸å™¨ Log-messages: 日誌訊æ¯ï¼š Logging @@ -585,7 +593,7 @@ Logging Mirror ->> é¡åƒ ->> Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization. -左邊資料夾的é¡åƒå‚™ä»½ï¼šåŒæ¥ä¹‹å¾Œï¼Œ å³é‚Šè³‡æ–™å¤¾å°‡è¢«è¦†è“‹ï¼Œå®Œå…¨å’Œå·¦é‚Šè³‡æ–™å¤¾ä¸€æ¨¡ä¸€æ¨£ã€‚ +左邊資料夾的é¡åƒå‚™ä»½ï¼šåŒæ¥ä¹‹å¾Œï¼Œå³é‚Šè³‡æ–™å¤¾å°‡è¢«è¦†è“‹ï¼Œå®Œå…¨å’Œå·¦é‚Šè³‡æ–™å¤¾ä¸€æ¨¡ä¸€æ¨£ã€‚ More than 50% of the total number of files will be copied or deleted! 超éŽç¸½æ•¸ 50% ä»¥ä¸Šçš„æª”æ¡ˆå°‡è¢«è¤‡è£½æˆ–åˆªé™¤ï¼ Move column down @@ -602,8 +610,8 @@ Moving folder %x to user-defined directory %y 移動資料夾 %x 到自定義資料夾 %y Multiple... 多個... -No database file existing yet: -ç›®å‰é‚„沒有資料庫檔案: +No filter selected +沒有é¸æ“‡ç¯©é¸å™¨ Not enough free disk space available in: æ²’æœ‰è¶³å¤ çš„å¯ç”¨ç©ºé–“: Nothing to synchronize according to configuration! @@ -638,8 +646,8 @@ Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) i 請複製é©ç•¶çš„\"Shadow.dll\"(ä½æ–¼\"Shadow.zip\"壓縮檔)到 FreeFileSync 安è£ç›®éŒ„以啟用æ¤åŠŸèƒ½ã€‚ Please fill all empty directory fields. 請填滿所有空白目錄欄ä½ã€‚ -Press button to activate filter -按下按鈕以啟用篩é¸å™¨ +Please run a Compare first before synchronizing! +請執行åŒæ¥å‰å…ˆæ¯”å°ï¼ Published under the GNU General Public License: 在GNU通用公共許å¯è‰ä¸‹ç™¼ä½ˆï¼š Question @@ -660,12 +668,16 @@ Remove folder 移除資料夾 Remove folder pair 移除兩個資料夾 +Remove local filter settings +移除局部性篩é¸å™¨è¨å®š Report translation error å›žå ±ç¿»è¯éŒ¯èª¤ Reset é‡ç½® Right å³é‚Š +Run minimized and write status information to a logfile +執行最å°åŒ–和狀態資訊寫入到日誌檔 S&ave configuration 儲å˜é…ç½®(&A) S&witch view @@ -680,14 +692,14 @@ Scanning: 掃瞄ä¸ï¼š Select a folder é¸æ“‡ä¸€å€‹è³‡æ–™å¤¾ -Select alternate filter settings -é¸æ“‡å‚™ç”¨ç¯©é¸è¨å®š Select alternate synchronization settings é¸æ“‡å‚™ç”¨åŒæ¥è¨å®š Select logfile directory: é¸æ“‡æ—¥èªŒæª”目錄: Select variant: é¸æ“‡è®Šæ•¸ï¼š +Setting default synchronization directions. Please check whether they are appropriate for you. +è¨å®šé è¨åŒæ¥æ–¹å‘。請檢查這些è¨å®šæ˜¯å¦é©åˆæ–¼ä½ 。 Show conflicts 顯示è¡çª Show file icons @@ -732,6 +744,8 @@ Size å¤§å° Source code written completely in C++ utilizing: 原始碼完全使用C++編寫: +Source directory does not exist anymore: +來æºç›®éŒ„ä¸å˜åœ¨ï¼š Speed: 速度: Start @@ -757,7 +771,7 @@ Synchronization settings Synchronization status åŒæ¥ç‹€æ…‹ Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\". -åŒæ¥æ‰€æœ‰ .doc, .zip å’Œ .exe 檔案, 除了\"temp\"ä¸çš„一切。 +åŒæ¥æ‰€æœ‰ .doc, .zip å’Œ .exe 檔案,除了\"temp\"ä¸çš„一切。 Synchronize both sides simultaneously: Copy new or updated files in both directions. åŒæ™‚é›™å‘åŒæ¥ï¼šé›™å‘複製新的或已更新的檔案。 Synchronize both sides using a database. Deletions are detected automatically. @@ -772,8 +786,12 @@ Target directory already existing! 目標目錄已å˜åœ¨ï¼ Target file already existing! 目標檔案已å˜åœ¨ï¼ +The database file is not yet existing, but will be created during synchronization: +資料庫檔未å˜åœ¨ï¼Œä½†æœƒåœ¨åŒæ¥éŽç¨‹ä¸æ–°å»ºï¼š The file does not contain a valid configuration: 該檔案ä¸åŒ…å«æœ‰æ•ˆçš„é…置: +The required database entry is not yet existing, but will be created during synchronization: +所需的資料庫æ¢ç›®æœªå˜åœ¨ï¼Œä½†æœƒåœ¨åŒæ¥éŽç¨‹ä¸æ–°å»ºï¼š This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. æ¤è®Šæ•¸è¨ˆç®—çµæžœç‚ºå…©å€‹æª”å相åŒçš„檔案,åªæœ‰ç•¶ä»–們的檔案大å°å’Œæœ€å¾Œä¿®æ”¹æ—¥æœŸæ™‚間也相åŒï¼Œæ‰æœƒåˆ¤æ–·ä»–們是相åŒçš„檔案。 Time @@ -798,8 +816,6 @@ Unable to create logfile! ç„¡æ³•æ–°å»ºæ—¥èªŒæª”ï¼ Unable to initialize Recycle Bin! 無法åˆå§‹åŒ–資æºå›žæ”¶ç’ï¼ -Uncheck all -å–消全部é¸ä¸ Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization. å˜åœ¨æœªè§£æ±ºçš„è¡çªï¼\n\nä½ å¯ä»¥å¿½ç•¥è¡çªï¼Œä¸¦ç¹¼çºŒåŒæ¥ã€‚ Update -> @@ -814,8 +830,6 @@ User-defined directory 自定義目錄 User-defined directory for deletion was not specified! 未指定è¦åˆªé™¤çš„è‡ªå®šç¾©ç›®éŒ„ï¼ -Using default synchronization directions. Please recheck. -使用é è¨åŒæ¥æ–¹å‘。請é‡æ–°æª¢æŸ¥ã€‚ Variant 變數 Verifying file %x diff --git a/BUILD/Languages/czech.lng b/BUILD/Languages/czech.lng index 9309965b..8be657b4 100644 --- a/BUILD/Languages/czech.lng +++ b/BUILD/Languages/czech.lng @@ -148,8 +148,6 @@ soubor: 1; <vÃcenásobný výbÄ›r> A newer version of FreeFileSync is available: je dostupná novÄ›jÅ¡Ã verze FreeFileSync: -ATTENTION: Failed directory access can lead to file deletions! -POZOR: Chyba pÅ™Ãstupu k adresáři může vést ke smazánà souborů! Abort requested: Waiting for current operation to finish... Požadavek na pÅ™eruÅ¡enÃ: ÄŒekánà na ukonÄenà aktuálnà operace... Aborted @@ -158,10 +156,14 @@ About O Programu Action Akce +Activate filter +Povolit filtr Add folder PÅ™idat adresář Add folder pair PÅ™idat adresář pro porovnánà +All directories in sync! +VÅ¡echny adresáře jsou synchronizovány! An exception occured! Vyskytla se chyba! As a result the files are separated into the following categories: @@ -198,10 +200,6 @@ Category Kategorie Change direction ZmÄ›nit akci -Check all -OznaÄit vÅ¡e -Choose to hide filtered files/directories from list -Vyberte pro skrytà filtrovaných souborů/adresářů ze seznamu Comma separated list Text oddÄ›lený Äárkami Commandline @@ -242,8 +240,6 @@ Configuration saved! Konfigurace uložena. Configure filter Nastavenà filtru -Configure filter... -Nastavenà filtru... Configure your own synchronization rules. Nastavenà vlastnÃch pravidel synchronizace. Confirm @@ -334,8 +330,6 @@ Directory Adresář Directory does not exist: Adresář neexistuje: -Do not display visual status information but write to a logfile instead -Nezobrazovat informace o stavu ale zapisovat pÅ™Ãmo do souboru záznamů Do not show this dialog again Tento dialog již nezobrazovat Do nothing @@ -406,12 +400,12 @@ Error writing file: Chyba zápisu souboru: Error writing to synchronization database: Chyba zápisu synchronizaÄnà databáze: -Source directory does not exist anymore: -Zdrojový adresář již neexistuje: Example PÅ™Ãklad Exclude Vynechat +Exclude all rows +Vynechat vÅ¡echny řádky Exclude temporarily Vynechat doÄasnÄ› Exclude via filter: @@ -422,6 +416,8 @@ Exit with RC < 0 UkonÄit s RC < 0 External applications Externà aplikace +Fatal Error +Závažná chyba Feedback and suggestions are welcome at: Komentáře a námÄ›ty zasÃlejte na: File %x has an invalid date! @@ -466,12 +462,14 @@ Files/folders that exist on right side only Soubory/adresáře, které existujà pouze vpravo Filter Filtr -Filter active: Press again to deactivate -Filtr aktivnÃ: KliknÄ›te znovu pro deaktivaci Filter files Filtrovat soubory +Filter has been selected +Filtr je zapnut Filter view Filtrovat seznam +Filtering is deactivated +Filtr je vypnut Folder Comparison and Synchronization Porovnánà a Synchronizace adresářů Free disk space available: @@ -494,6 +492,8 @@ Generating database... Vytvářenà databáze... Generating file list... Vytvářenà seznamu souborů... +Global filter +Globálnà filtr Global settings Nastavenà programu Help @@ -504,6 +504,8 @@ Hide all error and warning messages Skrýt vÅ¡echny chyby a varovánà Hide conflicts Skrýt konflikty +Hide excluded items +Skrýt vynechané položky Hide files that are different Skrýt rozdÃlné soubory Hide files that are equal @@ -530,14 +532,16 @@ Hide files that will be overwritten on right side Skrýt soubory, které budou vpravo pÅ™epsány Hide files that won't be copied Skrýt soubory, které nebudou kopÃrovány -Hide filtered items -Skrýt filtrované soubory +Hide filtered or temporarily excluded files +Skrýt filtrované nebo doÄasnÄ› vynechané soubory Hide further error messages during the current process Nezobrazovat dalÅ¡Ã chybová hlášenà bÄ›hem zpracovánà Hints: NápovÄ›da: Homepage Homepage +Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically. +Rozpoznat a provést zmÄ›ny na obou stranách pomocà databáze. OdstranÄ›né soubory a konflikty budou detekovány automaticky. If you like FFS Pokud se Vám FSS lÃbà Ignore 1-hour file time difference @@ -552,6 +556,8 @@ Ignore this error, retry or abort? Ignorovat chybu, opakovat nebo pÅ™eruÅ¡it? Include PÅ™idat +Include all rows +PoužÃt vÅ¡echny řádky Include temporarily PÅ™idat doÄasnÄ› Include: *.doc;*.zip;*.exe\nExclude: temp\\* @@ -562,8 +568,8 @@ Info Info Information Informace -Initial synchronization. -Prvotnà synchronizace. +Initial synchronization: +Prvotnà synchronizace: Integrate external applications into context menu. The following macros are available: Integrace externà aplikace do kontextového menu. K dispozici jsou následujÃcà makra: It was not possible to initialize the Recycle Bin!\n\nIt's likely that you are not using Windows.\nIf you want this feature included, please contact the author. :) @@ -578,6 +584,8 @@ Load configuration from file NaÄÃst konfiguraci ze souboru Load configuration history (press DEL to delete items) NaÄÃst historii konfigurace (pomocà DEL můžete položku smazat) +Local filter +MÃstnà filtr Log-messages: Záznamy: Logging @@ -602,8 +610,8 @@ Moving folder %x to user-defined directory %y PÅ™esouvánà adresáře %x do uživatelského adresáře %y Multiple... NÄ›kolikanásobný... -No database file existing yet: -SynchronizaÄnà databáze jeÅ¡tÄ› neexistuje: +No filter selected +Nenà vybrán žádný filtr Not enough free disk space available in: Nedostatek mÃsta na disku: Nothing to synchronize according to configuration! @@ -638,8 +646,8 @@ Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) i ProsÃm zkopÃrujte odpovÃdajÃcà \"Shadow.dll\" (umÃstÄ›ný v \"Shadow.zip\") do instalaÄnÃho adresáře FreeFileSync, aby bylo možné použÃt tuto funkci. Please fill all empty directory fields. Zadejte adresáře pro synchronizaci. -Press button to activate filter -KliknutÃm aktivujete filtr +Please run a Compare first before synchronizing! +ProsÃm proveÄte nejdÅ™Ãv porovnánà pÅ™ed synchronizacÃ! Published under the GNU General Public License: Vydáno podl GNU General Public License (GPL): Question @@ -660,12 +668,16 @@ Remove folder Odstranit adresář Remove folder pair Odstranit dvojici adresářů +Remove local filter settings +Odstranit nastavenà mÃstnÃho filtru Report translation error Hlásit chyby pÅ™ekladu Reset Resetovat Right Pravý +Run minimized and write status information to a logfile +Spustit minimalizovaný a zapisovat informace do souboru S&ave configuration &Uloženà konfigurace S&witch view @@ -680,14 +692,14 @@ Scanning: Zpracováváno: Select a folder Vyberte adresář -Select alternate filter settings -Vyberte alternativnà nastavenà filtru Select alternate synchronization settings Vyberte alternativnà nastavenà synchronizace Select logfile directory: Vyberte adresář pro záznamy: Select variant: Vyberte variantu: +Setting default synchronization directions. Please check whether they are appropriate for you. +Nastaven výchozà způsob synchronizace. ProsÃm zkontrolujte, zda odpovÃdá VaÅ¡im požadavkům. Show conflicts Zobrazit konflikty Show file icons @@ -732,6 +744,8 @@ Size Velikost Source code written completely in C++ utilizing: Zdrojový kód byl napsán kompletnÄ› v C++ s pomocÃ: +Source directory does not exist anymore: +Zdrojový adresář již neexistuje: Speed: Rychlost: Start @@ -772,8 +786,12 @@ Target directory already existing! CÃlový adresář již existuje! Target file already existing! CÃlový soubor již existuje! +The database file is not yet existing, but will be created during synchronization: +Databáze jeÅ¡tÄ› neexistuje, ale bude bÄ›hem synchronizace vytvoÅ™ena: The file does not contain a valid configuration: Soubor neobsahuje platnou konfiguraci: +The required database entry is not yet existing, but will be created during synchronization: +Požadovaný záznam v databázi jeÅ¡tÄ› neexistuje, ale bude bÄ›hem synchronizace vztvoÅ™en: This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. Tato varianta vyhodnotà dva stejnÄ› pojmenované soubory jako shodné pokud majà i stejnou velikost A ZÃROVEŇ i datum a Äas poslednà zmÄ›ny. Time @@ -798,8 +816,6 @@ Unable to create logfile! nenà možné vytvoÅ™it záznamový soubor! Unable to initialize Recycle Bin! Nenà možné použÃt KoÅ¡! -Uncheck all -OdznaÄit vÅ¡e Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization. NevyÅ™eÅ¡ené konflikty! \n\nJe možné konflikt ignorovat a pokraÄovat v synchronizaci. Update -> @@ -814,8 +830,6 @@ User-defined directory Uživatelsky definovaný adresář User-defined directory for deletion was not specified! Uživatelsky definovaný adresář pro mazánà nebyl zadán! -Using default synchronization directions. Please recheck. -Použito pÅ™eddefinované nastavenÃ. ProsÃm pÅ™ekontrolujte nastavenÃ. Variant Varianta Verifying file %x diff --git a/BUILD/Languages/dutch.lng b/BUILD/Languages/dutch.lng index bb19613a..c17049ba 100644 --- a/BUILD/Languages/dutch.lng +++ b/BUILD/Languages/dutch.lng @@ -156,10 +156,14 @@ About Informatie Action Actie +Activate filter +Activeer filter Add folder Map toevoegen Add folder pair Voeg 1 paar gekoppelde mappen toe +All directories in sync! +Alle paden zijn gesynchroniseerd! An exception occured! Er heeft een uitzondering plaatsgevonden! As a result the files are separated into the following categories: @@ -196,10 +200,6 @@ Category Categorie Change direction Zijdes omwisselen -Check all -Alles controleren -Choose to hide filtered files/directories from list -Gefilterde bestanden niet/wel weergeven Comma separated list Komma gescheiden lijst Commandline @@ -240,8 +240,6 @@ Configuration saved! Configuratie opgeslagen! Configure filter Configuratie filter -Configure filter... -Configuratie filter... Configure your own synchronization rules. Configureer uw eigen synchronisatieregels. Confirm @@ -327,13 +325,11 @@ Beschrijving Directories are dependent! Be careful when setting up synchronization rules: Mappen zijn afhankelijk van elkaar! Wees voorzichtig met het maken van synchronisatieregels: Directories to watch -Locaties om te controleren +Paden om te controleren Directory -Map +Pad Directory does not exist: -Map bestaat niet: -Do not display visual status information but write to a logfile instead -In plaats van visuele statusinformatie weergeven, alles naar een logbestand schrijven +Pad bestaat niet: Do not show this dialog again Deze melding niet meer weergeven Do nothing @@ -404,12 +400,12 @@ Error writing file: Er is een fout opgetreden bij het schrijven naar bestand: Error writing to synchronization database: Er is een fout opgetreden bij het schrijven naar de synchronisatie-database: -Source directory does not exist anymore: -De oorspronkelijke map bestaat niet meer: Example Voorbeeld Exclude Uitsluiten +Exclude all rows +Alle rijen uitsluiten Exclude temporarily Tijdelijk uitsluiten Exclude via filter: @@ -420,6 +416,8 @@ Exit with RC < 0 Afsluiten met RC < 0 External applications Externe applicaties +Fatal Error +Fatale fout Feedback and suggestions are welcome at: Tips en suggesties zijn welkom op: File %x has an invalid date! @@ -464,12 +462,14 @@ Files/folders that exist on right side only Bestanden/mappen die alleen aan de rechterkant bestaan Filter Filter -Filter active: Press again to deactivate -Filter actief: nogmaals klikken om uit te zetten Filter files Filter bestanden +Filter has been selected +Filter is geselecteerd Filter view Bekijk het filter +Filtering is deactivated +Filteren is uitgeschakeld Folder Comparison and Synchronization Mappen vergelijken en synchroniseren Free disk space available: @@ -492,6 +492,8 @@ Generating database... Database genereren... Generating file list... Bestandslijst genereren... +Global filter +Algemeen filter Global settings Algemene instellingen Help @@ -502,6 +504,8 @@ Hide all error and warning messages Verberg alle foutmeldingen en waarschuwingen Hide conflicts Verberg conflicten +Hide excluded items +Verberg uitgesloten items Hide files that are different Verberg bestanden die verschillend zijn Hide files that are equal @@ -528,14 +532,16 @@ Hide files that will be overwritten on right side Verberg bestanden die zullen worden overschreven aan de rechterkant Hide files that won't be copied Verberg bestanden die niet zullen worden gekopieerd -Hide filtered items -Verberg gefilterde items +Hide filtered or temporarily excluded files +Verberg gefilterde of tijdelijk uitgesloten bestanden Hide further error messages during the current process Volgende foutmeldingen niet meer weergeven tijdens de huidige handeling Hints: Tips: Homepage Homepage +Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically. +Identificeer en verwerk verandereringen aan beide kanten dmv een database. Verschillen en conflicten worden automatisch gedecteerd. If you like FFS Als het programma u bevalt Ignore 1-hour file time difference @@ -550,6 +556,8 @@ Ignore this error, retry or abort? Negeer deze fout, opnieuw proberen of de handeling afbreken? Include Gebruiken +Include all rows +Alle rijen gebruiken Include temporarily Tijdelijk bijsluiten Include: *.doc;*.zip;*.exe\nExclude: temp\\* @@ -560,8 +568,8 @@ Info Info Information Informatie -Initial synchronization. -Initiële synchronisatie. +Initial synchronization: +Initiële synchronisatie: Integrate external applications into context menu. The following macros are available: Integreer externe applicaties in het context menu. De volgende macros zijn beschikbaar: It was not possible to initialize the Recycle Bin!\n\nIt's likely that you are not using Windows.\nIf you want this feature included, please contact the author. :) @@ -576,6 +584,8 @@ Load configuration from file Laad configuratie uit bestand Load configuration history (press DEL to delete items) Laad configuratiegeschiedenis (druk op DEL om items te verwijderen) +Local filter +Lokaal filter Log-messages: Logberichten: Logging @@ -600,8 +610,8 @@ Moving folder %x to user-defined directory %y Verplaatsen map %x naar een door de gebruiker gedefinieerde locatie %y Multiple... Meerdere... -No database file existing yet: -Er bestaat nog geen database bestand: +No filter selected +Geen filter geselecteerd Not enough free disk space available in: Niet genoeg schijfruimte beschikbaar op: Nothing to synchronize according to configuration! @@ -636,8 +646,8 @@ Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) i Kopiëer alstublieft \"Shadow.dll\" (locatie in \"Shadow.zip\" archief) naar de FreeFileSync installatiemap om het gebruik van deze optie mogelijk te maken Please fill all empty directory fields. Vul alstublieft aan beide kanten een pad in. -Press button to activate filter -Druk op de knop om het filter te activeren. +Please run a Compare first before synchronizing! +Voer eerst een Vergelijking uit voordat u synchroniseerd. Published under the GNU General Public License: Gepubliceerd onder de GNU General Public License: Question @@ -658,12 +668,16 @@ Remove folder Verwijder map Remove folder pair Verwijder 1 paar gekoppelde mappen +Remove local filter settings +Verwijder lokale filter instellingen Report translation error Rapporteer een fout in de vertaling Reset Reset Right Rechts +Run minimized and write status information to a logfile +Tijdens het synchroniseren het venster minimaliseren en alle informatie opslaan in een log-bestand S&ave configuration S&la de instellingen op S&witch view @@ -678,14 +692,14 @@ Scanning: Scannen: Select a folder Selecteer een map -Select alternate filter settings -Selecteer alternatieve filter instellingen Select alternate synchronization settings Selecteer alternatieve synchronisatie instellingen Select logfile directory: Selecteer een map voor het logbestand: Select variant: Selecteer een variant: +Setting default synchronization directions. Please check whether they are appropriate for you. +De standaard synchronisatie-richtingen worden gebruikt. Controleer alstublieft of dit geschikt is voor u. Show conflicts Geef conflicten weer Show file icons @@ -730,6 +744,8 @@ Size Grootte Source code written completely in C++ utilizing: Broncode compleet geschreven in C++ met behulp van: +Source directory does not exist anymore: +De oorspronkelijke map bestaat niet meer: Speed: Snelheid: Start @@ -770,8 +786,12 @@ Target directory already existing! Doellocatie bestaal al! Target file already existing! Doelbestand bestaat al! +The database file is not yet existing, but will be created during synchronization: +Database-bestand bestaat nog niet, maar zal worden aangemaakt tijdens het synchroniseren: The file does not contain a valid configuration: Het bestand bevat geen geldige configuratie: +The required database entry is not yet existing, but will be created during synchronization: +De nodige database-informatie bestaan nog niet, maar zal worden aangemaakt tijdens synchroniseren: This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. Deze variant ziet twee gelijknamige bestanden als gelijk wanneer ze dezelfde bestandsgrootte EN tijdstempel hebben. Time @@ -796,8 +816,6 @@ Unable to create logfile! Niet mogelijk om een logbestand aan te maken! Unable to initialize Recycle Bin! De prullenbak kon niet worden geïnitialiseerd! -Uncheck all -Alles uitvinken Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization. Er bestaan onopgeloste conflicten! \n\nU kunt de conflicten negeren en doorgaan met synchroniseren. Update -> @@ -812,8 +830,6 @@ User-defined directory Door de gebruiker te definiëren locatie User-defined directory for deletion was not specified! Door de gebruiker te definiëren locatie voor verwijderen was niet opgegeven! -Using default synchronization directions. Please recheck. -De standaardrichting voor synchronisatie wordt gebruikt. Alstublieft opnieuw controleren. Variant Variant Verifying file %x diff --git a/BUILD/Languages/finnish.lng b/BUILD/Languages/finnish.lng new file mode 100644 index 00000000..d4b45c04 --- /dev/null +++ b/BUILD/Languages/finnish.lng @@ -0,0 +1,856 @@ + MinGW \t- Windows port of GNU Compiler Collection\n wxWidgets \t- Open-Source GUI framework\n wxFormBuilder\t- wxWidgets GUI-builder\n CodeBlocks \t- Open-Source IDE + MinGW \t- Windows port of GNU Compiler Collection\n wxWidgets \t- Open-Source GUI Framework\n wxFormBuilder\t- wxWidgets GUI-Builder\n CodeBlocks \t- Open-Source IDE + Byte + tavua + GB + GB + MB + MB + PB + PB + TB + TB + day(s) + päivää(e) + hour(s) + tunti(n) + kB + kB + min + Min. + sec + Sek. +%x / %y objects deleted successfully +%x / %y Kohteiden poisto onnistui +%x Percent +%x Prosenttia +%x directories +%x hakemistoja +%x files, +%x tiedostoja, +%x is not a valid FreeFileSync batch file! +%x ei kelvollinen FreeFileSync eräajotiedosto! +%x of %y rows in view +%x riviä %y rivistä näytössä +%x of 1 row in view +%x 1 rivistä näytössä +&Abort +&Keskeytä +&About... +&Ohje... +&Advanced +&Laajennettu +&Apply +&Käytä +&Cancel +&Lopeta +&Check for new version +Etsi &uusi versio +&Create batch job +&Tee eräajo +&Default +&Vakio +&Exit +&Poistu +&Export file list +&Vie tiedostojoukko +&File +&Tiedosto +&Global settings +&Yleiset asetukset +&Help +&Ohje +&Ignore +&Unohda +&Language +&Kieli +&Load +&Lataa +&Load configuration +Asetusten &lataus +&New +&Uusi +&No +&Ei +&OK +&OK +&Pause +&Keskeytä +&Quit +&Lopeta +&Restore +&Palauta +&Retry +&Uudestaan +&Save +&Tallenna +&Yes +&Kyllä +(Note that only FAT/FAT32 drives are affected by this problem!\nIn all other cases you can disable the setting \"ignore 1-hour difference\".) +(HUOM: Tämä ongelma vaikuttaa vain FAT/FAT32 ohjaimiin!\nOptio voidaan poistaa kaikissa muissa tapauksissa \"jätetään 1. tunnin ero huomiotta\".) +, +. +- Other side's counterpart to %dir +- Toisen puolen vastaavuus on %dir +- Other side's counterpart to %name +- Toisen puolen vastaavuus on %name +- conflict +- eroavuus +- conflict (same date, different size) +- eroavuus (sama päivämäärä, eri koko) +- different +- erilainen +- directory part only +- vain hakemistossa +- equal +- yhtenevät +- exists left only +- olemassa vain vasemmalla +- exists right only +- olemassa vain oikealla +- full file or directory name +- tiedoston tai hakemiston koko nimi +- left +- vasen +- left newer +- uudempi vasemmalla +- right +- oikea +- right newer +- uudempi oikealla +-Open-Source file synchronization- +-Open-Source tiedoston täsmäytys- +. +, +/sec +/s +1 directory +1 hakemisto +1 file, +1 tiedosto, +1. &Compare +1. &Vertaa +1. Enter relative file or directory names separated by ';' or a new line. +1. Anna tiedostojen tai hakemistojen suhteelliset nimet eroteltuina ';' tai rivivaihto +2. &Synchronize... +2. &Täsmäytä... +2. Use wildcard characters '*' and '?'. +2. Käytä jokerimerkkejä '*' ja '?' . +3. Exclude files directly on main grid via context menu. +3. Sulje tiedostoja pois suoraan pääikkunassa viite hakemiston avulla. +<Automatic> +<- Automaattinen -> +<Directory> +<Hakemisto> +<Last session> +<Edellinen istunto> +<multiple selection> +<monivalinta> +A newer version of FreeFileSync is available: +FreeFileSync:n uusi versio on olemassa: +Abort requested: Waiting for current operation to finish... +Ohjelma on lopetettava: Odotetaan toiminnon lopettamista... +Aborted +Keskeytetty +About +Ohje +Action +Suorita +Activate filter +Käynnistä suodatus +Add folder +Lisää hakemisto +Add folder pair +Lisää hakemistopari +All directories in sync! +Kaikki hakemistot täsmäävät! +An exception occured! +Virhe havaittu! +As a result the files are separated into the following categories: +Tiedoston on avattu seuraaviin luokkiin: +As the name suggests, two files which share the same name are marked as equal if and only if they have the same content. This option is useful for consistency checks rather than backup operations. Therefore the file times are not taken into account at all.\n\nWith this option enabled the decision tree is smaller: +Nimensä mukaisesti, tiedostot joilla on sama nimi, merkitään samoiksi vain jos niiden sisältö täsmää. Ominaisuus soveltuu paremmin yhdenpitävyyden tarkistukseen kuin varmistukseen. Siksi tiedostojen aikaleimaa ohitetaan.\n\nPäätöksentekopuu on tästä syystä pienempi: +Assemble a batch file for automated synchronization. To start in batch mode simply pass the name of the file to the FreeFileSync executable: FreeFileSync.exe <batchfile>. This can also be scheduled in your operating system's task planner. +Luo automaattiseen täsmäytykseen eräajon komentotiedosto. Käynnistä eräajo liittämällä FreeFileSyn ohjelmalle komentotiedosto: FreeFileSync.exe <eräajotiedosto>. Tehtävän suoritusta voit ajoittaa käyttöjärjestelmän toimilla. +Auto-adjust columns +Säädä sarakeleveys automaattisesti +Automatic mode +Automaattinen toimi +Batch execution +Eräajo +Batch file created successfully! +Eräajotiedosto luotu onnistuneesti! +Batch job +Eräajo +Big thanks for localizing FreeFileSync goes out to: +Suuret kiitokset FreeFileSync:n kääntämisestä: +Both sides have changed since last synchronization! +Molemmat puolet muuttuneet edellisestä täsmäytyksestä! +Browse +Selaa +Build: +Luotu: +Cancel +Keskeytä +Cannot determine sync-direction: Changed filter settings! +Täsmäytys suunta on tuntematon: Muuta suodatusasetuksia! +Cannot determine sync-direction: No change since last synchronization! +Täsmäytys suunta on tuntematon: Ei muutoksia viimeisestä täsmäytyksestä! +Category +Luokka +Change direction +Vaihda suunta +Comma separated list +CSV-muotoinen lista +Commandline +Komentokehote +Commandline is empty! +Tyhjä komentokehote! +Compare +Vertaile +Compare both sides +Vertaileea puolet keskenään +Compare by \"File content\" +Vertaa: \"tietosisältöä\" +Compare by \"File size and date\" +Vertaa: \"tiedoston koko ja -päiväys\" +Compare by... +Vertaile... +Comparing content +Vertaa tietosisältöä +Comparing content of files %x +Vertaa tiedostojen %x tietosisältöä +Comparing content... +Tietosisällön vertailu... +Comparing files by content failed. +Tietosisällön vertailu epäonnistui. +Comparison Result +Vertailun tulos +Comparison settings +Vertailun asetukset +Completed +Valmis +Configuration +Asetukset +Configuration loaded! +Asetukset ladattu! +Configuration overview: +Asetukset: +Configuration saved! +Asetukset tallennettu! +Configure filter +Aseta suodatus +Configure your own synchronization rules. +Määrittele oma täsmäytyssääntö. +Confirm +Vahvista +Conflict detected: +Ristiriita todettu: +Conflicts/files that cannot be categorized +Ristiriita/tiedostoja joita ei voida luokitella +Continue +Jatka +Conversion error: +Konversio virhe: +Copy from left to right +Kopioidaan vasen -> oikea +Copy from left to right overwriting +Kopioidaan vasen -> oikea ylikirjoittaen +Copy from right to left +Kopioidaan oikea -> vasen +Copy from right to left overwriting +Kopioidaan oikea -> vasen ylikirjoittaen +Copy new or updated files to right folder. +Kopioidaan uudet tai muuttuneet tiedostot oikeaan hakemistoon. +Copy to clipboard\tCTRL+C +Kopioi Leikepöydälle\tCTRL+C +Copying file %x to %y +Kopioidaan tiedostoa %x -> %y +Copying file %x to %y overwriting target +Kopioidaan tiedostoa %x -> %y ylikirjoittaen +Could not determine volume name for file: +Levyasemaa ei tunnistettu tiedostolle: +Could not initialize directory monitoring: +Ei voitu käynnistää hakemiston tarkkailua: +Could not read values for the following XML nodes: +Tietoja lukeminen epäonnistui, XML jäsen: +Create a batch job +Eräajon luonti +Creating folder %x +Luo hakemisto %x +Current operation: +Tämä toiminto: +Custom +Oma määritelmä +Customize columns +Sovita sarake +Customize... +Sovita... +D-Click +Klikkaa D +DECISION TREE +PÄÄTÖSPUU +Data remaining: +Dataa jäljellä: +Data verification error: Source and target file have different content! +Tiedon varmennusvirhe: Lähteellä ja kohteella on eri sisältö! +Date +Päiväys +Delay +Viive +Delay between detection of changes and execution of commandline in seconds +Viive sekunneissa havaitun muutoksen ja komentokehotteen suorittamisen välillä +Delete files/folders existing on left side only +Poista vain tiedostoja/hakemistoja vasemmalta +Delete files/folders existing on right side only +Poista vain tiedostoja/hakemistoja oikealta +Delete files\tDEL +Poista tiedostoja\tDEL +Delete on both sides +Poista molemmilta puolilta +Delete on both sides even if the file is selected on one side only +Poista molemmilta puolilta vaikka tiedosto valittu vain toisella puolella +Delete or overwrite files permanently. +Poista tai ylikirjoita tiedostoja pysyvästi +Delete permanently +Poista pysyvästi +Deleting file %x +Poista tiedosto %x +Deleting folder %x +Poista hakemisto %x +Deletion handling +Poistotapa +Description +Seloste +Directories are dependent! Be careful when setting up synchronization rules: +Hakemistot riippuvuussuhteessa! Aseta täsmäytyssääntöjä varovasti: +Directories to watch +Tarkkailtavat hakemistot +Directory +Hakemisto +Directory does not exist: +Puuttuva hakemisto: +Do not show this dialog again +Älä näytä tätä jatkossa +Do nothing +Älä tee mitään +Do you really want to delete the following objects(s)? +Haluatko varmasti poista valittuja kohteita? +Do you really want to move the following objects(s) to the Recycle Bin? +Haluatko varmasti siirtää valittuja kohteita Roskakoriin? +Do you want FreeFileSync to automatically check for updates every week? +Haluatko että FreeFileSync hakee päivityksiä automaattisesti viikoittain? +Donate with PayPal +Lahjoita PayPal:lla +Download now? +Lataa nyt? +Drag && drop +Vedä ja pudota +Email +S-posti +Enable filter to exclude files from synchronization +Aktivoi tiedostojen täsmäytyksen suodattimia +Endless loop when traversing directory: +Suorita hakemiston läpikulku jatkuvana: +Error +Virhe +Error changing modification time: +Virhe muuttaessa tiedoston aikaa: +Error copying file: +Virhe kopioitaessa tiedostoa: +Error copying locked file %x! +Virhe kopioitaessa lukittua tiedostoa %x! +Error creating directory: +Virhe tapahtui hakemistoa luotassa: +Error deleting directory: +Virhe poistettaessa hakemistoa: +Error deleting file: +Virhe poistettaessa tiedostoa: +Error handling +Virhe käsitellessä +Error loading library function: +Virhe ladattaessa kirjastotoimintoa: +Error moving directory: +Virhe siirtäessä hakemistoa: +Error moving file: +Virhe siirtäessä tiedostoa: +Error moving to Recycle Bin: +Virhe siirtäessä Roskakoriin: +Error opening file: +Virhe avatessa tiedostoa: +Error parsing configuration file: +Virhe jäsentäessä asetustiedostoa: +Error reading file attributes: +Virhe lukiessa tiedoston ominaisuuksia: +Error reading file: +Virhe lukiessa tiedostoa: +Error reading from synchronization database: +Virhe lukiessa täsmäytyksen tietokantaa: +Error resolving symbolic link: +Virhe selvittäessä symbolista linkkiä: +Error starting Volume Shadow Copy Service! +Virhe käynnistäessä Volume Shadow Copy Service! +Error traversing directory: +Virhe hakemistoa läpikäydessä: +Error when monitoring directories. +Virhe seuratessa hakemistoa. +Error writing file attributes: +Virhe kirjottaessa tiedosto ominaisuuksia: +Error writing file: +Virhe kirjottaessa tiedosto: +Error writing to synchronization database: +Virhe kirjottaessa täsmäytyksen tietokantaa: +Example +Esimerkki +Exclude +Sulje pois +Exclude all rows +Sulje pois kaikki rivit +Exclude temporarily +Sulje pois tilapäisesti +Exclude via filter: +Sulje pois suotimella: +Exit immediately and set returncode < 0 +Välitön poistuminen ja aseta paluukoodi < 0 +Exit with RC < 0 +Poistu ja RC < 0 +External applications +Ulkopuolinen sovellus +Fatal Error +Kohtalokas virhe +Feedback and suggestions are welcome at: +Palaute ja ehdotukset saa lähettää: +File %x has an invalid date! +Tiedostolla %x on virheellinen päiväys! +File already exists. Overwrite? +Tiedosto on jo olemassa. Ylikirjoitetaanko? +File content +Tiedoston sisältö +File does not exist: +Tiedosto puuttuu: +File list exported! +Tiedosto lista viety! +File size and date +Tiedoston koko ja päiväys +Filename +Tiedostonimi +Files %x have a file time difference of less than 1 hour!\n\nIt's not safe to decide which one is newer due to Daylight Saving Time issues. +Tiedostojen %x aikaleima poikkeaa alle tunnin!\n\nEi voida päättää turvallisesti, kesäajan takia, kumpi on uudempi. +Files %x have the same date but a different size! +Tiedostot %x samalta päivältä mutta koko poikkeaa! +Files are found equal if\n - file content\nis the same. +Tiedostot samat jos, \n - tiedoston sisältö\non sama. +Files are found equal if\n - filesize\n - last write time and date\nare the same. +Tiedosto samat jos, \n - koko\n - viimeinen aikaleima\non sama. +Files remaining: +Tiedostoja jäljellä: +Files that are equal on both sides +Tiedosto sama molemmilla puolilla +Files that exist on both sides and have different content +Tiedosto löytyy molemmilla puolilla mutta eri sisältö +Files that exist on both sides, left one is newer +Tiedosto löytyy molemmilla puolilla, vasen on uudempi +Files that exist on both sides, right one is newer +Tiedosto löytyy molemmilla puolilla, oikea on uudempi +Files/folders found: +Löydetty tiedostoja/hakemistoja: +Files/folders remaining: +Tiedostoja/hakemistoja jäljellä: +Files/folders that exist on left side only +Tiedostoja/hakemistoja vain vasemmalla +Files/folders that exist on right side only +Tiedostoja/hakemistoja vain oikealla +Filter +Suodatin +Filter files +Suodata tiedostoja +Filter has been selected +Suodin valittu +Filter view +Näytä suodattimet +Filtering is deactivated +Suodatus pois päältä +Folder Comparison and Synchronization +Hakemistojen vertailu ja täsmäytys +Free disk space available: +Levytilaa jäljellä: +FreeFileSync - Folder Comparison and Synchronization +FreeFileSync - hakemisto vertailu ja täsmäytys +FreeFileSync Batch Job +FreeFileSync Eräajo +FreeFileSync at Sourceforge +FreeFileSync Sourceforge:lla +FreeFileSync batch file +FreeFileSync eräajotiedosto +FreeFileSync configuration +FreeFileSync asetukset +FreeFileSync is up to date! +FreeFileSync on ajan tasalla! +Full path +Koko polku +Generating database... +Luodaan tietokantaa... +Generating file list... +Luodaan tiedostolista... +Global filter +Globaali suodin +Global settings +Yleiset asetukset +Help +Ohje +Hidden dialogs: +Piilotukset: +Hide all error and warning messages +Piilota kaikki virhe- ja varoitusviestit +Hide conflicts +Piilota ristiriidat +Hide excluded items +Piilota suodatetut +Hide files that are different +Piilota erilaiset tiedostot +Hide files that are equal +Piilota yhteneväiset tiedostot +Hide files that are newer on left +Piilota tiedostot jotka ovat uudempia vasemmalla +Hide files that are newer on right +Piilota tiedostot jotka ovat uudempia oikealla +Hide files that exist on left side only +Piilota tiedostot jotka ovat vain vasemmalla +Hide files that exist on right side only +Piilota tiedostot jotka ovat voin oikealla +Hide files that will be created on the left side +Piilota tiedostot jotka ovat luotu vasemmalla +Hide files that will be created on the right side +Piilota tiedostot jotka ovat luotu oikealla +Hide files that will be deleted on the left side +Piilota tiedostot jotka ovat poistettu vasemmalla +Hide files that will be deleted on the right side +Piilota tiedostot jotka ovat poistettu oikealla +Hide files that will be overwritten on left side +Piilota tiedostot jotka on ylikirjoitettu vasemmalla +Hide files that will be overwritten on right side +Piilota tiedostot jotka on ylikirjoitettu oikealla +Hide files that won't be copied +Piilota tiedostot jotka eivät kopioidu +Hide filtered or temporarily excluded files +Piilota suodatetut ja tilapäisesti poistetut +Hide further error messages during the current process +Piilota toistuvat virheet tässä suorituksessa +Hints: +Vihje: +Homepage +Kotisivu +Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically. +Tunnista ja monista muutokset molemmilla puolilla tietokannalla. Poistot ja ristiriidat hoidetaan automaattisesti. +If you like FFS +Jos pidät FFS:tä +Ignore 1-hour file time difference +Älä huomioi 1n tunnin poikkeamaa +Ignore errors +Älä huomioi virheitä +Ignore subsequent errors +Jätä huomioimatta toistuvia virheitä +Ignore this error, retry or abort synchronization? +Jätä virhe huomiotta, kokeile uudestaan tai keskeytä täsmäytys? +Ignore this error, retry or abort? +Jätä virhe huomiotta, kokeile uudestaan tai keskeytä? +Include +Sisällytä +Include all rows +Sisällytä kaikki rivit +Include temporarily +Sisällytä tilapäisesti +Include: *.doc;*.zip;*.exe\nExclude: temp\\* +Sisällytä: *.doc;*.zip;*.exe\nSulje pois: temp\\* +Incompatible synchronization database format: +Täsmäytyksen tietokannan muoto on virheellinen: +Info +Info +Information +Tietoja +Initial synchronization: +Ensi täsmäytys: +Integrate external applications into context menu. The following macros are available: +Liitä ulkoinen sovellus viitekehysvalikkoon. Seuraavat makrot ovat valittavissa: +It was not possible to initialize the Recycle Bin!\n\nIt's likely that you are not using Windows.\nIf you want this feature included, please contact the author. :) +Roskakorin alustus epäonnistui!\n\nIlmeisesti et käytä Microsoft Windowsia.\nJos haluat liittää tämän toiminnon, ota yhteyttä tekijää. :) +Leave as unresolved conflict +Jätä ratkaisemattomana virheenä +Left +Vasen +Legend +Selite +Load configuration from file +Lataa asetuksia tiedostosta +Load configuration history (press DEL to delete items) +Lataa asetusten historia (DEL poistaa osia - paina DEL) +Local filter +Paikallinen suodin +Log-messages: +Lokin viestit: +Logging +Kirjaa +Mirror ->> +Peilaava ->> +Mirror backup of left folder: Right folder will be overwritten and exactly match left folder after synchronization. +Vasemman hakemiston varmuuskopio: Oikea ylikirjoitetaan ja on täsmäytyksen jälkeen vasemman tarkka kopio. +More than 50% of the total number of files will be copied or deleted! +Enemmän kuin 50% tiedostoista kopioidaan tai poistetaan! +Move column down +Siirrä sarake alas +Move column up +Siirrä sarake ylös +Move files to a user-defined directory. +Tiedostojen siirto valittuun hakemistoon +Moving %x to Recycle Bin +Siirrä %x Roskakoriin +Moving file %x to user-defined directory %y +Siirretään tiedostoa %x valittuun hakemistoon %y +Moving folder %x to user-defined directory %y +Siirrä hakemisto %x valittuun hakemistoon %y +Multiple... +Moninkertainen... +No filter selected +Suodin valitsematta +Not enough free disk space available in: +Levytila ei riitä: +Nothing to synchronize according to configuration! +Asetusten mukaan ei löydy täsmäytettävää ! +Number of files and directories that will be created +Kirjataan tiedostojen ja hakemistojen lukumäärää +Number of files and directories that will be deleted +Poistetaan tiedostojen ja hakemistojen lukumäärää +Number of files that will be overwritten +Ylikirjoitettavien tiedostojen ja hakemistojen lukumäärä +OK +OK +Only files/directories that pass filtering will be selected for synchronization. The filter will be applied to the name relative(!) to the base synchronization directories. +Täsmäytykseen valitaan vain suodatetut tiedostot/hakemistot. Suodatus suoritetaan täsmäytyksen perus hakemistojen mukaisiin suhteellisiin nimiin. +Open directly +Suora avaus +Open with Explorer +Avaa Explorerilla +Open with Konqueror +Avaa Konquerorilla +Operation aborted! +Toiminto keskeytetty! +Operation: +Toiminto: +Overview +Yleiskatsaus +Pause +Tauko +Paused +Pysäytetty +Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) into the FreeFileSync installation directory to enable this feature. +Kopioi tiedosto \"Shadow.dll\" (tiedostossa \"Shadow.zip\") FreeFileSync asennushakemistossa. +Please fill all empty directory fields. +Täytä kaikki tyhjät hakemistokentät. +Please run a Compare first before synchronizing! +Aja tarkistus ennen täsmäytystä. +Published under the GNU General Public License: +Julkaistu lisenssillä GNU General Public License: +Question +Kysymys +Quit +Lopeta +Re-enable all hidden dialogs? +Ota uudestaan käyttöön piilotetut? +RealtimeSync - Automated Synchronization +RealtimeSync - Automaattinen täsmäytys +RealtimeSync configuration +RealtimeSync Asetukset +Relative path +Suhteellinen polku +Remove alternate settings +Poista toinen asetus +Remove folder +Poista hakemisto +Remove folder pair +Poista hakemistopari +Remove local filter settings +Poista paikalliset suotimet +Report translation error +Ilmoita käännösvirheestä +Reset +Palauta +Right +Oikea +Run minimized and write status information to a logfile +Suorita pienenettynä vie status tiedot lokiin +S&ave configuration +Asetukset t&allennetaan +S&witch view +Vaihda &näkymää +Save changes to current configuration? +Tallenna asetuksiin tehdyt muutokset? +Save current configuration to file +Tallenna nämä asetukset tiedostoon +Scanning... +Haen tiedostoja... +Scanning: +Haen: +Select a folder +Valitse hakemisto +Select alternate synchronization settings +Valitse toiset täsmäytys aseetukset +Select logfile directory: +Hakemisto lokitiedostoille: +Select variant: +Valitse vaihtoehto: +Setting default synchronization directions. Please check whether they are appropriate for you. +Oletus täsmäytys kansioille valittu. Tarkista soveltuvuus. +Show conflicts +Näytä ristiriidat +Show file icons +Näytä tiedostokuvakkeet +Show files that are different +Näytä poikkeavat tiedostot +Show files that are equal +Näytä yhtenevät tiedostot +Show files that are newer on left +Näytä uudemmat tiedostot vasemmalla +Show files that are newer on right +Näytä uudemmat tiedostot oikealla +Show files that exist on left side only +Näytä vain vasemmalla esiintyvät tiedostot +Show files that exist on right side only +Näytä vain oikealla esiintyvät tiedostot +Show files that will be created on the left side +Näytä vasemmalle luotavat tiedostot +Show files that will be created on the right side +Näytä oikealle luotavat tiedostot +Show files that will be deleted on the left side +Näytä vasemmalla poistettavat tiedostot +Show files that will be deleted on the right side +Näytä oikealla poistettavat tiedostot +Show files that will be overwritten on left side +Näytä vasemmalla ylikirjoitettavat tiedostot +Show files that will be overwritten on right side +Näytä oikealla ylikirjoitettavat tiedostot +Show files that won't be copied +Näytä kopioimatta jäävät tiedostot +Show hidden dialogs +Näytä piilotetut dialogit +Show popup +Näytä Popup +Show popup on errors or warnings +Näytä virheet ja varoitukset Popupissa +Significant difference detected: +Merkittävä eroavaisuus todettu: +Silent mode +Hiljainen suoritus +Size +Koko +Source code written completely in C++ utilizing: +Lähdekoodi kirjoitettu kokonaan C++ käyttäen: +Source directory does not exist anymore: +Lähdehakemisto puuttuu: +Speed: +Nopeus: +Start +Käynnistä +Start synchronization +Käynnistä täsmäytys +Statistics +Tilastot +Stop +Stop +Swap sides +Puolten vaihto +Synchronization Preview +Täsmäytyksen esikatselu +Synchronization aborted! +Täsmäytys keskeytetty! +Synchronization completed successfully! +Täsmäytys suoritettu onnistuneesti! +Synchronization completed with errors! +Täsmäytys päättyi virheisiin! +Synchronization settings +Täsmäytyksen asetukset +Synchronization status +Täsmäytyksen status +Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\". +Täsmäytä kaikki .doc, .zip und .exe tiedostot paitsi hakemistossa \"temp\" oleva. +Synchronize both sides simultaneously: Copy new or updated files in both directions. +Täsmäytetään molemmat puolet: Kopioidaan uudet tai päivitetyt tiedostot molempiin hakemistoihin. +Synchronize both sides using a database. Deletions are detected automatically. +Täsmäytetään molemmat puolet käyttäen tietokantaa. Poistot suoritetaan automaattisesti. +Synchronize... +Täsmäytä... +Synchronizing... +Täsmäytetään... +System out of memory! +Järjestelmän muisti loppui! +Target directory already existing! +Haluttu tiedosto on jo olemassa! +Target file already existing! +Kohde tiedosto on jo olemassa! +The database file is not yet existing, but will be created during synchronization: +Tietokanta puuttuu, luodaan täsmäytyksen aikana. +The file does not contain a valid configuration: +Asetustiedosto ei ole kelvollinen: +The required database entry is not yet existing, but will be created during synchronization: +Tarvittava alkio puuttuu tietokannasta, se luodaan täsmäytyksen aikana: +This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. +Tämä vaihtoehto todennetaan kaksi samannimistä tiedostoa samaksi, jos koko JA viimeinen tallennusaika on sama. +Time +Aika +Time elapsed: +Kulunut aika: +Time remaining: +Aikaa jäljellä: +Total amount of data that will be transferred +Siirrettävän datan määrä +Total required free disk space: +Vaadittu vapaa levytila: +Total time: +Kokonaisaika: +Treat file times that differ by exactly +/- 1 hour as equal, less than 1 hour as conflict in order to handle Daylight Saving Time changes. +Kohtele tiedostoja jolla aikaleima on tasan +/- tunti samoina, korjaa kesäajan siirtoa. +Two way <-> +Molempiin suuntiin <-> +Unable to connect to sourceforge.net! +Kytkeytyminen ei onnistu kohteeseen sourceforge.net! +Unable to create logfile! +Lokitiedostoa ei pystytä luomaan! +Unable to initialize Recycle Bin! +Roskakorin initialisointi ei onnistu! +Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization. +Ristiriita sovittamatta! \n\nVoit ohittaa ristiriita ja jatkaa täsmäytystä. +Update -> +Päivittävä -> +Usage: Select directories for monitoring and enter a commandline. Each time files are modified within these directories (or subdirectories) the commandline is executed. +Käyttö: Valitse hakemistot ja aseta komento. Jos tiedostojen sisältö muuttuu (myös alihakemistot) suoritetaan komento. +Use Recycle Bin +Käytä Roskakoria +Use Recycle Bin when deleting or overwriting files. +Käytä Roskakoria kun poistat tai ylikirjoitat tiedostoja. +User-defined directory +Käytä valittua hakemistoa +User-defined directory for deletion was not specified! +Hakemistoa ei valittu poistolle! +Variant +Vaihtoehto +Verifying file %x +Tarkistan tiedosto %x +Volume name %x not part of filename %y! +Osan nimi %x ei esiinny tiedostonimessä %y! +Warning +Varoitus +Warning: Synchronization failed for %x item(s): +Varoitus: täsmäytys epäonnistui %x kohdassa: +When the comparison is started with this option set the following decision tree is processed: +Käynnistäessä täsmäytystä näillä asetuksilla ottaa käyttöön tämä päätöspuu: +You can ignore the error to consider not existing directories as empty. +Sivuta virhe ja kohtele puuttuvat hakemistot tyhjinä. +You can ignore the error to skip current folder pair. +Sivuta virhe ja hylkää tämä hakemistopari. +You may try to synchronize remaining items again (WITHOUT having to re-compare)! +Yritä täsmäytystä lopuille uudestaan (ILMAN uutta vertailua)! +different +erilaiset +file exists on both sides +tiedosto löytyy molemmilla puolilla +on one side only +vain yhdellä puolella diff --git a/BUILD/Languages/french.lng b/BUILD/Languages/french.lng index 52642e59..ad91f136 100644 --- a/BUILD/Languages/french.lng +++ b/BUILD/Languages/french.lng @@ -156,10 +156,14 @@ About A propos de Action Action +Activate filter +Activer le filtre Add folder Ajout d'un dossier Add folder pair Ajout d'un couple de dossiers +All directories in sync! +Tous les répertoires en synchro ! An exception occured! Une violation s'est produite ! As a result the files are separated into the following categories: @@ -196,10 +200,6 @@ Category Catégorie Change direction Changer la direction -Check all -Cocher tout -Choose to hide filtered files/directories from list -Masquer les fichiers/répertoires filtrés Comma separated list Liste d'éléments séparés par une virgule Commandline @@ -240,8 +240,6 @@ Configuration saved! Configuration enregistrée ! Configure filter Configuration des filtres -Configure filter... -Configuration des filtres... Configure your own synchronization rules. Paramétrage de vos règles de synchronisation. Confirm @@ -332,8 +330,6 @@ Directory Répertoire Directory does not exist: Le répertoire n'existe pas : -Do not display visual status information but write to a logfile instead -Ne pas afficher les informations d'état à l'écran mais les enregistrer plutôt dans un fichier log Do not show this dialog again Ne pas afficher cette boîte de dialogue Do nothing @@ -404,12 +400,12 @@ Error writing file: Erreur lors de l'écriture du fichier : Error writing to synchronization database: Erreur lors de l'écriture de la base de données de synchro : -Source directory does not exist anymore: -Le répertoire source n'existe plus : Example Exemple Exclude Exclure +Exclude all rows +Exclure toutes les lignes Exclude temporarily Exclure temporairement Exclude via filter: @@ -420,6 +416,8 @@ Exit with RC < 0 Sortie avec RC < 0 External applications Applications externes +Fatal Error +Erreur Fatale Feedback and suggestions are welcome at: Commentaires et suggestions sont les bienvenus à : File %x has an invalid date! @@ -464,12 +462,14 @@ Files/folders that exist on right side only Fichiers/répertoires existants seulement à droite Filter Filtrage -Filter active: Press again to deactivate -Filtrage actif : Cliquez de nouveau pour le désactiver Filter files Filtrage des fichiers +Filter has been selected +Le filtre a été sélectionné Filter view Filtrage de la vue +Filtering is deactivated +Le filtrage est désactivé Folder Comparison and Synchronization Comparaison de Dossiers et Synchronisation Free disk space available: @@ -492,6 +492,8 @@ Generating database... Génération de la base de données... Generating file list... Génération de la liste des fichiers... +Global filter +Filtre global Global settings Paramètres généraux Help @@ -502,6 +504,8 @@ Hide all error and warning messages Masquer tous les messages d'erreurs et les avertissements Hide conflicts Conflits sur le masquage +Hide excluded items +Masquer les éléments exclus Hide files that are different Masquer les fichiers différents Hide files that are equal @@ -528,14 +532,16 @@ Hide files that will be overwritten on right side Fichiers masqués qui ont été écrasés à droite Hide files that won't be copied Masquer les fichiers qui ne seront pas copiés -Hide filtered items -Masquer les éléments filtrés +Hide filtered or temporarily excluded files +Masquer les fichiers filtrés ou exclus temporairement Hide further error messages during the current process Masquer les messages d'erreur suivants pendant le traitement Hints: Conseils : Homepage Accueil +Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically. +Identifier et propager les modifications des deux côtés en utilisant une base de données. Les suppressions et les conflits sont détectés automatiquement. If you like FFS Si vous aimez FFS Ignore 1-hour file time difference @@ -550,6 +556,8 @@ Ignore this error, retry or abort? Ignorer l'erreur, réessayer ou abandonner ? Include Inclure +Include all rows +Inclure toutes les lignes Include temporarily Inclure temporairement Include: *.doc;*.zip;*.exe\nExclude: temp\\* @@ -560,8 +568,8 @@ Info Info Information Information -Initial synchronization. -Première synchronisation. +Initial synchronization: +Première synchronisation: Integrate external applications into context menu. The following macros are available: Inclure les applications externes dans le menu contextuel. Les macros suivantes sont disponibles : It was not possible to initialize the Recycle Bin!\n\nIt's likely that you are not using Windows.\nIf you want this feature included, please contact the author. :) @@ -576,6 +584,8 @@ Load configuration from file Charger la configuration à partir du fichier Load configuration history (press DEL to delete items) Charger l'historique des configuration (appuyez sur Suppr pour supprimer des éléments) +Local filter +Filtre local Log-messages: Messages log : Logging @@ -600,8 +610,8 @@ Moving folder %x to user-defined directory %y Déplacement du dossier %x vers le répertoire défini par l'utilisateur %y Multiple... Multiple... -No database file existing yet: -Aucun fichier base de données n'existe actuellement : +No filter selected +Aucun filtre sélectionné Not enough free disk space available in: Espace disque insuffisant sur : Nothing to synchronize according to configuration! @@ -636,8 +646,8 @@ Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) i Veuillez copier le fichier \"Shadow.dll\" (situé dans l'archive \"Shadow.zip\") vers le répertoire d'installation de FreeFileSync pour utiliser cette fonctionnalité. Please fill all empty directory fields. Veuillez remplir tous les champs vides du répertoire. -Press button to activate filter -Cliquez pour activer le filtrage +Please run a Compare first before synchronizing! +Veuillez cliquer sur "Compareré avant de lancer la synchronisation ! Published under the GNU General Public License: Publié sous la licence GNU General Public : Question @@ -658,12 +668,16 @@ Remove folder Supprimer le dossier Remove folder pair Supprimer le couple de dossiers +Remove local filter settings +Supprimer la configuration du filtre local Report translation error Etat d'erreurs de transfert Reset Réinitialiser Right Droite +Run minimized and write status information to a logfile +Exécution en mode réduit. Les informations d'état sont enregitrées dans un fichier .log S&ave configuration S&auvegarder la configuration S&witch view @@ -678,14 +692,14 @@ Scanning: Lecture en cours : Select a folder Choisissez un répertoire -Select alternate filter settings -Sélectionner une autre configuration du filtre Select alternate synchronization settings Sélectionner une autre configuration de la synchronisation Select logfile directory: Choisissez un dossier pour le fichier .log : Select variant: Choisissez une variante : +Setting default synchronization directions. Please check whether they are appropriate for you. +Configuration de synchronisation par défaut. Veuillez vérifiez si elles vous conviennent. Show conflicts Afficher les conflits Show file icons @@ -730,6 +744,8 @@ Size Taille Source code written completely in C++ utilizing: Code source écrit totalement en C++ et utilisant : +Source directory does not exist anymore: +Le répertoire source n'existe plus : Speed: Vitesse : Start @@ -770,8 +786,12 @@ Target directory already existing! Le répertoire de destination existe déjà ! Target file already existing! Le fichier de destination existe déjà ! +The database file is not yet existing, but will be created during synchronization: +La base de données n'existe pas encore, mais elle sera créée pendant la synchronisation : The file does not contain a valid configuration: Le fichier ne contient pas de configuration valide : +The required database entry is not yet existing, but will be created during synchronization: +L'entrée demandée de la base de données n'existe pas encore, mais elle sera créée pendant la synchronisation : This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. Cette variante définit comme identiques deux fichiers de même nom lorsqu'ils ont la même taille et le même date et heure de modification. Time @@ -796,8 +816,6 @@ Unable to create logfile! Impossible de créer un fichier log ! Unable to initialize Recycle Bin! Impossible d'initialiser la corbeille ! -Uncheck all -Décocher tout Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization. Il y a des conflits non résolus !\n\nVous pouvez ignorer ces conflits et continuer la synchronisation. Update -> @@ -812,8 +830,6 @@ User-defined directory Réoertoire défini par l'utilisateur User-defined directory for deletion was not specified! Le réoertoire défini par l'utilisateur pour la suppression n'a pas été indiqué ! -Using default synchronization directions. Please recheck. -Sens de la synchronisation par défaut. Veuillez revérifier. Variant Variante Verifying file %x diff --git a/BUILD/Languages/german.lng b/BUILD/Languages/german.lng index c94c1d8c..552019ed 100644 --- a/BUILD/Languages/german.lng +++ b/BUILD/Languages/german.lng @@ -46,6 +46,8 @@ &Abbrechen &Check for new version &Auf neuere Version prüfen +&Content +&Inhalt &Create batch job &Batch-Job erstellen &Default @@ -148,8 +150,6 @@ Konfiguration &laden <Mehrfachauswahl> A newer version of FreeFileSync is available: Eine neuere Version von FreeFileSync ist verfügbar: -ATTENTION: Failed directory access can lead to file deletions! -ACHTUNG: Fehler beim Verzeichniszugriff können zum Löschen von Dateien führen! Abort requested: Waiting for current operation to finish... Abbruch initiiert: Warte, bis aktuelle Operation beendet ist... Aborted @@ -158,10 +158,14 @@ About Ãœber Action Aktion +Activate filter +Aktiviere Filter Add folder Verzeichnis hinzufügen Add folder pair Verzeichnispaar hinzufügen +All directories in sync! +Alle Verzeichnisse sind synchron! An exception occured! Eine Ausnahme ist aufgetreten! As a result the files are separated into the following categories: @@ -198,16 +202,12 @@ Category Kategorie Change direction Richtung ändern -Check all -Alles auswählen -Choose to hide filtered files/directories from list -Gefilterte Dateien bzw. Verzeichnisse ein-/ausblenden Comma separated list Kommagetrennte Liste Commandline Befehlszeile Commandline is empty! -Die Kommandozeile ist leer! +Die Befehlszeile ist leer! Compare Vergleichen Compare both sides @@ -242,8 +242,6 @@ Configuration saved! Konfiguration gespeichert! Configure filter Konfiguriere Filter -Configure filter... -Konfiguriere Filter... Configure your own synchronization rules. Eigene Synchronisationsregeln definieren. Confirm @@ -264,6 +262,8 @@ Copy from right to left Von rechts nach links kopieren Copy from right to left overwriting Von rechts nach links kopieren und überschreiben +Copy locked files +Gesperrte Dateien kopieren Copy new or updated files to right folder. Neue oder aktualisierte Dateien vom linken in das rechte Verzeichnis kopieren. Copy to clipboard\tCTRL+C @@ -276,6 +276,8 @@ Could not determine volume name for file: Der Laufwerksname für folgende Datei konnte nicht ermittelt werden: Could not initialize directory monitoring: Die Verzeichnisüberwachung konnte nicht gestartet werden: +Could not load a required DLL: +Eine benötigte DLL konnte nicht geladen werden: Could not read values for the following XML nodes: Die folgenden XML Knoten konnten nicht gelesen werden: Create a batch job @@ -295,7 +297,7 @@ D-Klick DECISION TREE ENTSCHEIDUNGSBAUM Data remaining: -Verbliebene Daten: +Verbleibende Daten: Data verification error: Source and target file have different content! Verifizierungsfehler: Quell- und Zieldatei haben unterschiedlichen Inhalt! Date @@ -303,7 +305,7 @@ Datum Delay Verzögerung Delay between detection of changes and execution of commandline in seconds -Verzögerung zwischen Erkennen einer Änderung und Aufrufen der Kommandozeile in Sekunden +Verzögerung zwischen Erkennen einer Änderung und Aufrufen der Befehlszeile in Sekunden Delete files/folders existing on left side only Nur links existierende Dateien/Verzeichnisse löschen Delete files/folders existing on right side only @@ -334,8 +336,6 @@ Directory Verzeichnis Directory does not exist: Das Verzeichnis existiert nicht: -Do not display visual status information but write to a logfile instead -Keine graphischen Statusinformationen anzeigen, sondern eine Logdatei schreiben Do not show this dialog again Diesen Dialog nicht mehr anzeigen Do nothing @@ -406,12 +406,12 @@ Error writing file: Fehler beim Schreiben der Datei: Error writing to synchronization database: Fehler beim Schreiben der Synchronisationsdatenbank: -Source directory does not exist anymore: -Quellverzeichnis existiert nicht mehr: Example Beispiel Exclude Ausschließen +Exclude all rows +Alle Zeilen ausschließen Exclude temporarily Temporär ausschließen Exclude via filter: @@ -422,6 +422,8 @@ Exit with RC < 0 Beenden mit RC < 0 External applications Externe Anwendungen +Fatal Error +Fataler Fehler Feedback and suggestions are welcome at: Feedback und Vorschläge sind willkommen unter: File %x has an invalid date! @@ -447,7 +449,7 @@ Dateien gelten als gleich, wenn\n - der Inhalt\ngleich ist. Files are found equal if\n - filesize\n - last write time and date\nare the same. Dateien gelten als gleich, wenn\n - die Größe\n - Datum und Uhrzeit der letzten Änderung\ngleich sind. Files remaining: -Verbliebene Dateien: +Verbleibende Dateien: Files that are equal on both sides Auf beiden Seiten gleiche Dateien Files that exist on both sides and have different content @@ -459,19 +461,21 @@ Auf beiden Seiten existierende Dateien; rechte Datei ist neuer Files/folders found: Gefundene Dateien/Ordner: Files/folders remaining: -Verbliebene Dateien/Ordner: +Verbleibende Dateien/Ordner: Files/folders that exist on left side only Nur links exisitierende Dateien/Verzeichnisse Files/folders that exist on right side only Nur rechts exisitierende Dateien/Verzeichnisse Filter Filter -Filter active: Press again to deactivate -Filter aktiviert: Zum Deaktivieren erneut anwählen Filter files Dateien filtern +Filter has been selected +Filter ist ausgewählt Filter view Ansicht filtern +Filtering is deactivated +Filter ist deaktiviert Folder Comparison and Synchronization Verzeichnisvergleich und Synchronisation Free disk space available: @@ -494,6 +498,8 @@ Generating database... Erzeuge Synchronisationsdatenbank... Generating file list... Erzeuge Dateiliste... +Global filter +Globaler Filter Global settings Globale Einstellungen Help @@ -504,6 +510,8 @@ Hide all error and warning messages Alle Fehler- und Warnmeldungen werden unterdrückt Hide conflicts Konflikte ausblenden +Hide excluded items +Ausgeschlossene Elemente verstecken Hide files that are different Ungleiche Dateien ausblenden Hide files that are equal @@ -530,14 +538,16 @@ Hide files that will be overwritten on right side Dateien die rechts überschrieben werden ausblenden Hide files that won't be copied Dateien die nicht kopiert werden ausblenden -Hide filtered items -Gefilterte Elemente ausblenden +Hide filtered or temporarily excluded files +Gefilterte oder temporär ausgeschlossene Dateien ausblenden Hide further error messages during the current process Weitere Fehlermeldungen während des laufenden Prozesses ausblenden Hints: Tipps: Homepage Homepage +Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically. +Identifiziere und propagiere Änderungen auf beiden Seiten mit Hilfe einer Datenbank. Löschungen und Konflikte werden automatisch erkannt. If you like FFS FFS unterstützen Ignore 1-hour file time difference @@ -552,6 +562,8 @@ Ignore this error, retry or abort? Fehler ignorieren, wiederholen oder abbrechen? Include Einschließen +Include all rows +Alle Zeilen einschließen Include temporarily Temporär einschließen Include: *.doc;*.zip;*.exe\nExclude: temp\\* @@ -562,8 +574,8 @@ Info Info Information Information -Initial synchronization. -Erstmalige Synchronisation. +Initial synchronization: +Erstmalige Synchronisation: Integrate external applications into context menu. The following macros are available: Integriert externe Anwendungen in das Kontextmenu. Die folgenden Makros stehen zur Verfügung: It was not possible to initialize the Recycle Bin!\n\nIt's likely that you are not using Windows.\nIf you want this feature included, please contact the author. :) @@ -578,6 +590,8 @@ Load configuration from file Konfiguration aus Datei laden Load configuration history (press DEL to delete items) Lade Konfigurationshistorie (DEL-Taste löscht Einträge) +Local filter +Lokaler Filter Log-messages: Protokollmeldungen: Logging @@ -602,8 +616,8 @@ Moving folder %x to user-defined directory %y Verschiebe Ordner %x in benutzerdefiniertes Verzeichnis %y Multiple... Verschiedene... -No database file existing yet: -Es existiert noch keine Datenbankdatei: +No filter selected +Kein Filter ausgewählt Not enough free disk space available in: Nicht genügend freier Speicher verfügbar unter: Nothing to synchronize according to configuration! @@ -634,12 +648,10 @@ Pause Pause Paused Angehalten -Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) into the FreeFileSync installation directory to enable this feature. -Um diese Funktionalität zu aktivieren, bitte die entsprechende Datei \"Shadow.dll\" (siehe Archiv \"Shadow.zip\") in das FreeFileSync Installationsverzeichnis kopieren. Please fill all empty directory fields. Bitte die leeren Verzeichnisfelder füllen. -Press button to activate filter -Taste drücken, um Filter zu aktivieren +Please run a Compare first before synchronizing! +Vor der Synchronisation bitte zuerst einen Vergleich ausführen! Published under the GNU General Public License: Veröffentlicht unter der GNU General Public License: Question @@ -660,12 +672,18 @@ Remove folder Verzeichnis entfernen Remove folder pair Verzeichnispaar entfernen +Remove local filter settings +Lokale Filtereinstellungen entfernen Report translation error Ãœbersetzungsfehler melden Reset Zurücksetzen Right Rechts +Run minimized and write status information to a logfile +Minimiert ausführen und Statusinformationen in eine Logdatei schreiben +Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version. +Das Erstellen von Schattenkopien unter WOW64 wird nicht unterstützt. Bitte benutzen Sie die FreeFileSync 64-Bit Version. S&ave configuration Konfiguration s&peichern S&witch view @@ -680,14 +698,14 @@ Scanning: Suche Dateien: Select a folder Verzeichnis auswählen -Select alternate filter settings -Alternative Filtereinstellungen auswählen Select alternate synchronization settings Alternative Synchronisationseinstellungen auswählen Select logfile directory: Verzeichnis für Logdatei wählen: Select variant: Variante auswählen: +Setting default synchronization directions. Please check whether they are appropriate for you. +Setze Standardsynchronisationsrichtungen. Bitte prüfen Sie, ob diese für Sie passend gewählt wurden. Show conflicts Konflikte zeigen Show file icons @@ -732,6 +750,8 @@ Size Größe Source code written completely in C++ utilizing: Sourcecode komplett in C++ geschrieben mit Hilfe von: +Source directory does not exist anymore: +Quellverzeichnis existiert nicht mehr: Speed: Geschwindigkeit: Start @@ -772,8 +792,12 @@ Target directory already existing! Zielverzeichnis existiert bereits! Target file already existing! Die Zieldatei existiert bereits! +The database file is not yet existing, but will be created during synchronization: +Die Datenbankdatei existiert noch nicht, wird jedoch während der Synchronisation erzeugt werden: The file does not contain a valid configuration: Die Datei enthält keine gültige Konfiguration: +The required database entry is not yet existing, but will be created during synchronization: +Der benötigte Datenbankeintrag existiert noch nicht, wird jedoch während der Synchronisation erzeugt werden. This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. Diese Variante identifiziert zwei gleichnamige Dateien als gleich, wenn sie die gleiche Dateigröße haben UND der Zeitpunkt der letzten Änderung derselbe ist. Time @@ -781,7 +805,7 @@ Uhrzeit Time elapsed: Vergangene Zeit: Time remaining: -Verbliebene Zeit: +Verbleibende Zeit: Total amount of data that will be transferred Gesamtmenge der zu übertragenden Daten Total required free disk space: @@ -798,24 +822,22 @@ Unable to create logfile! Die Protokolldatei konnte nicht erstellt werden! Unable to initialize Recycle Bin! Der Papierkorb konnte nicht initialisiert werden! -Uncheck all -Nichts auswählen Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization. Es existieren ungelöste Konflikte! \n\nDie Konflikte können ignoriert und die Synchronisation fortgesetzt werden. Update -> Aktualisieren -> Usage: Select directories for monitoring and enter a commandline. Each time files are modified within these directories (or subdirectories) the commandline is executed. -Verwendung: Die zu überwachenden Verzeichnisse auswählen und eine Kommandozeile angeben. Jedesmal wenn Dateien innerhalb dieser Verzeichnisse (oder Unterverzeichnisse) verändert werden, wird die Kommandozeile ausgeführt. +Verwendung: Die zu überwachenden Verzeichnisse auswählen und eine Befehlszeile angeben. Jedesmal wenn Dateien innerhalb dieser Verzeichnisse (oder Unterverzeichnisse) verändert werden, wird die Befehlszeile ausgeführt. Use Recycle Bin Papierkorb verwenden Use Recycle Bin when deleting or overwriting files. Papierkorb für zu löschende oder zu überschreibende Dateien nutzen. +Use Volume Shadow Copy Service to copy locked or shared files. +Verwende den Volume Shadow Copy Service um gesperrte oder gemeinsam verwendete Dateien zu kopieren. User-defined directory Benutzerdefiniertes Verzeichnis User-defined directory for deletion was not specified! Kein benutzerdefiniertes Verzeichnis zum Löschen angegeben! -Using default synchronization directions. Please recheck. -Die Standard-Synchronisationsrichtungen wurden gesetzt. Bitte überprüfen. Variant Variante Verifying file %x diff --git a/BUILD/Languages/hungarian.lng b/BUILD/Languages/hungarian.lng index 2fd4dfa1..ea6fccaa 100644 --- a/BUILD/Languages/hungarian.lng +++ b/BUILD/Languages/hungarian.lng @@ -156,10 +156,14 @@ About A programról Action Művelet +Activate filter +SzűrÅ‘ aktiválása Add folder Mappa hozzáadása Add folder pair Mappa pár megadása +All directories in sync! +Minden mappa szinkronban! An exception occured! Kivétel keletkezett! As a result the files are separated into the following categories: @@ -196,10 +200,6 @@ Category Kategória Change direction Irány megváltoztatása -Check all -Mindent kijelöl -Choose to hide filtered files/directories from list -Szűrt fájlok/mappák elrejtése a listában Comma separated list Comma separated values Commandline @@ -240,8 +240,6 @@ Configuration saved! BeállÃtások elmentve! Configure filter SzűrÅ‘ beállÃtása -Configure filter... -SzűrÅ‘ beállÃtása Configure your own synchronization rules. Saját szinkronizálási szabályok beállÃtása. Confirm @@ -332,8 +330,6 @@ Directory Mappa Directory does not exist: A mappa nem létezik: -Do not display visual status information but write to a logfile instead -Ne mutasd a vizuális állapotinformációkat, helyette naplózd Do not show this dialog again Ne mutasd újra ezt a párbeszédablakot Do nothing @@ -408,6 +404,8 @@ Example Példa Exclude Kizár +Exclude all rows +Minden sor kizárása Exclude temporarily Ideiglenesen kizár Exclude via filter: @@ -418,6 +416,8 @@ Exit with RC < 0 Kilépés (visszatérési érték < 0) External applications KülsÅ‘ alkalmazások +Fatal Error +Kritikus hiba Feedback and suggestions are welcome at: A visszajelzéseket és javaslatokat ide várjuk: File %x has an invalid date! @@ -462,12 +462,14 @@ Files/folders that exist on right side only Csak a jobb oldalon létezÅ‘ fájlok/mappák Filter SzűrÅ‘ -Filter active: Press again to deactivate -SzűrÅ‘ aktÃv: Nyomja meg újra a deaktiváláshoz Filter files Fájlok szűrése +Filter has been selected +SzűrÅ‘ kiválasztva Filter view SzűrÅ‘ nézet +Filtering is deactivated +A szűrés kikapcsolva Folder Comparison and Synchronization Mappa összehasonlÃtás és szinkronizáció Free disk space available: @@ -490,6 +492,8 @@ Generating database... Adatbázis generálása... Generating file list... Fájllista generálása... +Global filter +Globális szűrÅ‘ Global settings Globális beállÃtások Help @@ -500,6 +504,8 @@ Hide all error and warning messages Összes hibaüzenet és figyelmeztetés elrejtése Hide conflicts Ãœtközések elrejtése +Hide excluded items +A kizárt elemek elrejtése Hide files that are different A nem egyezÅ‘ fájlok elrejtése Hide files that are equal @@ -526,14 +532,16 @@ Hide files that will be overwritten on right side A jobb oldalon felülÃrandó fájlok elrejtése Hide files that won't be copied A nem másolandó fájlok elrejtése -Hide filtered items -A szűrt elemek elrejtése +Hide filtered or temporarily excluded files +A kiszűrt vagy ideiglenesen kizárt fájlok elrejtése Hide further error messages during the current process A további hibaüzenetek elrejtése az aktuális folyamat során Hints: Tippek: Homepage Honlap +Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically. +Mindkét oldal változásainak azonosÃtása és tárolása adatbázis segÃtségével. A törlések és ütközések automatikusan észlelÅ‘dnek. If you like FFS FFS támogatása Ignore 1-hour file time difference @@ -548,8 +556,10 @@ Ignore this error, retry or abort? Figyelmen kÃvül hagyja ezt a hibát, újra megpróbálja vagy megszakÃtja? Include Csatol +Include all rows +Minden sort csatolni Include temporarily -Ideiglenesen tartalmaz +Ideiglenesen csatolni Include: *.doc;*.zip;*.exe\nExclude: temp\\* Csatol: *.doc;*.zip;*.exe\nKizár: temp\\* Incompatible synchronization database format: @@ -558,8 +568,8 @@ Info Információ Information Információ -Initial synchronization. -ElsÅ‘ szinkronizáció. +Initial synchronization: +ElsÅ‘ szinkronizáció: Integrate external applications into context menu. The following macros are available: KülsÅ‘ alkalmazás integrálása a helyi menübe. Az elérhetÅ‘ makrók a következÅ‘k: It was not possible to initialize the Recycle Bin!\n\nIt's likely that you are not using Windows.\nIf you want this feature included, please contact the author. :) @@ -574,6 +584,8 @@ Load configuration from file BeállÃtások betöltése fájlból Load configuration history (press DEL to delete items) BeállÃtások elÅ‘zményeinek a betöltése (Nyomja meg a DEL gombot a törléshez) +Local filter +Lokális szűrÅ‘ Log-messages: Naplóbejegyzések: Logging @@ -598,8 +610,8 @@ Moving folder %x to user-defined directory %y %x mappa mozgatása a felhasználó által megadott %y mappába Multiple... SokszorosÃtás -No database file existing yet: -Nem létezÅ‘ adatbázis fájl: +No filter selected +Nincs szűrÅ‘ kiválasztva Not enough free disk space available in: Nincs elég szabad lemezterület: Nothing to synchronize according to configuration! @@ -634,8 +646,8 @@ Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) i Ennek a funkciónak a használatához, kérjük, másold a megfelelÅ‘ \"Shadow.dll\" fájlt (megtalálható a \"Shadow.zip\" archÃvumban) abba a mappába, amelybe a FreeFileSync-et telepÃtetted. Please fill all empty directory fields. Kérjük, töltse ki az összes üres mappa mezÅ‘t. -Press button to activate filter -Nyomja meg a gombot a szűrÅ‘ aktiválásához +Please run a Compare first before synchronizing! +Kérjük, futtass le egy összehasonlÃtást mielÅ‘tt szinkronizálnál! Published under the GNU General Public License: Kiadva a GNU General Public License alatt: Question @@ -656,12 +668,16 @@ Remove folder Mappa eltávolÃtása Remove folder pair Mappa párok eltávolÃtása +Remove local filter settings +Lokális szűrÅ‘beállÃtások eltávolÃtása Report translation error FordÃtói hiba bejelentése Reset HelyreállÃtás Right Jobb oldal +Run minimized and write status information to a logfile +Futtatás lekicsinyÃtve és a státuszinformációk mentése naplófájlba S&ave configuration BeállÃtások mentés&e S&witch view @@ -676,14 +692,14 @@ Scanning: Vizsgálat: Select a folder Mappa kiválasztása -Select alternate filter settings -AlternatÃv szűrÅ‘beállÃtások kiválasztása Select alternate synchronization settings AlternatÃv szinkronizációs beállÃtások kiválasztása Select logfile directory: Naplófájl mappájának kiválasztása: Select variant: Változat kiválasztása: +Setting default synchronization directions. Please check whether they are appropriate for you. +Alapértelmezett szinkronizációs irányok beállÃtása. Kérjük, ellenÅ‘rizd a helyességüket. Show conflicts Ãœtközések mutatása Show file icons @@ -770,8 +786,12 @@ Target directory already existing! A célmappa már létezik! Target file already existing! A célként megadott fájl már létezik! +The database file is not yet existing, but will be created during synchronization: +Az adatbázisfájl nem létezik, de létre lesz hozva a szinkronizáció folyamán: The file does not contain a valid configuration: A következÅ‘ fájl nem tartalmaz érvényes beállÃtásokat: +The required database entry is not yet existing, but will be created during synchronization: +A szükséges adatbázisbejegyzés nem létezik, de létre lesz hozva a szinkronizáció folyamán: This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. Ez a változat akkor tekint egyezÅ‘nek két azonos nevű fájlt, ha azok mérete ÉS az utolsó módosÃtásuk ideje azonos. Time @@ -796,8 +816,6 @@ Unable to create logfile! Nem lehet létrehozni a naplófájlt! Unable to initialize Recycle Bin! Nem lehet inicializálni a Lomtárat (Recycle Bin)! -Uncheck all -Összes kijelölést megszűntet Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization. Feloldatlan ütközések vannak! \n\nFigyelmen kÃvül hagyhatod az ütközéseket és folytathatod a szinkronizálást. Update -> @@ -812,8 +830,6 @@ User-defined directory Felhasználó által megadott mappa User-defined directory for deletion was not specified! A törléshez nem lett mappa megadva a felhasználó által! -Using default synchronization directions. Please recheck. -Az alapértelmezett szinkronizációs irányok vannak használatban. Kérjük, ellenÅ‘rizze újra. Variant Variáns Verifying file %x diff --git a/BUILD/Languages/italian.lng b/BUILD/Languages/italian.lng index f5134536..22e85097 100644 --- a/BUILD/Languages/italian.lng +++ b/BUILD/Languages/italian.lng @@ -156,10 +156,14 @@ About A proposito di Action Azioni +Activate filter +Attiva filtro Add folder Aggiungi cartella Add folder pair Aggiungi una coppia di cartelle +All directories in sync! +Tutte le directory in sync! An exception occured! Si è verificato un problema! As a result the files are separated into the following categories: @@ -196,10 +200,6 @@ Category Categoria Change direction Cambia direzione -Check all -Seleziona tutto -Choose to hide filtered files/directories from list -Nascondi i files/directories dalla lista Comma separated list Lista di elementi separati da virgola Commandline @@ -240,8 +240,6 @@ Configuration saved! Configurazione salvata! Configure filter Configurazione dei filtri -Configure filter... -Configurazione dei filtri... Configure your own synchronization rules. Configura le tue regole di sincronizzazione. Confirm @@ -332,8 +330,6 @@ Directory Directory Directory does not exist: La directory non esiste: -Do not display visual status information but write to a logfile instead -Non visualizzare le informazioni di stato ma scrivile in un file di log Do not show this dialog again Non visualizzare più questo messaggio Do nothing @@ -404,12 +400,12 @@ Error writing file: Errore durante la scrittura del file: Error writing to synchronization database: Errore in scrittura sul database di sincronizzazione: -Source directory does not exist anymore: -La directory sorgente non è più esistente: Example Esempio Exclude Escludi +Exclude all rows +Escludi tutte le righe Exclude temporarily Escludi temporaneamente Exclude via filter: @@ -420,6 +416,8 @@ Exit with RC < 0 Esci con RC < 0 External applications Applicazioni esterne +Fatal Error +Fatal Error Feedback and suggestions are welcome at: Commenti e suggerimenti sono i benvenuti: File %x has an invalid date! @@ -464,12 +462,14 @@ Files/folders that exist on right side only Files/cartelle esistenti solo a destra Filter Filtro -Filter active: Press again to deactivate -Filtro attivo: Clicca nuovamente per disattivare Filter files Filtro dei files +Filter has been selected +Filtro selezionato Filter view Filtro della vista +Filtering is deactivated +Filtro disattivato Folder Comparison and Synchronization Comparazione di Cartelle e Sincronizzazione Free disk space available: @@ -492,6 +492,8 @@ Generating database... Generazione database... Generating file list... Generazione lista dei file... +Global filter +Filtro globale Global settings Preferenze Help @@ -502,6 +504,8 @@ Hide all error and warning messages Nascondi tutti gli errori e i messaggi d'avviso Hide conflicts Nascondi i conflitti +Hide excluded items +Nascondi oggetti esclusi Hide files that are different Nascondi i file differenti Hide files that are equal @@ -528,14 +532,16 @@ Hide files that will be overwritten on right side Nascondi i file che verranno sovrascritti sul lato destro Hide files that won't be copied Nascondi i file che non saranno copiati -Hide filtered items -Nascondi gli elementi filtrati +Hide filtered or temporarily excluded files +Nascondi file filtrati o temporaneamente esclusi Hide further error messages during the current process Non mostrare i successivi messaggi d'errore durante il processo corrente Hints: Consigli: Homepage Homepage +Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically. +Identifica e propaga cambiamenti su entrambi i lati usando un database. Cancellazioni e conflitti sono riconosciuti automaticamente. If you like FFS Se ti piace FFS Ignore 1-hour file time difference @@ -550,6 +556,8 @@ Ignore this error, retry or abort? Ignora questo errore, riprova o abbandona? Include Includi +Include all rows +Includi tutte le righe Include temporarily Includi temporaneamente Include: *.doc;*.zip;*.exe\nExclude: temp\\* @@ -560,8 +568,8 @@ Info Info Information Informazioni -Initial synchronization. -Prima sincronizzazione. +Initial synchronization: +Prima sincronizzazione: Integrate external applications into context menu. The following macros are available: Integra applicazioni esterne nel menu contestuale. Sono disponibili le seguenti macro: It was not possible to initialize the Recycle Bin!\n\nIt's likely that you are not using Windows.\nIf you want this feature included, please contact the author. :) @@ -576,6 +584,8 @@ Load configuration from file Carica configurazione da file Load configuration history (press DEL to delete items) Carica la cronologia delle configurazioni (premi DEL per eliminare elementi) +Local filter +Filtro locale Log-messages: Log-messages: Logging @@ -600,8 +610,8 @@ Moving folder %x to user-defined directory %y Spostamento di cartella %x nella directory personalizzata %y Multiple... Multiplo... -No database file existing yet: -Database file non ancora esistente: +No filter selected +Nessun filtro selezionato Not enough free disk space available in: Spazio libero su disco insufficiente in: Nothing to synchronize according to configuration! @@ -636,8 +646,8 @@ Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) i Per abilitare questa funzione è necessario copiare l'appropriata \"Shadow.dll\" (che si trova nell'archivio \"Shadow.zip\") nella directory di installazione di FreeFileSync. Please fill all empty directory fields. Compilare tutti i campi di directory vuoti. -Press button to activate filter -Cliccare per attivare il filtro +Please run a Compare first before synchronizing! +Prima di sincronizzare effettua una Comparazione! Published under the GNU General Public License: Pubblicato sotto licenza GNU General Public: Question @@ -658,12 +668,16 @@ Remove folder Rimuovi cartella Remove folder pair Elimina la coppia di cartelle +Remove local filter settings +Rimuovi impostazioni di filtro locale Report translation error Segnala errori di traduzione Reset Reset Right Destra +Run minimized and write status information to a logfile +Lancia minimizzato e scrivi informazioni di stato in un log S&ave configuration S&alva la configurazione S&witch view @@ -678,14 +692,14 @@ Scanning: Analisi in corso: Select a folder Seleziona una cartella -Select alternate filter settings -Seleziona impostazioni di filtro alternative Select alternate synchronization settings Seleziona impostazioni di sincronizzazione alternative Select logfile directory: Seleziona cartella per il file di log: Select variant: Selezionare una variante: +Setting default synchronization directions. Please check whether they are appropriate for you. +Impostazione direzione standard di sincronizzazione. Prego controlla se sono adatte per te. Show conflicts Mostra conflitti Show file icons @@ -730,6 +744,8 @@ Size Dimensione Source code written completely in C++ utilizing: Codice sorgente scritto completamente in C++ \ne utilizzando: +Source directory does not exist anymore: +La directory sorgente non è più esistente: Speed: Velocita': Start @@ -770,8 +786,12 @@ Target directory already existing! Directory di destinazione già esistente! Target file already existing! File destinazione già esistente! +The database file is not yet existing, but will be created during synchronization: +Il database non e' ancora esistente, ma verra' creato durante la sincronizzazione: The file does not contain a valid configuration: Il file non contiene una configurazione valida +The required database entry is not yet existing, but will be created during synchronization: +Il database richiesto non e' ancora esistente, ma verra' creato durante la sincronizzazione: This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. Questa variante definisce identici due file con lo stesso nome quando hanno la stessa dimensione E la stessa data e ora. Time @@ -796,8 +816,6 @@ Unable to create logfile! Impossibile creaer il file di log! Unable to initialize Recycle Bin! Impossibile inizializzare il Cestino! -Uncheck all -Deseleziona tutto Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization. Sono presenti conflitti irrisolti! \n\nPuoi ignorare i conflitti e continuare la sincronizzazione. Update -> @@ -812,8 +830,6 @@ User-defined directory Directory personalizzata User-defined directory for deletion was not specified! Directory personalizzata per la cancellazione non specificata! -Using default synchronization directions. Please recheck. -Impostate direzioni di sincronizzazione di default. Controllare nuovamente. Variant Variante Verifying file %x diff --git a/BUILD/Languages/japanese.lng b/BUILD/Languages/japanese.lng index 27354764..ff52cff2 100644 --- a/BUILD/Languages/japanese.lng +++ b/BUILD/Languages/japanese.lng @@ -148,8 +148,6 @@ <複数é¸æŠž> A newer version of FreeFileSync is available: FreeFileSync ã®æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒåˆ©ç”¨å¯èƒ½ã§ã™: -ATTENTION: Failed directory access can lead to file deletions! -注æ„: ディレクトリã®ã‚¢ã‚¯ã‚»ã‚¹ã«å¤±æ•—ã—ãŸå ´åˆã€ãƒ•ã‚¡ã‚¤ãƒ«ã¯å‰Šé™¤ã•ã‚Œã¾ã™! Abort requested: Waiting for current operation to finish... ユーザã«ã‚ˆã‚‹ä¸æ–: ç¾åœ¨ã®å‡¦ç†ã‚’終了ã—ã¦ã„ã¾ã™.. ãŠå¾…ã¡ãã ã•ã„... Aborted @@ -158,10 +156,14 @@ About æƒ…å ± Action æ“作 +Activate filter +フィルターを有効化 Add folder ãƒ•ã‚©ãƒ«ãƒ€ã‚’è¿½åŠ Add folder pair フォルダã®ãƒšã‚¢ã‚’è¿½åŠ +All directories in sync! +ã™ã¹ã¦ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’åŒæœŸ! An exception occured! 例外ãŒç™ºç”Ÿã—ã¾ã—ãŸ! As a result the files are separated into the following categories: @@ -198,10 +200,6 @@ Category カテゴリ Change direction æ–¹å‘を変更 -Check all -ã™ã¹ã¦é¸æŠž -Choose to hide filtered files/directories from list -リストã‹ã‚‰é™¤å¤–ã—ãŸã„ファイル/ディレクトリをé¸æŠž Comma separated list カンマ区切り Commandline @@ -242,8 +240,6 @@ Configuration saved! 構æˆè¨å®šã¯ä¿å˜ã•ã‚Œã¾ã—ãŸ! Configure filter フィルターè¨å®š -Configure filter... -フィルターè¨å®š... Configure your own synchronization rules. ã‚ãªãŸã®è¨å®šã—ãŸåŒæœŸè¦å‰‡ Confirm @@ -334,8 +330,6 @@ Directory ディレクトリ Directory does not exist: ディレクトリãŒå˜åœ¨ã—ã¾ã›ã‚“: -Do not display visual status information but write to a logfile instead -進æ—状æ³ãªã©ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’表示ã—ãªã„ã§ã€ãƒã‚°ãƒ•ã‚¡ã‚¤ãƒ«ã®æ›¸ãè¾¼ã¿ã¯å®Ÿæ–½ã™ã‚‹ã€‚ Do not show this dialog again 次回ã‹ã‚‰è¡¨ç¤ºã—ãªã„ Do nothing @@ -406,12 +400,12 @@ Error writing file: ファイル書ãè¾¼ã¿ã‚¨ãƒ©ãƒ¼: Error writing to synchronization database: åŒæœŸãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¸ã®æ›¸ãè¾¼ã¿ã‚¨ãƒ©ãƒ¼: -Source directory does not exist anymore: -ソースディレクトリãŒå˜åœ¨ã—ã¾ã›ã‚“: Example 例 Exclude 除外 +Exclude all rows +ã™ã¹ã¦ã®è¡Œã‚’除外 Exclude temporarily 一時フォルダを除外 Exclude via filter: @@ -422,6 +416,8 @@ Exit with RC < 0 RC ã§çµ‚了 < 0 External applications 外部アプリケーション +Fatal Error +致命的ãªã‚¨ãƒ©ãƒ¼ Feedback and suggestions are welcome at: フィードãƒãƒƒã‚¯ã€æ案ãªã©: File %x has an invalid date! @@ -466,18 +462,20 @@ Files/folders that exist on right side only å³å´ã®ã¿ã«å˜åœ¨ã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«/フォルダ Filter フィルター -Filter active: Press again to deactivate -フィルター有効化: å†åº¦æŠ¼ã™ã¨ç„¡åŠ¹åŒ– Filter files ファイルフィルター +Filter has been selected +フィルターã¯é¸æŠžæ¸ˆã¿ã§ã™ Filter view 表示フィルター +Filtering is deactivated +フィルタリングã¯éžã‚¢ã‚¯ãƒ†ã‚£ãƒ–ã§ã™ Folder Comparison and Synchronization フォルダã®æ¯”較ã¨åŒæœŸ Free disk space available: 利用å¯èƒ½ãªãƒ‡ã‚£ã‚¹ã‚¯ç©ºã容é‡: FreeFileSync - Folder Comparison and Synchronization -FreeFileSync - Folder Comparison and Synchronization +FreeFileSync - フォルダ比較ã¨åŒæœŸå‡¦ç† FreeFileSync Batch Job FreeFileSync 一括ジョブ FreeFileSync at Sourceforge @@ -494,6 +492,8 @@ Generating database... データベースを作æˆä¸... Generating file list... ファイル一覧を作æˆä¸... +Global filter +全般フィルター Global settings 全般的ãªè¨å®š Help @@ -504,6 +504,8 @@ Hide all error and warning messages ã™ã¹ã¦ã®ã‚¨ãƒ©ãƒ¼ã¨è¦å‘Šãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’éžè¡¨ç¤º Hide conflicts ä¸ä¸€è‡´ã‚’éš ã™ +Hide excluded items +é™¤å¤–ã‚¢ã‚¤ãƒ†ãƒ ã‚’éš ã™ Hide files that are different ç•°ãªã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã‚’éžè¡¨ç¤º Hide files that are equal @@ -530,14 +532,16 @@ Hide files that will be overwritten on right side å³å´ã§ä¸Šæ›¸ãã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’éžè¡¨ç¤ºã«ã™ã‚‹ Hide files that won't be copied コピーã—ãªã‹ã£ãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’éš ã™ -Hide filtered items -é©åˆã™ã‚‹ã‚¢ã‚¤ãƒ†ãƒ ã‚’éžè¡¨ç¤ºã«ã™ã‚‹ +Hide filtered or temporarily excluded files +フィルターã€ã¾ãŸã¯ä¸€æ™‚é™¤å¤–ãƒ•ã‚¡ã‚¤ãƒ«ã‚’éš ã™ Hide further error messages during the current process ç¾åœ¨ã®å‡¦ç†ä¸ã¯ä»¥é™ã®ã‚¨ãƒ©ãƒ¼ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’表示ã—ãªã„ Hints: ヒント: Homepage ホームページ +Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically. +データベースを使用ã—ã¦ã€ä¸¡å´ã‚¢ã‚¤ãƒ†ãƒ ã®å¤‰æ›´ã‚’特定ã—ã¾ã™ã€‚削除ã€ç«¶åˆã¯è‡ªå‹•çš„ã«æ¤œå‡ºã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ If you like FFS FFS ãŒæ°—ã«å…¥ã£ãŸå ´åˆ Ignore 1-hour file time difference @@ -552,6 +556,8 @@ Ignore this error, retry or abort? ã“ã®ã‚¨ãƒ©ãƒ¼ã‚’無視ã—ã¦å†è©¦è¡Œ/ä¸æ–ã—ã¾ã™ã‹? Include å«ã‚ã‚‹ +Include all rows +ã™ã¹ã¦ã®è¡Œã‚’å«ã‚ã‚‹ Include temporarily 一時フォルダをå«ã‚ã‚‹ Include: *.doc;*.zip;*.exe\nExclude: temp\\* @@ -562,8 +568,8 @@ Info æƒ…å ± Information インフォメーション -Initial synchronization. -åŒæœŸå‡¦ç†ã®åˆæœŸåŒ–. +Initial synchronization: +åŒæœŸå‡¦ç†ã®åˆæœŸåŒ–: Integrate external applications into context menu. The following macros are available: 外部ã®ã‚¢ãƒ—リケーションをコンテã‚ストメニューã«çµ±åˆã€ä»¥ä¸‹ã®ãƒžã‚¯ãƒãŒåˆ©ç”¨ã§ãã¾ã™: It was not possible to initialize the Recycle Bin!\n\nIt's likely that you are not using Windows.\nIf you want this feature included, please contact the author. :) @@ -578,6 +584,8 @@ Load configuration from file 外部ファイルã‹ã‚‰æ§‹æˆè¨å®šã‚’èªã¿è¾¼ã¿ã¾ã™ Load configuration history (press DEL to delete items) 構æˆè¨å®šå±¥æ´ã®èªã¿è¾¼ã¿(DELã‚ーã§ã‚¢ã‚¤ãƒ†ãƒ を削除) +Local filter +ãƒãƒ¼ã‚«ãƒ«ãƒ•ã‚£ãƒ«ã‚¿ãƒ¼ Log-messages: ãƒã‚°ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸: Logging @@ -602,8 +610,8 @@ Moving folder %x to user-defined directory %y フォルダ %x をユーザ定義ディレクトリ %y ã«ç§»å‹• Multiple... 複数処ç†... -No database file existing yet: -データベースãŒå˜åœ¨ã—ã¾ã›ã‚“: +No filter selected +フィルターé¸æŠžãªã— Not enough free disk space available in: 利用å¯èƒ½ãªãƒ‡ã‚£ã‚¹ã‚¯ç©ºã容é‡ãŒè¶³ã‚Šã¾ã›ã‚“: Nothing to synchronize according to configuration! @@ -638,8 +646,8 @@ Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) i \"Shadow.dll\" (\"Shadow.zip\" アーカイブ内) ã‚’ã€FreeFileSync インストールフォルダã«ã‚³ãƒ”ーã™ã‚‹ã“ã¨ã§ã€ã“ã®æ©Ÿèƒ½ã‚’利用ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚ Please fill all empty directory fields. アイテムãŒé¸æŠžã•ã‚Œã¦ã„ã¾ã›ã‚“! -Press button to activate filter -ボタンをクリックã§æœ‰åŠ¹åŒ– +Please run a Compare first before synchronizing! +åŒæœŸå‡¦ç†ã‚’実行ã™ã‚‹å‰ã«æ¯”較を行ã£ã¦ãã ã•ã„! Published under the GNU General Public License: Published under the GNU General Public License: Question @@ -660,12 +668,16 @@ Remove folder フォルダ除去 Remove folder pair フォルダペアを除去 +Remove local filter settings +ãƒãƒ¼ã‚«ãƒ«ãƒ•ã‚£ãƒ«ã‚¿ãƒ¼è¨å®šã‚’除去 Report translation error 翻訳エラーã®è©³ç´° Reset リセット Right å³å´ +Run minimized and write status information to a logfile +最å°åŒ–ã§èµ·å‹•ã—ã¦ã€ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹æƒ…å ±ã‚’ãƒã‚°ã«æ›¸ã込む S&ave configuration 構æˆè¨å®šã‚’ä¿å˜(&A) S&witch view @@ -680,14 +692,14 @@ Scanning: スã‚ャン: Select a folder フォルダをé¸æŠž -Select alternate filter settings -代替フィルターè¨å®šã‚’é¸æŠž Select alternate synchronization settings 代替åŒæœŸè¨å®šã‚’é¸æŠž Select logfile directory: ãƒã‚°ãƒ•ã‚¡ã‚¤ãƒ«ã®ä¿å˜å…ˆã‚’é¸æŠž: Select variant: 変数をé¸æŠž: +Setting default synchronization directions. Please check whether they are appropriate for you. +デフォルトã®åŒæœŸæ–¹å‘ã‚’è¨å®šã—ã¾ã™ã€ãã—ã¦ãã®æ–¹å‘ãŒé©åˆ‡ã§ã‚ã‚‹ã‹ã‚’確èªã—ã¦ãã ã•ã„。 Show conflicts ä¸ä¸€è‡´ã‚’表示 Show file icons @@ -732,6 +744,8 @@ Size サイズ Source code written completely in C++ utilizing: ソースコード㯠C++ ã§æ›¸ã‹ã‚Œã€ã‚³ãƒ³ãƒ‘イルã•ã‚Œã¦ã„ã¾ã™: +Source directory does not exist anymore: +ソースディレクトリãŒå˜åœ¨ã—ã¾ã›ã‚“: Speed: 速度: Start @@ -772,8 +786,12 @@ Target directory already existing! 対象ディレクトリã¯ã™ã§ã«å˜åœ¨ã—ã¾ã™! Target file already existing! 対象ファイルã¯æ—¢ã«å˜åœ¨ã—ã¾ã™! +The database file is not yet existing, but will be created during synchronization: +ã“ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«ã¯ã€ã¾ã å˜åœ¨ã—ã¾ã›ã‚“ãŒã€åŒæœŸå‡¦ç†ã®å®Ÿè¡Œä¸ã«ä½œæˆã•ã‚Œã¾ã™: The file does not contain a valid configuration: ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã«ã¯æœ‰åŠ¹ãªæ§‹æˆãŒå«ã¾ã‚Œã¦ã„ã¾ã›ã‚“: +The required database entry is not yet existing, but will be created during synchronization: +å¿…è¦ãªãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚¨ãƒ³ãƒˆãƒªã¯ã¾ã å˜åœ¨ã—ã¾ã›ã‚“ãŒã€åŒæœŸå‡¦ç†ã®å®Ÿè¡Œä¸ã«ä½œæˆã•ã‚Œã¾ã™: This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. ã“ã®å¤‰æ•°ã§ã¯ã€ãµãŸã¤ã®åŒåファイルãŒå˜åœ¨ã—ãŸå ´åˆã€ ãã‚Œãžã‚Œã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚µã‚¤ã‚ºã¨æœ€çµ‚更新日付/時間を比較ã—ã¾ã™ã€‚ Time @@ -798,8 +816,6 @@ Unable to create logfile! ãƒã‚°ãƒ•ã‚¡ã‚¤ãƒ«ã‚’作æˆå‡ºæ¥ã¾ã›ã‚“! Unable to initialize Recycle Bin! ゴミ箱ã®åˆæœŸåŒ–ãŒå‡ºæ¥ã¾ã›ã‚“! -Uncheck all -ã™ã¹ã¦è§£é™¤ Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization. 未解決ã®ä¸ä¸€è‡´ãŒã‚ã‚Šã¾ã™! \n\nã“ã®ä¸ä¸€è‡´ã‚’無視ã—ã¦åŒæœŸã‚’続行ã™ã‚‹ã“ã¨ãŒå‡ºæ¥ã¾ã™ã€‚ Update -> @@ -814,8 +830,6 @@ User-defined directory ユーã§å®šç¾©ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª User-defined directory for deletion was not specified! ユーザ定義ディレクトリãŒæŒ‡å®šã•ã‚Œã¦ã„ã¾ã›ã‚“! -Using default synchronization directions. Please recheck. -デフォルトã§ä½¿ç”¨ã™ã‚‹åŒæœŸå‡¦ç†æ–¹å‘ (å†ç¢ºèªã—ã¦ãã ã•ã„) Variant 変化 Verifying file %x diff --git a/BUILD/Languages/polish.lng b/BUILD/Languages/polish.lng index 25dd8523..fc554eca 100644 --- a/BUILD/Languages/polish.lng +++ b/BUILD/Languages/polish.lng @@ -148,8 +148,6 @@ <zaznaczone elementy> A newer version of FreeFileSync is available: DostÄ™pna jest nowa wersja FreeFileSync: -ATTENTION: Failed directory access can lead to file deletions! -UWAGA: Niepoprawny dostÄ™p do katalogu może spowodować utratÄ™ pliku! Abort requested: Waiting for current operation to finish... Żądanie przerwania: Czekaj na koniec aktualnie wykonywanego zadania... Aborted @@ -158,10 +156,14 @@ About O Programie Action Akcja +Activate filter +Aktywuj filtr Add folder Dodaj folder Add folder pair Dodaj foldery do porównania +All directories in sync! +Wszystkie katalogi zsynchronizowane! An exception occured! WystÄ…piÅ‚ wyjÄ…tek! As a result the files are separated into the following categories: @@ -198,10 +200,6 @@ Category Kategoria Change direction ZmieÅ„ kierunek -Check all -Sprawdź wszystko -Choose to hide filtered files/directories from list -Zaznacz aby ukryć przefiltrowane pliki/katalogi z listy Comma separated list Lista oddzielona przecinkami Commandline @@ -242,8 +240,6 @@ Configuration saved! Konfiguracja zapisana! Configure filter Konfiguruj filtr -Configure filter... -Konfiguruj filtr... Configure your own synchronization rules. Skonfiguruj swoje wÅ‚asne zasady synchronizacji. Confirm @@ -334,8 +330,6 @@ Directory Katalog Directory does not exist: Katalog nie istnieje: -Do not display visual status information but write to a logfile instead -Nie wyÅ›wietla graficznej informacji o statusie, ale tworzy plik z logami Do not show this dialog again Nie pokazuj tego okna ponownie Do nothing @@ -406,12 +400,12 @@ Error writing file: BÅ‚Ä…d zapisu pliku: Error writing to synchronization database: BÅ‚Ä…d zapisu do bazy danych synchronizacji: -Source directory does not exist anymore: -Katalog źródÅ‚owy nie istnieje: Example PrzykÅ‚ad Exclude Wyklucz +Exclude all rows +Wyklucz wszystkie rzÄ™dy Exclude temporarily Wyklucz tymczasowo Exclude via filter: @@ -422,6 +416,8 @@ Exit with RC < 0 ZakoÅ„cz z RC < 0 External applications Aplikacje zewnÄ™trzne +Fatal Error +BÅ‚Ä…d krytyczny Feedback and suggestions are welcome at: Komentarze i sugestie mile widziane na: File %x has an invalid date! @@ -466,12 +462,14 @@ Files/folders that exist on right side only Pliki/katalogi istniejÄ…ce tylko po prawej stronie Filter Filtr -Filter active: Press again to deactivate -Filtr aktywny: Kliknij ponownie aby wyÅ‚Ä…czyć Filter files Filtruj pliki +Filter has been selected +Filtr zostaÅ‚ zaznaczony Filter view Filtr podglÄ…du +Filtering is deactivated +Filtrowanie jest wyÅ‚Ä…czone Folder Comparison and Synchronization Porównywanie i Synchronizacja folderów Free disk space available: @@ -494,6 +492,8 @@ Generating database... Generowanie bazy danych... Generating file list... Generowanie listy plików... +Global filter +Filtr globalny Global settings Ustawienia programu Help @@ -504,6 +504,8 @@ Hide all error and warning messages Ukryj wszystkie informacje bÅ‚Ä™dach i ostrzeżeniach Hide conflicts Ukryj konflikty +Hide excluded items +Ukryj wykluczone pliki Hide files that are different Ukryj pliki, które sÄ… różne Hide files that are equal @@ -530,14 +532,16 @@ Hide files that will be overwritten on right side Ukryj pliki, które zostanÄ… nadpisane po prawej stronie Hide files that won't be copied Ukryj pliki, które nie bÄ™dÄ… kopiowane -Hide filtered items -Ukryj elementy przefiltrowane +Hide filtered or temporarily excluded files +Ukryj pliki filtrowane lub tymczasowo wykluczone Hide further error messages during the current process Ukryj kolejne informacje o bÅ‚Ä™dach dla tego zadania Hints: Wskazówki: Homepage Strona domowa +Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically. +Wykryj i zastosuj zmiany po obu stronach używajÄ…c bazy danych. UsuniÄ™cia i konflikty sÄ… wykrywane automatycznie. If you like FFS Jeżeli Ci siÄ™ podoba Ignore 1-hour file time difference @@ -552,6 +556,8 @@ Ignore this error, retry or abort? Ignorować bÅ‚Ä…d, powtórzyć albo zakoÅ„czyć? Include DoÅ‚Ä…cz +Include all rows +DoÅ‚Ä…cz wszystkie rzÄ™dy Include temporarily DoÅ‚Ä…cz tymczasowo Include: *.doc;*.zip;*.exe\nExclude: temp\\* @@ -562,8 +568,8 @@ Info Info Information Informacja -Initial synchronization. -WstÄ™pna synchronizacja. +Initial synchronization: +WstÄ™pna synchronizacja: Integrate external applications into context menu. The following macros are available: DoÅ‚Ä…cz zewnÄ™trznÄ… aplikacjÄ™ do menu kontekstowego. DostÄ™pne macra: It was not possible to initialize the Recycle Bin!\n\nIt's likely that you are not using Windows.\nIf you want this feature included, please contact the author. :) @@ -578,6 +584,8 @@ Load configuration from file Wczytaj konfiguracjÄ™ z pliku Load configuration history (press DEL to delete items) Wczytaj historie konfiguracji (naciÅ›nij Del aby usunąć element) +Local filter +Filtr lokalny Log-messages: Logi: Logging @@ -602,8 +610,8 @@ Moving folder %x to user-defined directory %y Przenoszenie folderu %x do katalogu użytkownika %y Multiple... Wiele... -No database file existing yet: -Brak pliku bazy danych: +No filter selected +Nie wybrano żadnego filtra Not enough free disk space available in: Brak wystarczajÄ…cej przestrzeni dyskowej na: Nothing to synchronize according to configuration! @@ -638,8 +646,8 @@ Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) i Skopiuj odpowiedni plik \"Shadow.dll\" (ulokowany w \"Shadow.zip\") do folderu z instalacjÄ… FreeFileSync aby uaktywnić tÄ… opcjÄ™. Please fill all empty directory fields. Podaj foldery do synchronizacji. -Press button to activate filter -Kliknij aby aktywować filtr +Please run a Compare first before synchronizing! +Przed synchronizacjÄ… należy uruchomić Porównaj! Published under the GNU General Public License: UdostÄ™pnione na zasadach licencji GNU General Public License: Question @@ -660,12 +668,16 @@ Remove folder UsuÅ„ folder Remove folder pair UsuÅ„ parÄ™ folderów +Remove local filter settings +UsuÅ„ ustawienia lokalnego filtra Report translation error ZgÅ‚oÅ› bÅ‚Ä…d w tÅ‚umaczeniu Reset Resetuj Right Prawy +Run minimized and write status information to a logfile +Uruchom w trybie ukrytym i zapisz informacje w logu S&ave configuration Z&apisz konfiguracjÄ™ S&witch view @@ -680,14 +692,14 @@ Scanning: Skanowanie: Select a folder Wybierz folder -Select alternate filter settings -Stwórz alternatywne ustawienia filtra Select alternate synchronization settings Stwórz alternatywne reguÅ‚y synchronizacji Select logfile directory: Wybierz katalog z logami: Select variant: Wybierz wariant: +Setting default synchronization directions. Please check whether they are appropriate for you. +Ustawiono domyÅ›lne kierunki synchronizacji. Sprawdź czy sÄ… dla Ciebie odpowiednie. Show conflicts Pokaż konflikty Show file icons @@ -732,6 +744,8 @@ Size Rozmiar Source code written completely in C++ utilizing: Kod źródÅ‚owy napisany caÅ‚kowicie w C++ z wykorzystaniem: +Source directory does not exist anymore: +Katalog źródÅ‚owy nie istnieje: Speed: PrÄ™dkość: Start @@ -772,8 +786,12 @@ Target directory already existing! Katalog docelowy już istnieje! Target file already existing! Plik docelowy już istnieje! +The database file is not yet existing, but will be created during synchronization: +Plik bazy danych nie istnieje, ale zostanie utworzony podczas synchronizacji: The file does not contain a valid configuration: NieprawidÅ‚owy format pliku: +The required database entry is not yet existing, but will be created during synchronization: +Wymagany wpis bazy danych nie istnieje, ale zostanie utworzony podczas synchronizacji: This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. Ten wariant traktuje dwa pliki jako równe w przypadku gdy majÄ… jednakowy rozmiar oraz tÄ… samÄ… datÄ™ i czas ostatniej modyfikacji. Time @@ -798,8 +816,6 @@ Unable to create logfile! Nie można utworzyć pliku z logami! Unable to initialize Recycle Bin! Nie można zainicjalizować Kosz! -Uncheck all -Odznacz wszystko Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization. IstniejÄ… nierozwiÄ…zane konflikty! \n\nMożesz je zignorować i kontynuÅ‚ować synchronizacjÄ™. Update -> @@ -814,8 +830,6 @@ User-defined directory Katalog użytkownika User-defined directory for deletion was not specified! Katalog użytkownika dla elementów usuniÄ™tych nie zostaÅ‚ okreÅ›lony! -Using default synchronization directions. Please recheck. -Ustawione sÄ… domyÅ›lne kierunki synchronizacji. Sprawdź ponownie. Variant Wariant Verifying file %x diff --git a/BUILD/Languages/portuguese.lng b/BUILD/Languages/portuguese.lng index 31d75a02..83518934 100644 --- a/BUILD/Languages/portuguese.lng +++ b/BUILD/Languages/portuguese.lng @@ -148,8 +148,6 @@ <Selecção Múltipla> A newer version of FreeFileSync is available: Mais recente versão do FreeFileSync disponÃvel: -ATTENTION: Failed directory access can lead to file deletions! -ATENÇÃO: Falha no acesso ao directório pode levar à eliminação de ficheiros! Abort requested: Waiting for current operation to finish... Abortar pedido: À espera do fim da operação... Aborted @@ -158,10 +156,14 @@ About Sobre Action Acção +Activate filter + Add folder Adicionar pasta Add folder pair Adicionar um par de pastas +All directories in sync! + An exception occured! Ocorreu uma excepção! As a result the files are separated into the following categories: @@ -198,10 +200,6 @@ Category Categoria Change direction Mudar direcção -Check all -Verificar tudo -Choose to hide filtered files/directories from list -Ocultar itens filtrados da lista Comma separated list Lista de itens separados por virgula Commandline @@ -242,8 +240,6 @@ Configuration saved! Configuração guardada! Configure filter Configuração dos filtros -Configure filter... -Configurar filtros... Configure your own synchronization rules. Configure as suas regras de sincronização. Confirm @@ -334,8 +330,6 @@ Directory Directório Directory does not exist: A pasta não existe: -Do not display visual status information but write to a logfile instead -Não apresentar informação de estado, mas escrever num ficheiro log Do not show this dialog again Não mostrar novamente Do nothing @@ -406,12 +400,12 @@ Error writing file: Erro de escrita no ficheiro: Error writing to synchronization database: Erro na escrita da base de dados de sincronização: -Source directory does not exist anymore: -A pasta de origem já não existe: Example Exemplo Exclude Excluir +Exclude all rows + Exclude temporarily Excluir temporariamente Exclude via filter: @@ -422,6 +416,8 @@ Exit with RC < 0 Sair com RC < 0 External applications Aplicações externas +Fatal Error + Feedback and suggestions are welcome at: Comentários e sugestões são benvindos em: File %x has an invalid date! @@ -466,12 +462,14 @@ Files/folders that exist on right side only Ficheiros/pastas existentes somente à direita Filter Filtro -Filter active: Press again to deactivate -Filtro activo: Clique aqui para desactivar Filter files Filtrar ficheiros +Filter has been selected + Filter view Filtrar vista +Filtering is deactivated + Folder Comparison and Synchronization Comparação e Sincronização de pastas Free disk space available: @@ -494,6 +492,8 @@ Generating database... A gerar base de dados... Generating file list... A gerar lista ficheiros... +Global filter + Global settings Opções Help @@ -504,6 +504,8 @@ Hide all error and warning messages Ocultar todas as mensagens de erro ou aviso Hide conflicts Ocultar conflitos +Hide excluded items + Hide files that are different Ocultar ficheiros diferentes Hide files that are equal @@ -530,14 +532,16 @@ Hide files that will be overwritten on right side Ocultar ficheiros a ser substituidos do lado direito Hide files that won't be copied Ocultar ficheiros que não serão copiados -Hide filtered items -Ocultar itens filtrados +Hide filtered or temporarily excluded files + Hide further error messages during the current process Ocultar próximas mensagens de erro durante este processo Hints: Dicas: Homepage Site +Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically. + If you like FFS Se gosta do FreeFileSync Ignore 1-hour file time difference @@ -552,6 +556,8 @@ Ignore this error, retry or abort? Ignorar erro, tentar de novo ou abortar? Include Incluir +Include all rows + Include temporarily Incluir temporariamente Include: *.doc;*.zip;*.exe\nExclude: temp\\* @@ -562,8 +568,8 @@ Info Info Information Informação -Initial synchronization. -Sincronização inicial. +Initial synchronization: +Sincronização inicial: Integrate external applications into context menu. The following macros are available: Integrar aplicações externas no menu de contexto. As seguintes macros estão disponÃveis: It was not possible to initialize the Recycle Bin!\n\nIt's likely that you are not using Windows.\nIf you want this feature included, please contact the author. :) @@ -578,6 +584,8 @@ Load configuration from file Carregar configuração do ficheiro Load configuration history (press DEL to delete items) Carregar histórico de configuração (pressione DEL para apagar itens) +Local filter + Log-messages: Log de mensagens: Logging @@ -602,8 +610,8 @@ Moving folder %x to user-defined directory %y A mover pasta %x para o directório %y Multiple... Multiplo... -No database file existing yet: -Base de dados inexistente: +No filter selected + Not enough free disk space available in: Não há espaço livre suficiente em: Nothing to synchronize according to configuration! @@ -638,8 +646,8 @@ Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) i Por favor copie o \"Shadow.dll\" correcto (localizado no arquivo \"Shadow.zip\") para a pasta da instalação do FreeFileSync para activar esta opção. Please fill all empty directory fields. Por favor, preencha todos os campos vazios. -Press button to activate filter -Pressione para activar o filtro +Please run a Compare first before synchronizing! + Published under the GNU General Public License: Publicado sobre GNU General Public License: Question @@ -660,12 +668,16 @@ Remove folder Remover pasta(s) Remove folder pair Remover o par de pastas +Remove local filter settings + Report translation error Informar um erro de tradução Reset Reiniciar Right Direita +Run minimized and write status information to a logfile + S&ave configuration G&uardar a configuração S&witch view @@ -680,14 +692,14 @@ Scanning: A pesquisar: Select a folder Seleccione uma pasta -Select alternate filter settings -Seleccionar opções alternativas de filtros Select alternate synchronization settings Seleccionar opções alternativas de sincronização Select logfile directory: Seleccione directório para ficheiro log: Select variant: Seleccione uma variante: +Setting default synchronization directions. Please check whether they are appropriate for you. + Show conflicts Mostrar conflitos Show file icons @@ -732,6 +744,8 @@ Size Tamanho Source code written completely in C++ utilizing: Código fonte todo escrito em C++ utilizando: +Source directory does not exist anymore: +A pasta de origem já não existe: Speed: Velocidade: Start @@ -772,8 +786,12 @@ Target directory already existing! Directório de destino já existe! Target file already existing! Ficheiro de destino já existe! +The database file is not yet existing, but will be created during synchronization: + The file does not contain a valid configuration: O ficheiro não contém uma configuração válida: +The required database entry is not yet existing, but will be created during synchronization: + This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. Esta variante avalia dois ficheiros de nome igual como iguais quando têm o mesmo tamanho e a mesma data e hora de modificação. Time @@ -798,8 +816,6 @@ Unable to create logfile! Não é possÃvel criar ficheiro log! Unable to initialize Recycle Bin! Não é possÃvel iniciar a Reciclagem! -Uncheck all -Deseleccionar todos Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization. Existem conflitos não resolvidos! \n\nPode ignorá-los e continuar a sincronização. Update -> @@ -814,8 +830,6 @@ User-defined directory Directório definido pelo utilizador User-defined directory for deletion was not specified! Directório para eliminação não foi especificado! -Using default synchronization directions. Please recheck. -Direcção de sincronização inicial em uso. Verifique de novo. Variant Variável Verifying file %x diff --git a/BUILD/Languages/portuguese_br.lng b/BUILD/Languages/portuguese_br.lng index c2be1885..081e1b96 100644 --- a/BUILD/Languages/portuguese_br.lng +++ b/BUILD/Languages/portuguese_br.lng @@ -156,10 +156,14 @@ About Sobre Action Ação +Activate filter +Ativar filtro Add folder Adicionar pasta Add folder pair Adicionar par de pastas +All directories in sync! +Todos os diretórios em sincronismo! An exception occured! Ocorreu uma exceção! As a result the files are separated into the following categories: @@ -196,10 +200,6 @@ Category Categoria Change direction Inverter sentido -Check all -Marcar todos -Choose to hide filtered files/directories from list -Ocultar arquivos/diretórios filtrados da lista Comma separated list Lista de itens separada por vÃrgula Commandline @@ -240,8 +240,6 @@ Configuration saved! Configuração salva! Configure filter Configurar filtros -Configure filter... -Configurar filtros... Configure your own synchronization rules. Configure as suas próprias regras de sincronização. Confirm @@ -332,8 +330,6 @@ Directory Diretório Directory does not exist: Diretório não existe: -Do not display visual status information but write to a logfile instead -Ao invés de mostrar informação do estado visualmente, escrever para um arquivo log Do not show this dialog again Não mostrar esse diálogo novamente Do nothing @@ -404,12 +400,12 @@ Error writing file: Erro ao escrever arquivo: Error writing to synchronization database: Erro ao escrever no banco de dados de sincronização: -Source directory does not exist anymore: -Diretório de origem não existe mais: Example Exemplo Exclude Excluir +Exclude all rows +Excluir todas as linhas Exclude temporarily Excluir temporariamente Exclude via filter: @@ -420,6 +416,8 @@ Exit with RC < 0 Sair com RC < 0 External applications Aplicações externas +Fatal Error +Erro fatal Feedback and suggestions are welcome at: Comentários e sugestões são bem-vindos em: File %x has an invalid date! @@ -464,12 +462,14 @@ Files/folders that exist on right side only Arquivos/pastas que existem somente à direita Filter Filtro -Filter active: Press again to deactivate -Filtro ativo: Clique novamente para desativar Filter files Filtrar arquivos +Filter has been selected +Filtro foi selecionado Filter view Filtrar vista +Filtering is deactivated +Filtragem está desativada Folder Comparison and Synchronization Comparação e Sincronização de Pastas Free disk space available: @@ -492,6 +492,8 @@ Generating database... Gerando banco de dados... Generating file list... Gerando lista de arquivos... +Global filter +Filtro global Global settings Configurações Help @@ -502,6 +504,8 @@ Hide all error and warning messages Ocultar todas as mensagens de erro ou aviso Hide conflicts Ocultar conflitos +Hide excluded items +Ocultar itens excluÃdos Hide files that are different Ocultar arquivos que são diferentes Hide files that are equal @@ -528,14 +532,16 @@ Hide files that will be overwritten on right side Ocultar arquivos que serão substituÃdos no lado direito Hide files that won't be copied Ocultar arquivos que não serão copiados -Hide filtered items -Ocultar itens filtrados +Hide filtered or temporarily excluded files +Ocultar arquivos filtrados ou temporariamente excluÃdos Hide further error messages during the current process Ocultar próximas mensagens de erro durante este processo Hints: Dicas: Homepage Homepage +Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically. +Identificar e propagar mudanças em ambos os lados usando o banco de dados. Exclusões e conflitos serão detectados automaticamente. If you like FFS Se gosta do FFS Ignore 1-hour file time difference @@ -550,6 +556,8 @@ Ignore this error, retry or abort? Ignorar este erro, tentar novamente ou abortar? Include Incluir +Include all rows +Incluir todas as linhas Include temporarily Incluir temporariamente Include: *.doc;*.zip;*.exe\nExclude: temp\\* @@ -560,8 +568,8 @@ Info Info Information Informação -Initial synchronization. -Sincronização inicial. +Initial synchronization: +Sincronização inicial: Integrate external applications into context menu. The following macros are available: Integrar aplicações externas no menu de contexto. As seguintes macros estão disponÃveis: It was not possible to initialize the Recycle Bin!\n\nIt's likely that you are not using Windows.\nIf you want this feature included, please contact the author. :) @@ -576,6 +584,8 @@ Load configuration from file Carregar configuração do arquivo Load configuration history (press DEL to delete items) Carregar histórico de configuração (pressione DEL para apagar itens) +Local filter +Filtro local Log-messages: Log de mensagens: Logging @@ -600,8 +610,8 @@ Moving folder %x to user-defined directory %y Movendo pasta %x para o diretório especificado Multiple... Múltiplos... -No database file existing yet: -Nenhum arquivo de banco de dados existe ainda: +No filter selected +Nenhum filtro selecionado Not enough free disk space available in: Espaço em disco insuficiente em: Nothing to synchronize according to configuration! @@ -636,8 +646,8 @@ Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) i Por favor, copie o \"Shadow.dll\" apropriado (localizado no arquivo \"Shadow.zip\") no diretório de instalação do FreeFileSync para habilitar essa funcionalidade. Please fill all empty directory fields. Por favor, preencha todos os campos de diretórios vazios. -Press button to activate filter -Pressione para ativar o filtro +Please run a Compare first before synchronizing! +Por favor execute primeiro a Comparação antes de sincronizar! Published under the GNU General Public License: Publicado sobre a GNU General Public License: Question @@ -658,12 +668,16 @@ Remove folder Remover pasta Remove folder pair Remover par de pastas +Remove local filter settings +Remover configurações locais de filtro Report translation error Reportar erro de tradução Reset Reiniciar Right Direita +Run minimized and write status information to a logfile +Executar minimizado e escrever informações de status em um arquivo log S&ave configuration S&alvar configuração S&witch view @@ -678,14 +692,14 @@ Scanning: Pesquisando: Select a folder Selecione uma pasta -Select alternate filter settings -Selecionar configuração de filtro alternativa Select alternate synchronization settings Selecionar configuração de sincronização alternativa Select logfile directory: Escolha um diretório para salvar o arquivo log: Select variant: Selecione uma variante: +Setting default synchronization directions. Please check whether they are appropriate for you. +Ajustando direções padrões de sincronização. Por favor verifique se são apropriadas para você. Show conflicts Mostrar conflitos Show file icons @@ -730,6 +744,8 @@ Size Tamanho Source code written completely in C++ utilizing: Código fonte todo escrito em C++ utilizando: +Source directory does not exist anymore: +Diretório de origem não existe mais: Speed: Velocidade: Start @@ -770,8 +786,12 @@ Target directory already existing! Diretório de destino já existe! Target file already existing! Arquivo de destino já existe! +The database file is not yet existing, but will be created during synchronization: +O arquivo de banco de dados ainda não existe, mas será criado durante a sincronização: The file does not contain a valid configuration: O arquivo não contém uma configuração válida: +The required database entry is not yet existing, but will be created during synchronization: +A entrada de banco de dados requerida ainda não existe, mas será criada durante a sincronização: This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. Esta variante avalia dois arquivos de nomes equivalentes como sendo iguais quando têm o mesmo tamanho E a mesma data e hora de modificação. Time @@ -796,8 +816,6 @@ Unable to create logfile! Não foi possÃvel criar arquivo log! Unable to initialize Recycle Bin! Não foi possÃvel abrir a Lixeira! -Uncheck all -Desmarcar todos Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization. Conflitos não resolvidos existentes! \n\nVocê pode ignorar os conflitos e continuar a sincronização. Update -> @@ -812,8 +830,6 @@ User-defined directory Diretório especificado User-defined directory for deletion was not specified! Diretório especificado para arquivos apagados não foi definido! -Using default synchronization directions. Please recheck. -Usando direções de sincronização padrões. Por favor, verificar novamente. Variant Variante Verifying file %x diff --git a/BUILD/Languages/romanian.lng b/BUILD/Languages/romanian.lng index ee155870..8bdf1247 100644 --- a/BUILD/Languages/romanian.lng +++ b/BUILD/Languages/romanian.lng @@ -49,7 +49,7 @@ &Create batch job &Creează o Sarcină Lot &Default -&Implicit +&Implicite &Exit &IeÈ™i &Export file list @@ -61,7 +61,7 @@ &Help &Ajutor &Ignore -&Ignoră +&OK &Language &Limbă &Load @@ -139,7 +139,7 @@ 3. Exclude files directly on main grid via context menu. 3. ExcludeÈ›i fiÈ™ierele È™i dosarele direct de pe grila principală cu ajutorul meniului contextual. <Automatic> -<Automată> +<Sincronizare Inteligentă> <Directory> <Dosar> <Last session> @@ -148,8 +148,6 @@ <selectare multiplă> A newer version of FreeFileSync is available: Este disponibilă o versiune nouă de FreeFileSync: -ATTENTION: Failed directory access can lead to file deletions! -ATENÈšIE: EÈ™ecul accesului la dosar poate duce la È™tergerea de fiÈ™iere! Abort requested: Waiting for current operation to finish... Abandonare solicitată: Se aÈ™teaptă terminarea operaÈ›iunii în curs... Aborted @@ -158,22 +156,26 @@ About Despre Action AcÈ›iune +Activate filter +Activează filtrul Add folder Adaugă Dosar Add folder pair Adaugă Pereche Nouă de Dosare +All directories in sync! +Toate dosarele au fost sincronizate! An exception occured! A apărut o excepÈ›ie ! As a result the files are separated into the following categories: -ÃŽn concluzie, fiÈ™ierele sînt repartizate în categoriile următoare : +ÃŽn concluzie, fiÈ™ierele sînt repartizate în categoriile următoare: As the name suggests, two files which share the same name are marked as equal if and only if they have the same content. This option is useful for consistency checks rather than backup operations. Therefore the file times are not taken into account at all.\n\nWith this option enabled the decision tree is smaller: -AÈ™a cum sugerează È™i numele, două fiÈ™iere cu acelaÈ™i nume sînt considerate identice dacă È™i numai dacă este identic È™i conÈ›inutul lor. Această opÈ›iune este utilă mai degrabă pentru verificările de consecvență decît pentru operaÈ›iunile de salvgardare [backup]. AÈ™a că timpurile fiÈ™ierelor (data È™i ora) nu sînt luaÈ›i deloc în considerare.\n\nCu această opÈ›iune activată, arborele de decizie e mai simplu : +AÈ™a cum sugerează È™i numele, două fiÈ™iere cu acelaÈ™i nume sînt considerate identice dacă È™i numai dacă este identic È™i conÈ›inutul lor. Această opÈ›iune este utilă mai degrabă pentru verificările de consecvență decît pentru operaÈ›iunile de salvgardare [backup]. AÈ™a că timpurile fiÈ™ierelor (data È™i ora) nu sînt luaÈ›i deloc în considerare.\n\nCu această opÈ›iune activată, arborele de decizie e mai simplu: Assemble a batch file for automated synchronization. To start in batch mode simply pass the name of the file to the FreeFileSync executable: FreeFileSync.exe <batchfile>. This can also be scheduled in your operating system's task planner. -Se poate crea un fiÈ™ier cu un lot de comenzi [batch file] pentru sincronizarea automată. Pentru a porni în modul lot, indicaÈ›i astfel numele fiÈ™ierului lot pentru prelucrarea sa de către executabilul FreeFileSync : freefilesync.exe <fiÈ™ier lot>. Această operaÈ›iune poate fi programată în planificatorul de sarcini al sistemului de operare [task scheduler]. +Se poate crea un fiÈ™ier cu un lot de comenzi [batch file] pentru sincronizarea inteligentă. Pentru a porni în modul lot, indicaÈ›i astfel numele fiÈ™ierului lot pentru prelucrarea sa de către executabilul FreeFileSync: freefilesync.exe <fiÈ™ier lot>. Această operaÈ›iune poate fi programată în planificatorul de sarcini al sistemului de operare [task scheduler]. Auto-adjust columns Autoajustează Coloanele Automatic mode -Mod Automat +Mod Inteligent Batch execution Execută FiÈ™ierul Lot Batch file created successfully! @@ -181,13 +183,13 @@ FiÈ™ierul cu lotul de comenzi a fost creat cu succces ! Batch job Sarcină Lot Big thanks for localizing FreeFileSync goes out to: -MulÈ›umiri pentru traducerea FreeFileSync : +MulÈ›umiri pentru traducerea FreeFileSync: Both sides have changed since last synchronization! Ambele părÈ›i s-au modificat de la ultima sincronizare! Browse Explorează Build: -Compilat la : +Compilat la: Cancel Anulează Cannot determine sync-direction: Changed filter settings! @@ -197,11 +199,7 @@ Nu se poate determina sensul de sincronizare: Nici o modificare de la ultima sin Category Categorie Change direction -Schimbă Sensul -Check all -Bifează Tot -Choose to hide filtered files/directories from list -Ascunde sau arată fiÈ™ierele/dosarele filtrate din listă +Schimbă în Sensul IconiÈ›ei Comma separated list Listă de elemente separate prin virgulă Commandline @@ -237,15 +235,13 @@ ConfiguraÈ›ie Configuration loaded! ConfiguraÈ›ie încărcată ! Configuration overview: -Panorama ConfiguraÈ›iei : +Panorama ConfiguraÈ›iei: Configuration saved! ConfiguraÈ›ie salvată ! Configure filter Configurează Filtrul -Configure filter... -Configurează Filtrul Configure your own synchronization rules. -Aplicare a regulilor de sincronizare definite de utilizator pentru fiecare situaÈ›ie. Definirea se face cu butoanele colorate din partea dreaptă a panoului. +Reguli de sincronizare definite de utilizator pentru fiecare situaÈ›ie. Definirea se face cu butoanele colorate din partea dreaptă a panoului, care apar la clicarea pe Clonare sau Actualizare. Confirm Confirmare Conflict detected: @@ -257,13 +253,13 @@ Continuă Conversion error: Eroare de convertire: Copy from left to right -Copiază de la stînga la dreapta +Copiază de la Stînga la Dreapta Copy from left to right overwriting -Copiază de la stînga la dreapta cu suprascriere +Copiază de la Stînga la Dreapta cu Suprascriere Copy from right to left -Copiază de la dreapta la stînga +Copiază de la Dreapta la Stînga Copy from right to left overwriting -Copiază de la dreapta la stînga cu suprascriere +Copiază de la Dreapta la Stînga cu Suprascriere Copy new or updated files to right folder. Copiere în dosarul din dreapta a fiÈ™ierelor actualizate sau noi. Copy to clipboard\tCTRL+C @@ -283,9 +279,9 @@ Creează o Sarcină Lot Creating folder %x Creez dosarul %x Current operation: -OperaÈ›iunea curentă : +OperaÈ›ia Curentă: Custom -Personalizată +Sincronizare Personalizată Customize columns Personalizează coloanele Customize... @@ -295,7 +291,7 @@ Clic-Dreapta DECISION TREE ARBORE DECIZIONAL Data remaining: -Date rămase : +Date Rămase: Data verification error: Source and target file have different content! Eroare la verificarea datelor: FiÈ™ierele sursă È™i È›intă au conÈ›inut diferit! Date @@ -303,11 +299,11 @@ Dată Delay ÃŽntîrziere Delay between detection of changes and execution of commandline in seconds -ÃŽntîrziere în secunde între detectarea modificărilor ÅŸi executarea liniei de comandă +ÃŽntîrziere în secunde între detectarea modificărilor È™i executarea liniei de comandă Delete files/folders existing on left side only -Șterge doar fiÈ™ierele/dosarele din partea stîngă +Șterge Itemul din Stînga Delete files/folders existing on right side only -Șterge doar fiÈ™ierele/dosarele din partea dreaptă +Șterge Itemul din Dreapta Delete files\tDEL Șterge FiÈ™ierele\tDEL Delete on both sides @@ -333,13 +329,11 @@ Dosare de monitorizat Directory Dosar Directory does not exist: -Dosarul nu există : -Do not display visual status information but write to a logfile instead -Nu se afiÈ™ează informaÈ›iile despre stare, dar ele se scriu într-un fiÈ™ier jurnal [log] +Dosarul nu există: Do not show this dialog again -Nu afiÈ™a din nou acest dialog +Nu afiÈ™a acest dialog din nou Do nothing -Nici o acÈ›iune +Nici o AcÈ›iune Do you really want to delete the following objects(s)? Sigur doriÈ›i să È™tergeÈ›i următoarele elemente ? Do you really want to move the following objects(s) to the Recycle Bin? @@ -406,12 +400,12 @@ Error writing file: Eroare la scrierea fiÈ™ierului: Error writing to synchronization database: Eroare la scrierea în baza de date a sincronizării: -Source directory does not exist anymore: -Dosarul sursă nu mai există: Example Exemplu Exclude Excluse +Exclude all rows +Exclude Toate Rîndurile Exclude temporarily Exclude Temporar Exclude via filter: @@ -422,6 +416,8 @@ Exit with RC < 0 IeÈ™i cu RC < 0 External applications AplicaÈ›ii Externe +Fatal Error +Eroare Fatală Feedback and suggestions are welcome at: Opiniile È™i sugestiile sînt binevenite: File %x has an invalid date! @@ -447,7 +443,7 @@ FiÈ™ierele sînt considerate identice dacă\n - conÈ›inutul\neste identic. Files are found equal if\n - filesize\n - last write time and date\nare the same. FiÈ™ierele sînt considerate identice dacă\n - mărimea\n - È™i data ultimei modificări\nsînt identice. Files remaining: -FiÈ™iere rămase: +FiÈ™iere Rămase: Files that are equal on both sides FiÈ™iere identice în ambele părÈ›i Files that exist on both sides and have different content @@ -459,23 +455,25 @@ FiÈ™iere care există în ambele părÈ›i, cel din dreapta fiind mai nou Files/folders found: FiÈ™iere/dosare găsite: Files/folders remaining: -FiÈ™iere/dosare rămase: +Itemuri Rămase: Files/folders that exist on left side only FiÈ™iere sau dosare care există doar în partea stîngă Files/folders that exist on right side only FiÈ™iere sau dosare care există doar în partea dreaptă Filter Filtrare -Filter active: Press again to deactivate -Filtru activ: clicaÈ›i din nou pentru a-l dezactiva Filter files Filtrează FiÈ™ierele +Filter has been selected +Filtrul a fost selectat Filter view Filtru de Vedere +Filtering is deactivated +Filtrarea este dezactivată Folder Comparison and Synchronization Comparare È™i Sincronizare de Dosare Free disk space available: -SpaÈ›iu disponibil pe hardisc : +SpaÈ›iu disponibil pe hardisc: FreeFileSync - Folder Comparison and Synchronization FreeFileSync - Comparare È™i Sincronizare de Dosare FreeFileSync Batch Job @@ -494,6 +492,8 @@ Generating database... Generez baza de date... Generating file list... Generez lista de fiÈ™iere... +Global filter +Filtru Global Global settings Setări Globale Help @@ -504,6 +504,8 @@ Hide all error and warning messages Se ascund toate mesajele de eroare È™i de avertizare Hide conflicts Ascunde conflictele +Hide excluded items +Ascunde itemurile excluse Hide files that are different Ascunde fiÈ™ierele care sînt diferite Hide files that are equal @@ -530,14 +532,16 @@ Hide files that will be overwritten on right side Ascunde fiÈ™ierele care vor fi suprascrise în dreapta Hide files that won't be copied Ascunde fiÈ™ierele care nu vor fi copiate -Hide filtered items -Ascunde itemurile filtrate +Hide filtered or temporarily excluded files +Ascunde fiÈ™ierele filtrate sau excluse temporar Hide further error messages during the current process Ascunde mesajele de eroare apărute ulterior în timpul acestui proces Hints: Sfaturi: Homepage Sit +Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically. +Identifică È™i propagă modificările în ambele părÈ›i folosind o bază de date. Ștergerile È™i conflictele sînt detectate automat. If you like FFS Donare pentru FFS Ignore 1-hour file time difference @@ -545,31 +549,33 @@ Ignoră diferenÈ›ele de 1 oră ale timpurilor fiÈ™ierelor Ignore errors Ignoră erorile Ignore subsequent errors -Ignoră erorile ulterioare +Ignoră (nu lua în seamă) erorile ulterioare Ignore this error, retry or abort synchronization? -Ignor eroarea, reîncerc sau abandonez sincronizarea ? +IgnoraÈ›i eroarea, reîncercaÈ›i sau anulaÈ›i sincronizarea? Ignore this error, retry or abort? -Ignor eroarea, reîncerc sau abandonez? +IgnoraÈ›i eroarea, reîncercaÈ›i sau anulaÈ›i? Include Incluse +Include all rows +Include Toate Rîndurile Include temporarily -Include temporar +Include Temporar Include: *.doc;*.zip;*.exe\nExclude: temp\\* -Incluse : *.doc;*.zip;*.exe\nExcluse : temp\\* +Incluse: *.doc;*.zip;*.exe\nExcluse: temp\\* Incompatible synchronization database format: Format incompatibil al bazei de date a sincronizării: Info Info Information InformaÈ›ii -Initial synchronization. -Sincronizare iniÈ›ială. +Initial synchronization: +Sincronizare iniÈ›ială: Integrate external applications into context menu. The following macros are available: Include aplicaÈ›iile externe în meniul contextual. Sînt disponibile următoarele macrocomenzi: It was not possible to initialize the Recycle Bin!\n\nIt's likely that you are not using Windows.\nIf you want this feature included, please contact the author. :) IniÈ›ializarea Reciclatorului nu a fost posibilă!\n\nCauza poate fi faptul că nu utilizaÈ›i SO Windows.\nDacă doriÈ›i să utilizaÈ›i această funcÈ›ionalitate, contactaÈ›i autorul. :) Leave as unresolved conflict -Lasă ca un conflict nerezolvat +Lasă ca Conflict Nerezolvat Left Stînga Legend @@ -578,6 +584,8 @@ Load configuration from file ÃŽncarcă configuraÈ›ia dintr-un fiÈ™ier Load configuration history (press DEL to delete items) ÃŽncarcă istoricul configuraÈ›iei (apăsaÈ›i tasta DEL pentru a È™terge itemuri) +Local filter +Filtru Local Log-messages: Mesaje de jurnalizare: Logging @@ -602,8 +610,8 @@ Moving folder %x to user-defined directory %y Mut dosarul %x în dosarul %y ales de utilizator Multiple... Multiplu... -No database file existing yet: -Nu există încă un fiÈ™ier cu baza de date: +No filter selected +Nu a fost selectat nici un filtru Not enough free disk space available in: SpaÈ›iu de stocare insuficient pe: Nothing to synchronize according to configuration! @@ -638,8 +646,8 @@ Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) i CopiaÈ›i fiÈ™ierul \"Shadow.dll\" (din arhiva \"Shadow.zip\") în dosarul de instalare FreeFileSync pentru a putea utiliza această funcÈ›ionalitate. Please fill all empty directory fields. CompletaÈ›i toate cîmpurile unde trebuie să apară adrese ale dosarelor comparate. -Press button to activate filter -ClicaÈ›i butonul pentru a activa filtrul +Please run a Compare first before synchronizing! +RulaÈ›i compararea înainte de a sincroniza! Published under the GNU General Public License: Publicat sub licenÈ›a GNU GPL: Question @@ -649,7 +657,7 @@ IeÈ™i Re-enable all hidden dialogs? ReactivaÈ›i casetele de dialog ascunse? RealtimeSync - Automated Synchronization -RealtimeSync - Sincronizare Automatizată +RealtimeSync - Sincronizare Inteligentă RealtimeSync configuration RealtimeSync configuraÈ›ie Relative path @@ -660,12 +668,16 @@ Remove folder ÃŽnlătură Dosarul Remove folder pair ÃŽnlătură Perechea de Dosare +Remove local filter settings +ÃŽnlătură ConfiguraÈ›ia Filtrului Local Report translation error Raportarea erorilor de traducere Reset Resetează Right Dreapta +Run minimized and write status information to a logfile +Rulează minimizat È™i scrie informaÈ›iile de stare într-un jurnal S&ave configuration S&alvează ConfiguraÈ›ia S&witch view @@ -680,14 +692,14 @@ Scanning: Scanez: Select a folder SelectaÈ›i un dosar -Select alternate filter settings -SelectaÈ›i o altă configuraÈ›ie a filtrului Select alternate synchronization settings SelectaÈ›i o altă configuraÈ›ie a sincronizării Select logfile directory: SelectaÈ›i un dosar pentru fiÈ™ierul .log: Select variant: SelectaÈ›i Varianta de Sincronizare: +Setting default synchronization directions. Please check whether they are appropriate for you. +Va fi setat sensul implicit de sincronizare. VerificaÈ›i dacă se potriveÈ™te cu ceea ce doriÈ›i. Show conflicts Arată conflictele Show file icons @@ -732,8 +744,10 @@ Size Mărime Source code written completely in C++ utilizing: Cod sursă scris complet în C++ folosind: +Source directory does not exist anymore: +Dosarul sursă nu mai există: Speed: -Viteză : +Viteză: Start PorneÈ™te Start synchronization @@ -772,22 +786,26 @@ Target directory already existing! Dosarul È›intă există deja! Target file already existing! FiÈ™ierul È›intă există deja! +The database file is not yet existing, but will be created during synchronization: +FiÈ™ierul cu baza de date nu există încă, dar va fi creat în cursul sincronizării: The file does not contain a valid configuration: FiÈ™ierul nu conÈ›ine o configuraÈ›ie validă: +The required database entry is not yet existing, but will be created during synchronization: +Intrarea solicitată din baza de date nu există încă, dar va fi creată în cursul sincronizării: This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. Această variantă defineÈ™te două fiÈ™iere cu acelaÈ™i nume ca fiind identice atunci cînd au aceeaÈ™i mărime ȘI aceeaÈ™i dată È™i oră a ultimei modificări. Time Oră Time elapsed: -Timp scurs : +Timp Scurs: Time remaining: -Timp rămas : +Timp Rămas: Total amount of data that will be transferred Volumul total de date care va fi transferat Total required free disk space: SpaÈ›iu de stocare necesar: Total time: -Timp total : +Timp Total: Treat file times that differ by exactly +/- 1 hour as equal, less than 1 hour as conflict in order to handle Daylight Saving Time changes. Tratează ca egale timpurile fiÈ™ierelor care diferă exact cu +/- 1 oră, iar cele care diferă cu mai puÈ›in de 1 oră, ca niÈ™te conflicte generate de gestiunea orei de vară. Two way <-> @@ -798,8 +816,6 @@ Unable to create logfile! FiÈ™ierul jurnal nu poate fi creat! Unable to initialize Recycle Bin! Reciclatorul nu poate fi iniÈ›ializat! -Uncheck all -Debifează Tot Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization. Există conflicte nerezolvate!\n\nPuteÈ›i ignora conflictele pentru a continua cu sincronizarea. Update -> @@ -814,8 +830,6 @@ User-defined directory Mută într-un dosar personalizat User-defined directory for deletion was not specified! Dosarul ales de utilizator pentru È™tergere nu a fost specificat ! -Using default synchronization directions. Please recheck. -Se folosesc sensurile implicite de sincronizare. ReverificaÈ›i. Variant Varianta Sincronizării Verifying file %x @@ -825,7 +839,7 @@ Numele volumului %x nu face parte din numele fiÈ™ierului %y ! Warning Avertisment Warning: Synchronization failed for %x item(s): -AtenÈ›ie : Sincronizarea a eÈ™uat pentru %x itemuri : +AtenÈ›ie: Sincronizarea a eÈ™uat pentru %x itemuri: When the comparison is started with this option set the following decision tree is processed: Cînd compararea este pornită cu acest set de opÈ›iuni, este executat următorul arbore de decizie: You can ignore the error to consider not existing directories as empty. diff --git a/BUILD/Languages/russian.lng b/BUILD/Languages/russian.lng index 963e388c..f2dd49ef 100644 --- a/BUILD/Languages/russian.lng +++ b/BUILD/Languages/russian.lng @@ -148,8 +148,6 @@ <групповое выделение> A newer version of FreeFileSync is available: ДоÑтупна Ð½Ð¾Ð²Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ FreeFileSync: -ATTENTION: Failed directory access can lead to file deletions! -Ð’ÐИМÐÐИЕ: Отказ в доÑтупе к каталогу может привеÑти к удалению файла! Abort requested: Waiting for current operation to finish... Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ñ‹: Ожидайте, пока Ñ‚ÐµÐºÑƒÑ‰Ð°Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐ¸Ñ‚ÑÑ... Aborted @@ -158,10 +156,14 @@ About О программе Action ДейÑтвие +Activate filter +Включить фильтр Add folder Добавить папку Add folder pair Добавить пару папок +All directories in sync! +Ð’Ñе папки Ñинхронизированы! An exception occured! ИÑключение произошло! As a result the files are separated into the following categories: @@ -198,10 +200,6 @@ Category ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ Change direction ПоменÑÑ‚ÑŒ направление -Check all -Проверить вÑе -Choose to hide filtered files/directories from list -Выберите Ð´Ð»Ñ ÑÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ð¾Ñ‚Ñ„Ð¸Ð»ÑŒÑ‚Ñ€Ð¾Ð²Ð°Ð½Ð½Ñ‹Ñ… файлов/папок из ÑпиÑка Comma separated list СпиÑок, разделÑемый запÑтыми Commandline @@ -242,8 +240,6 @@ Configuration saved! ÐаÑтройка Ñохранена! Configure filter ÐаÑтройка фильтра -Configure filter... -ÐаÑтроить фильтр Configure your own synchronization rules. ÐаÑтроить Ñвои ÑобÑтвенные правила Ñинхронизации. Confirm @@ -334,8 +330,6 @@ Directory Папка Directory does not exist: Папка не ÑущеÑтвует: -Do not display visual status information but write to a logfile instead -Ðе показывать информацию по ÑтатуÑу, но запиÑывать в лог-файл Do not show this dialog again Больше не показывать Ñто окно Do nothing @@ -406,12 +400,12 @@ Error writing file: Ошибка при запиÑи файла: Error writing to synchronization database: Ошибка при запиÑи в базу данных Ñинхронизации: -Source directory does not exist anymore: -ИÑÑ…Ð¾Ð´Ð½Ð°Ñ Ð¿Ð°Ð¿ÐºÐ° больше не ÑущеÑтвует: Example Пример Exclude ИÑÐºÐ»ÑŽÑ‡Ð°Ñ +Exclude all rows +ИÑключить вÑе Ñтроки Exclude temporarily ИÑключить временные Exclude via filter: @@ -422,6 +416,8 @@ Exit with RC < 0 Выход Ñ RC <0 External applications Внешние Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ +Fatal Error +КритичеÑÐºÐ°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° Feedback and suggestions are welcome at: Отзывы и Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸Ñылайте по адреÑу: File %x has an invalid date! @@ -466,12 +462,14 @@ Files/folders that exist on right side only Файлы/папки, ÑущеÑтвующие только на правой Ñтороне Filter Фильтр -Filter active: Press again to deactivate -Фильтр активен: Ðажмите еще раз Ð´Ð»Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Filter files Фильтр файлов +Filter has been selected +Фильтр уÑтановлен Filter view Вид фильтра +Filtering is deactivated +Ð¤Ð¸Ð»ÑŒÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð²Ñ‹ÐºÐ»ÑŽÑ‡ÐµÐ½Ð° Folder Comparison and Synchronization Сравнение и ÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Free disk space available: @@ -494,6 +492,8 @@ Generating database... Создание базы данных... Generating file list... Создание ÑпиÑка файлов... +Global filter +Глобальный фильтр Global settings Глобальные наÑтройки Help @@ -504,6 +504,8 @@ Hide all error and warning messages Скрывать вÑе ошибки и ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñ Ð¿Ñ€ÐµÐ´ÑƒÐ¿Ñ€ÐµÐ¶Ð´ÐµÐ½Ð¸Ñми Hide conflicts Скрыть конфликтующие файлы +Hide excluded items +Скрыть иÑключенные пункты Hide files that are different Скрыть различающиеÑÑ Ñ„Ð°Ð¹Ð»Ñ‹ Hide files that are equal @@ -530,14 +532,16 @@ Hide files that will be overwritten on right side Скрыть файлы, которые будут перезапиÑаны на правой Ñтороне Hide files that won't be copied Скрыть файлы, которые не будут Ñкопированы -Hide filtered items -Скрыть отфильтрованные +Hide filtered or temporarily excluded files +Скрыть отфильтрованные или временно иÑключенные файлы Hide further error messages during the current process Скрыть поÑледующие ошибки во Ð²Ñ€ÐµÐ¼Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ³Ð¾ процеÑÑа Hints: ПодÑказка: Homepage Оф.Ñайт +Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically. +Ð’Ñ‹Ñвление и раÑпроÑтранение изменений на обеих Ñторонах Ñ Ð¸Ñпользованием базы данных. Удаленные файлы и конфликты определÑÑŽÑ‚ÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки. If you like FFS ЕÑли Вам понравилÑÑ FFS Ignore 1-hour file time difference @@ -552,6 +556,8 @@ Ignore this error, retry or abort? Игнорировать Ñту ошибку, повторить или отменить? Include Ð’ÐºÐ»ÑŽÑ‡Ð°Ñ +Include all rows +Ð’ÐºÐ»ÑŽÑ‡Ð°Ñ Ð²Ñе Ñтроки Include temporarily Ð’ÐºÐ»ÑŽÑ‡Ð°Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ðµ Include: *.doc;*.zip;*.exe\nExclude: temp\\* @@ -562,8 +568,8 @@ Info Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Information Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ -Initial synchronization. -ÐŸÐµÑ€Ð²Ð¾Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ ÑинхронизациÑ. +Initial synchronization: +ÐŸÐµÑ€Ð²Ð¾Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ ÑинхронизациÑ: Integrate external applications into context menu. The following macros are available: Интегрирует внешние Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð² контекÑтное меню.\nСледующие команды доÑтупны: It was not possible to initialize the Recycle Bin!\n\nIt's likely that you are not using Windows.\nIf you want this feature included, please contact the author. :) @@ -578,6 +584,8 @@ Load configuration from file Загрузить конфигурацию из файла Load configuration history (press DEL to delete items) Выбрать конфигурацию из ÑпиÑка (нажмите DEL Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¿ÑƒÐ½ÐºÑ‚Ð¾Ð²) +Local filter +Локальный фильтр Log-messages: Лог-ÑообщениÑ: Logging @@ -602,8 +610,8 @@ Moving folder %x to user-defined directory %y Перемещение папки %x в заданную пользователем папку %y Multiple... Различные варианты Ñинхронизации -No database file existing yet: -Файла базы данных еще не ÑущеÑтвует: +No filter selected +Ðи один фильтр не выбран Not enough free disk space available in: Ðе доÑтаточно Ñвободного меÑта в: Nothing to synchronize according to configuration! @@ -638,8 +646,8 @@ Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) i ПожалуйÑта, Ñкопируйте ÑоответÑтвующий \"Shadow.dll\" (находÑщийÑÑ Ð² архиве \"Shadow.zip\") в папку уÑтановки FreeFileSync Ð´Ð»Ñ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ñтой функции. Please fill all empty directory fields. ПожалуйÑта, заполните вÑе пуÑтые Ð¿Ð¾Ð»Ñ Ð¿Ð°Ð¿Ð¾Ðº -Press button to activate filter -Включить фильтр +Please run a Compare first before synchronizing! +ПожалуйÑта, запуÑтите Ñравнение перед Ñинхронизацией! Published under the GNU General Public License: ИздаетÑÑ Ð¿Ð¾Ð´ GNU General Public License: Question @@ -660,12 +668,16 @@ Remove folder Удалить папку Remove folder pair Удалить пару папок +Remove local filter settings +Удалить наÑтройки локального фильтра Report translation error Сообщить об ошибке перевода Reset СброÑить Right Справа +Run minimized and write status information to a logfile +ЗапуÑтить Ñвернутым и пиÑать информацию по ÑтатуÑу в лог-файл S&ave configuration Сохранить конфигурацию... S&witch view @@ -680,14 +692,14 @@ Scanning: Сканирую: Select a folder Выбрать папку -Select alternate filter settings -Выбрать альтернативные наÑтройки фильтра Select alternate synchronization settings Выбрать альтернативные наÑтройки Ñинхронизации Select logfile directory: Выберите папку Ð´Ð»Ñ Ð»Ð¾Ð³-файлов: Select variant: Выберите вариант: +Setting default synchronization directions. Please check whether they are appropriate for you. +Ðаправление Ñинхронизации выÑтавлено по умолчанию. ПожалуйÑта, проверьте, подходит ли оно Ð´Ð»Ñ Ð’Ð°Ñ. Show conflicts Показать конфликтующие файлы Show file icons @@ -732,6 +744,8 @@ Size Размер Source code written completely in C++ utilizing: ИÑходный код напиÑан на С++ Ñ Ð¸Ñпользованием: +Source directory does not exist anymore: +ИÑÑ…Ð¾Ð´Ð½Ð°Ñ Ð¿Ð°Ð¿ÐºÐ° больше не ÑущеÑтвует: Speed: СкороÑÑ‚ÑŒ: Start @@ -761,7 +775,7 @@ Synchronize all .doc, .zip and .exe files except everything in subfolder \"temp\ Synchronize both sides simultaneously: Copy new or updated files in both directions. Синхронизировать обе Ñтороны одновременно: копировать новые или обновлÑÑ‚ÑŒ файлы в обоих направлениÑÑ…. Synchronize both sides using a database. Deletions are detected automatically. -Синхронизировать обе Ñтороны, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð±Ð°Ð·Ñƒ данных. Удаленные файлы/папки определÑÑŽÑ‚ÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки. +Синхронизировать обе Ñтороны, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð±Ð°Ð·Ñƒ данных\nУдаленные файлы/папки определÑÑŽÑ‚ÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки Synchronize... Синхронизировать Synchronizing... @@ -772,8 +786,12 @@ Target directory already existing! ÐšÐ¾Ð½ÐµÑ‡Ð½Ð°Ñ Ð¿Ð°Ð¿ÐºÐ° уже ÑущеÑтвует! Target file already existing! Конечный файл уже ÑущеÑтвует! +The database file is not yet existing, but will be created during synchronization: +Файл базы данных еще не ÑущеÑтвует, но будет Ñоздан во Ð²Ñ€ÐµÐ¼Ñ Ñинхронизации: The file does not contain a valid configuration: Файл не Ñодержит дейÑтвительную конфигурацию: +The required database entry is not yet existing, but will be created during synchronization: +Требуемой запиÑи еще не ÑущеÑтвует в базе данных, но она будет Ñоздана во Ð²Ñ€ÐµÐ¼Ñ Ñинхронизации: This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. Ðтот вариант Ñравнивает два файла Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñ‹Ð¼Ð¸ именами и Ñчитает их равными, еÑли они имеют одинаковый размер файла и одинаковую дату и Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ñледнего изменениÑ. Time @@ -798,8 +816,6 @@ Unable to create logfile! Ðевозможно Ñоздать лог! Unable to initialize Recycle Bin! Ðевозможно инициализировать "Корзину"! -Uncheck all -СнÑÑ‚ÑŒ выделение Ñо вÑех Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization. СущеÑтвуют нерешенные конфликты \n\nÐ’Ñ‹ можете проигнорировать их и продолжить Ñинхронизацию. Update -> @@ -814,8 +830,6 @@ User-defined directory ИÑпользовать заданную пользователем папку User-defined directory for deletion was not specified! ПользовательÑÐºÐ°Ñ Ð¿Ð°Ð¿ÐºÐ° Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð½Ðµ была указана! -Using default synchronization directions. Please recheck. -ИÑпользуютÑÑ Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñинхронизации по-умолчанию. ПожалуйÑта, перепроверьте. Variant Вариант Verifying file %x diff --git a/BUILD/Languages/slovenian.lng b/BUILD/Languages/slovenian.lng index b84087c7..1dab4ba0 100644 --- a/BUILD/Languages/slovenian.lng +++ b/BUILD/Languages/slovenian.lng @@ -148,8 +148,6 @@ Duplikat z druge strani od %name <mnogokratna izbira> A newer version of FreeFileSync is available: Na voljo je nova razliÄica FreeFileSync: -ATTENTION: Failed directory access can lead to file deletions! -POZOR: NeuspeÅ¡en dostop do imenika lahko vodi do izbrisa datotek! Abort requested: Waiting for current operation to finish... Zahtevana je bila prekinitev: Äakam, da se zakljuÄi trenutna operacija... Aborted @@ -158,10 +156,14 @@ About O programu(1) Action Ukrep +Activate filter +Aktiviraj filter Add folder Dodaj mapo Add folder pair Dodaj par imenikov +All directories in sync! +Vsi imeniki so sinhronizirani! An exception occured! Zgodila se je napaka! As a result the files are separated into the following categories: @@ -169,7 +171,7 @@ Kot rezultat so datoteke razdeljene v naslednje kategorije: As the name suggests, two files which share the same name are marked as equal if and only if they have the same content. This option is useful for consistency checks rather than backup operations. Therefore the file times are not taken into account at all.\n\nWith this option enabled the decision tree is smaller: Kot že samo ime pove, sta dve datoteki oznaÄeni kot enaki samo takrat, ko imata enako vsebino. Ta možnost je bolj uporabna za preverjanje doslednosti kot za operacije varnostnega shranjevanja. Zaradi tega se Äasi datotek ne upoÅ¡tevajo.\n\nZ omogoÄeno to možnostjo je drevo odloÄanja manjÅ¡e: Assemble a batch file for automated synchronization. To start in batch mode simply pass the name of the file to the FreeFileSync executable: FreeFileSync.exe <batchfile>. This can also be scheduled in your operating system's task planner. -Sestavi batch datoteko za samodejno sinhronizacijo. Da zaÄnete v batch naÄinu, preprosto podajte ime datoteke k FreeFileSync izvrÅ¡ilni datoteki: FreeFileSync.exe <imedatotekebatch>. To se lahko tudi nastavi v urniku opravil vaÅ¡ega operacijskega sistema. +Sestavi batch datoteko za samodejno sinhronizacijo. Da zaÄnete v batch naÄinu, preprosto podajte ime batch datoteke k FreeFileSync izvrÅ¡ilni datoteki: FreeFileSync.exe <imedatotekebatch>. To se lahko nastavi tudi v urniku opravil vaÅ¡ega operacijskega sistema. Auto-adjust columns Samo-prilagodi stolpce Automatic mode @@ -198,10 +200,6 @@ Category Kategorija Change direction Spremeni smer -Check all -Preveri vse -Choose to hide filtered files/directories from list -Skrij filtrirane datoteke/imenike iz seznama Comma separated list Seznam loÄen z vejico Commandline @@ -242,8 +240,6 @@ Configuration saved! Konfiguracija shranjena! Configure filter Konfiguriraj filter -Configure filter... -Konfiguriraj filter... Configure your own synchronization rules. Konfigurirajte vaÅ¡a lastna sinhronizacijska pravila. Confirm @@ -334,8 +330,6 @@ Directory Imenik Directory does not exist: Imenik ne obstaja: -Do not display visual status information but write to a logfile instead -Ne prikazuj vidnih statusnih informacij, ampak piÅ¡i v dnevniÅ¡ko datoteko Do not show this dialog again Ne prikaži veÄ tega pogovornega okna Do nothing @@ -355,7 +349,7 @@ Povleci && spusti Email Email Enable filter to exclude files from synchronization -OmogoÄi filter, da se datoteke izkljuÄi iz sinhronizacije +OmogoÄi filter da se datoteke izkljuÄi iz sinhronizacije Endless loop when traversing directory: NeskonÄna zanka pri prehodu imenika: Error @@ -406,12 +400,12 @@ Error writing file: Napaka pri pisanju datoteke: Error writing to synchronization database: Napaka pri pisanju v sinhronizacijsko podatkovno bazo: -Source directory does not exist anymore: -Izvorni imenik ne obstaja veÄ: Example Primer Exclude IzkljuÄi +Exclude all rows +IzkljuÄi vse vrstice Exclude temporarily ZaÄasno izkljuÄi Exclude via filter: @@ -422,6 +416,8 @@ Exit with RC < 0 Zapusti z RC < 0 External applications Zunanje aplikacije +Fatal Error +Usodna napaka Feedback and suggestions are welcome at: Povratne informacije in predlogi so dobrodoÅ¡li na: File %x has an invalid date! @@ -466,12 +462,14 @@ Files/folders that exist on right side only Datoteke/mape, ki obstajajo samo na desni strani Filter Filter -Filter active: Press again to deactivate -Filter aktiven: Ponovno kliknite za deaktivacijo Filter files Filtriraj datoteke +Filter has been selected +Filter je bil izbran Filter view Filtriran pogled +Filtering is deactivated +Filter je deaktiviran Folder Comparison and Synchronization Primerjava in sinhronizacija imenika Free disk space available: @@ -494,6 +492,8 @@ Generating database... Ustvarjam podatkovno bazo... Generating file list... Ustvarjam seznam datotek... +Global filter +Globalni filter Global settings Globalne nastavitve Help @@ -504,6 +504,8 @@ Hide all error and warning messages Skrij vsa obvestila o napakah in opozorilih Hide conflicts Skrij spore +Hide excluded items +Skrij izkljuÄene predmete Hide files that are different Skrij datoteke ki so razliÄne Hide files that are equal @@ -530,14 +532,16 @@ Hide files that will be overwritten on right side Skrij datoteke, ki bodo prepisane na desni strani Hide files that won't be copied Skrij datoteke, ki ne bodo kopirane -Hide filtered items -Skrij filtrirane predmete +Hide filtered or temporarily excluded files +Skrij filtrirane ali zaÄasno izkljuÄene datoteke Hide further error messages during the current process Skrijte nadaljnja obvestila o napakah med trenutnim procesom Hints: Namigi: Homepage DomaÄa stran +Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically. +Prepoznaj in Å¡iri spremembe na obeh straneh z uporabo podatkovne baze. Izbrisi in spori so zaznani samodejno. If you like FFS ÄŒe vam je FFS vÅ¡eÄ Ignore 1-hour file time difference @@ -552,6 +556,8 @@ Ignore this error, retry or abort? Ignoriraj to napako, poskusi ponovno ali prekini? Include VkljuÄi +Include all rows +VkljuÄi se vrstice Include temporarily Trenutno vkljuÄi Include: *.doc;*.zip;*.exe\nExclude: temp\\* @@ -562,8 +568,8 @@ Info Info Information Informacije -Initial synchronization. -ZaÄetna sinhronizacija. +Initial synchronization: +ZaÄetna sinhronizacija: Integrate external applications into context menu. The following macros are available: Integriraj zunanje aplikacije v kontekstni menu. Na voljo so naslednji makri: It was not possible to initialize the Recycle Bin!\n\nIt's likely that you are not using Windows.\nIf you want this feature included, please contact the author. :) @@ -578,6 +584,8 @@ Load configuration from file Naloži konfiguracijo iz datoteke Load configuration history (press DEL to delete items) Naloži zgodovino konfiguracije (pritisnite DEL za brisanje predmetov) +Local filter +Lokalni filter Log-messages: SporoÄila beleženja: Logging @@ -602,8 +610,8 @@ Moving folder %x to user-defined directory %y Premikam mapo %x v uporabniÅ¡ko-doloÄen imenik %y Multiple... VeÄkratno... -No database file existing yet: -Datoteka podatkovne baze Å¡e ne obstaja: +No filter selected +Noben filter ni izbran Not enough free disk space available in: Na voljo ni dovolj prostega prostora na disku v: Nothing to synchronize according to configuration! @@ -638,8 +646,8 @@ Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) i Prosim prekopirajte ustrezno \"Shadow.dll\" (ki se nahaja v \"Shadow.zip\" arhivu) v FreeFileSync namestitveni imenik, da omogoÄite to lastnost. Please fill all empty directory fields. Prosim izpolnite vse imenike s praznimi polji. -Press button to activate filter -Kliknite za aktivacijo filtra +Please run a Compare first before synchronizing! +Prosim najprej zaženite Primerjaj preden sinhronizirate! Published under the GNU General Public License: Objavljeno pod licenco GNU General Public: Question @@ -660,12 +668,16 @@ Remove folder Odstrani v mapo Remove folder pair Odstrani par imenikov +Remove local filter settings +Odstrani nastavitve lokalnega filtra Report translation error PoroÄaj o napaki prevoda Reset Ponastavi Right Desno +Run minimized and write status information to a logfile +Poženi minimizirano in zapisuj statusne informacije v dnevniÅ¡ko datoteko S&ave configuration Shr&ani konfiguracijo S&witch view @@ -680,14 +692,14 @@ Scanning: Pregledujem: Select a folder Izberite mapo -Select alternate filter settings -Izberite nadomestne nastavitve filtra Select alternate synchronization settings Izberite nadomestne nastavitve sinhronizacije Select logfile directory: Izberite imenik datoteke za beleženje: Select variant: Izberite varianto: +Setting default synchronization directions. Please check whether they are appropriate for you. +Nastavljam privzete sinhronizacijske smeri. Prosim preverite ali vam ustrezajo. Show conflicts Prikaži spore Show file icons @@ -732,6 +744,8 @@ Size Velikost Source code written completely in C++ utilizing: Izvorna koda napisana celotno v C++ z uporabo: +Source directory does not exist anymore: +Izvorni imenik ne obstaja veÄ: Speed: Hitrost: Start @@ -772,8 +786,12 @@ Target directory already existing! Ciljni imenik že obstaja! Target file already existing! Ciljna datoteka že obstaja! +The database file is not yet existing, but will be created during synchronization: +Datoteka podatkovne baze Å¡e ne obstaja, ampak bo ustvarjena med sinhronizacijo: The file does not contain a valid configuration: Datoteka ne vsebuje veljavne konfiguracije: +The required database entry is not yet existing, but will be created during synchronization: +Zahteavan vnos v podatkovni bazi Å¡e en obstaja, ampak bo ustvarjen med sinhronizacijo: This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. Ta varianta oceni dve datoteki z enakim imenom kot enaki, ko imata enako velikost IN enak datum ter Äas zadnjega spreminjanja. Time @@ -798,8 +816,6 @@ Unable to create logfile! Ne morem ustvariti datoteko za beleženje! Unable to initialize Recycle Bin! Ne morem inicializirati KoÅ¡a! -Uncheck all -OdznaÄi vse Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization. Obstajajo nereÅ¡eni spori! \n\nLahko ignorirate spore in nadaljujete s sinhronizacijo. Update -> @@ -814,8 +830,6 @@ User-defined directory UporabniÅ¡ko-doloÄen imenik User-defined directory for deletion was not specified! UporabniÅ¡ko-doloÄen imenik za brisanje ni bil naveden! -Using default synchronization directions. Please recheck. -Uporabljam privzete sinhronizacijske smeri. Prosimo preverite ponovno. Variant RazliÄica Verifying file %x diff --git a/BUILD/Languages/spanish.lng b/BUILD/Languages/spanish.lng index ea202d8a..466161c8 100644 --- a/BUILD/Languages/spanish.lng +++ b/BUILD/Languages/spanish.lng @@ -148,8 +148,6 @@ <Selección múltiple> A newer version of FreeFileSync is available: -ATTENTION: Failed directory access can lead to file deletions! - Abort requested: Waiting for current operation to finish... Abortar pedido: Esperar a que la actual operación finalice... Aborted @@ -158,10 +156,14 @@ About Sobre Action Acción +Activate filter + Add folder Add folder pair Añadir un par de carpetas +All directories in sync! + An exception occured! ¡Ha ocurrido una excepción! As a result the files are separated into the following categories: @@ -198,10 +200,6 @@ Category Change direction -Check all -Verificar todo -Choose to hide filtered files/directories from list -Ocultar en la lista ficheros/directorios filtrados Comma separated list Lista de "items" separados por coma Commandline @@ -242,8 +240,6 @@ Configuration saved! ¡Configuración guardada! Configure filter Configurar filtro -Configure filter... -Configurar filtros... Configure your own synchronization rules. Configure sus propias reglas de sincronización. Confirm @@ -334,8 +330,6 @@ Directory Directory does not exist: El directorio no existe: -Do not display visual status information but write to a logfile instead - Do not show this dialog again Do nothing @@ -406,12 +400,12 @@ Error writing file: Error al escribir fichero: Error writing to synchronization database: -Source directory does not exist anymore: -El directorio origen no existe ya: Example Ejemplo Exclude Excluir +Exclude all rows + Exclude temporarily Excluir temporalmente Exclude via filter: @@ -422,6 +416,8 @@ Exit with RC < 0 Salir com RC < 0 External applications +Fatal Error + Feedback and suggestions are welcome at: Los comentarios y sugerencias será bienvenidos en: File %x has an invalid date! @@ -466,12 +462,14 @@ Files/folders that exist on right side only Ficheros/carpetas que existen sólo en el lado derecho Filter -Filter active: Press again to deactivate -Filtro activo: Clique aquà para desactivar Filter files Filtrar ficheros +Filter has been selected + Filter view Vista de filtros +Filtering is deactivated + Folder Comparison and Synchronization Carpeta de Comparación y Sincronización Free disk space available: @@ -494,6 +492,8 @@ Generating database... Generating file list... Generando lista de ficheros... +Global filter + Global settings Opciones globales Help @@ -504,6 +504,8 @@ Hide all error and warning messages Ocultar todos los mensajes de error y aviso Hide conflicts +Hide excluded items + Hide files that are different Ocultar ficheros diferentes Hide files that are equal @@ -530,14 +532,16 @@ Hide files that will be overwritten on right side Hide files that won't be copied -Hide filtered items -Ocultar items filtrados +Hide filtered or temporarily excluded files + Hide further error messages during the current process Ocultar próximos mensajes de error durante este processo Hints: Consejos: Homepage Homepage +Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically. + If you like FFS Si te gusta FFS Ignore 1-hour file time difference @@ -552,6 +556,8 @@ Ignore this error, retry or abort? ¿Ignorar este error, reintentar o abortar? Include Incluir +Include all rows + Include temporarily Incluir temporalmente Include: *.doc;*.zip;*.exe\nExclude: temp\\* @@ -562,7 +568,7 @@ Info Info Information Información -Initial synchronization. Please verify default copy-directions! +Initial synchronization: Integrate external applications into context menu. The following macros are available: @@ -578,6 +584,8 @@ Load configuration from file Cargar configuración desde fichero Load configuration history (press DEL to delete items) Cargar histórico de configuración (presionar DEL para borrar elementos) +Local filter + Log-messages: Log de mensajes: Logging @@ -602,7 +610,7 @@ Moving folder %x to user-defined directory %y Multiple... -No database file existing yet: +No filter selected Not enough free disk space available in: @@ -638,8 +646,8 @@ Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) i Please fill all empty directory fields. Por favor, rellene todos los campos del directorio vacÃos. -Press button to activate filter -Presione el botón para activar el filtro +Please run a Compare first before synchronizing! + Published under the GNU General Public License: Publicado bajo "GNU General Public License": Question @@ -660,12 +668,16 @@ Remove folder Remove folder pair Eliminar par de carpetas +Remove local filter settings + Report translation error Reset Reiniciar Right +Run minimized and write status information to a logfile + S&ave configuration G&uardar configuración S&witch view @@ -680,14 +692,14 @@ Scanning: Analizar: Select a folder Seleccione una carpeta -Select alternate filter settings - Select alternate synchronization settings Select logfile directory: Select variant: Sleccione una variante: +Setting default synchronization directions. Please check whether they are appropriate for you. + Show conflicts Show file icons @@ -732,6 +744,8 @@ Size Tamaño Source code written completely in C++ utilizing: Código fuente escrito en C++ utilizando: +Source directory does not exist anymore: +El directorio origen no existe ya: Speed: Start @@ -772,8 +786,12 @@ Target directory already existing! Target file already existing! ¡El fichero objetivo existe ya! +The database file is not yet existing, but will be created during synchronization: + The file does not contain a valid configuration: El fichero no contiene una configuración válida: +The required database entry is not yet existing, but will be created during synchronization: + This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. Esta variante evalúa dos ficheros con el mismo nombre como iguales cuando tienen el mismo tamaño Y la misma fecha de modificación. Time @@ -798,8 +816,6 @@ Unable to create logfile! Permitir crear logfile Unable to initialize Recycle Bin! Permitir iniciar la Papelera -Uncheck all -Deseleccionar todos Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization. Update -> @@ -814,8 +830,6 @@ User-defined directory User-defined directory for deletion was not specified! -Using default synchronization directions. Please recheck. - Variant Verifying file %x diff --git a/BUILD/Languages/turkish.lng b/BUILD/Languages/turkish.lng index a171483a..8b548066 100644 --- a/BUILD/Languages/turkish.lng +++ b/BUILD/Languages/turkish.lng @@ -156,10 +156,14 @@ About Hakkında Action Ä°ÅŸlem +Activate filter + Add folder Klasör ekle Add folder pair Klasör çifti ekle +All directories in sync! + An exception occured! OlaÄŸan dışı bir durum oluÅŸtu! As a result the files are separated into the following categories: @@ -196,10 +200,6 @@ Category Kategori Change direction Yönü deÄŸiÅŸtir -Check all -Tümünü iÅŸaretle -Choose to hide filtered files/directories from list -Listedeki filtrelenmiÅŸ dosyaları/dizinleri gizlemek seçiniz Comma separated list Virgül ile ayrılmış liste Commandline @@ -240,8 +240,6 @@ Configuration saved! Konfigürasyon kaydedildi! Configure filter Filtrelemeyi ayarla -Configure filter... -Filtrelemeyi ayarla... Configure your own synchronization rules. Kendi senkronizasyon kurallarınızı ayarlayın. Confirm @@ -332,8 +330,6 @@ Directory Dizin Directory does not exist: Dizin mevcut deÄŸil: -Do not display visual status information but write to a logfile instead -Görsel durum bilgisini ekrana getirme, fakat bir kayıt dosyasına yaz Do not show this dialog again Bu iletiyi tekrar gösterme Do nothing @@ -408,6 +404,8 @@ Example Örnek Exclude Dışarda bırak +Exclude all rows + Exclude temporarily Geçici olarak dışarda bırak Exclude via filter: @@ -418,6 +416,8 @@ Exit with RC < 0 RC < 0 ile çık External applications Harici uygulamalar +Fatal Error + Feedback and suggestions are welcome at: Geri bildirim ve öneriler için: File %x has an invalid date! @@ -462,12 +462,14 @@ Files/folders that exist on right side only Sadece saÄŸ tarafta mevcut olan dosyalar/klasörler Filter Filtre -Filter active: Press again to deactivate -Filtre etkin: EtkinliÄŸini kaldırmak için tekrar basın Filter files Fltre dosyaları +Filter has been selected + Filter view Filtre görünümü +Filtering is deactivated + Folder Comparison and Synchronization Klasör KarşılaÅŸtırması ve Senkronizasyonu Free disk space available: @@ -490,6 +492,8 @@ Generating database... Veri tabaný yaratýlýyor... Generating file list... Dosya listesi oluÅŸturuluyor... +Global filter + Global settings Genel ayarlar Help @@ -500,6 +504,8 @@ Hide all error and warning messages Hata ve uyarı mesajlarını gösterme Hide conflicts Tutarsızlıkları gösterme +Hide excluded items + Hide files that are different Farklı olan dosyaları gösterme Hide files that are equal @@ -526,14 +532,16 @@ Hide files that will be overwritten on right side SaÄŸ tarafta üzerine yazılacak dosyaları gösterme Hide files that won't be copied Kopyalanmayacak dosyaları gösterme -Hide filtered items -FiltrelenmiÅŸ olanları gösterme +Hide filtered or temporarily excluded files + Hide further error messages during the current process Devam eden iÅŸlem süresince daha fazla hata mesajı gösterme Hints: Ä°puçları: Homepage Ana sayfa +Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically. + If you like FFS EÄŸer FFS’i sevdiyseniz Ignore 1-hour file time difference @@ -548,6 +556,8 @@ Ignore this error, retry or abort? Bu hatayı yoksay, yeniden dene veya vazgeç? Include Dahil et +Include all rows + Include temporarily Geçici olarak dahil et Include: *.doc;*.zip;*.exe\nExclude: temp\\* @@ -558,8 +568,8 @@ Info Bilgi Information Bilgi -Initial synchronization. -Baþlangýç senkronizasyonu. +Initial synchronization: +Baþlangýç senkronizasyonu: Integrate external applications into context menu. The following macros are available: Harici uygulamaları içerik menüsüne ekle. Åžu makro’lar temin edilebilir: It was not possible to initialize the Recycle Bin!\n\nIt's likely that you are not using Windows.\nIf you want this feature included, please contact the author. :) @@ -574,6 +584,8 @@ Load configuration from file Dosyadan konfigürasyonu yükle Load configuration history (press DEL to delete items) Konfigürasyon geçmiÅŸini yükle (Öğeleri silmek için DEL’e basın) +Local filter + Log-messages: Kayıt mesajları: Logging @@ -598,8 +610,8 @@ Moving folder %x to user-defined directory %y %x klasörü kullanıcı tanımlı dizin %y’e taşınıyor Multiple... Çoklu... -No database file existing yet: -Henüz mevcut bir veritabaný yok: +No filter selected + Not enough free disk space available in: Yeterli disk alanı yok : Nothing to synchronize according to configuration! @@ -634,8 +646,8 @@ Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) i Bu özelliÄŸi etkinleÅŸtirmek için FreeFileSync’in kurulum dizinine \"Shadow.dll\" (\"Shadow.zip\" sıkıştırılmış dosyasındaki uygun olanı) kopyalayın. Please fill all empty directory fields. Lütfen boÅŸ dizin alanlarını doldurunuz. -Press button to activate filter -Filtrelemeyi etkinleÅŸtirmek için tuÅŸa basın +Please run a Compare first before synchronizing! + Published under the GNU General Public License: “GNU General Public Licenseâ€a uygun olarak yayımlanmıştır: Question @@ -656,12 +668,16 @@ Remove folder Klasörü kaldır Remove folder pair Klasör çiftini kaldır +Remove local filter settings + Report translation error Çeviri hatasını bildir Reset Sıfırla Right SaÄŸ +Run minimized and write status information to a logfile + S&ave configuration Konfigürasyonu &kaydet S&witch view @@ -676,14 +692,14 @@ Scanning: Taranıyor: Select a folder Bir klasör seç -Select alternate filter settings -Alternatif filtreleme ayarı seç Select alternate synchronization settings Alternatif senkronizasyon ayarı seç Select logfile directory: Kayıt dosyası dizinini seç: Select variant: DeÄŸiÅŸkeni seç: +Setting default synchronization directions. Please check whether they are appropriate for you. + Show conflicts Tutarsızlıkları göster Show file icons @@ -770,8 +786,12 @@ Target directory already existing! Hedef dizin zaten mevcut! Target file already existing! Hedef dosya zaten mevcut! +The database file is not yet existing, but will be created during synchronization: + The file does not contain a valid configuration: Dosya geçerli bir konfigürasyon içermiyor: +The required database entry is not yet existing, but will be created during synchronization: + This variant evaluates two equally named files as being equal when they have the same file size AND the same last write date and time. Bu deÄŸiÅŸken, aynı isimli iki dosyanın, aynı ebata ve aynı son deÄŸiÅŸikik tarihine sahip olması durumunda eÅŸit olması anlamına gelir. Time @@ -796,8 +816,6 @@ Unable to create logfile! Kayıt dosyası yaratılamıyor! Unable to initialize Recycle Bin! Geri dönüşüm kutusu baÅŸlatılamıyor! -Uncheck all -Tüm iÅŸaretlemeleri kaldır Unresolved conflicts existing! \n\nYou can ignore conflicts and continue synchronization. Çözülemeyen tutarsızlık mevcut! \n\nTutarsızlıkları yoksayıp senkronizasyona devam edebilirsiniz. Update -> @@ -812,8 +830,6 @@ User-defined directory Kullanıcı tanımlı dizin User-defined directory for deletion was not specified! Silme için kulllanıcı tanımlı dizin belirtilmemiÅŸ! -Using default synchronization directions. Please recheck. -Ön tanýmlý senkronizasyon yönlerini kullanarak. Lütfen yeniden kontrol edin. Variant DeÄŸiÅŸken Verifying file %x diff --git a/BUILD/License.txt b/BUILD/License.txt index 94a9ed02..94a04532 100644 --- a/BUILD/License.txt +++ b/BUILD/License.txt @@ -619,56 +619,3 @@ Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - <program> Copyright (C) <year> <name of author> - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -<http://www.gnu.org/licenses/>. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/BUILD/Readme.txt b/BUILD/Readme.txt deleted file mode 100644 index 0f2ae840..00000000 --- a/BUILD/Readme.txt +++ /dev/null @@ -1,197 +0,0 @@ -FreeFileSync v3.1 ------------------ - ---------- -| Usage | ---------- - -1. Choose left and right directories and "Compare" them. -2. Select synchronization settings and press "Synchronize..." to begin synchronization. - - ----------------- -| Key Features | ----------------- - -1. Compare files (bytewise or by date) and synchronize them. -2. No limitations: An arbitrary number of files can be synchronized. -3. Unicode support. -4. Network support. -5. Synchronization database for automated setting of sync-directions and conflict detection -6. Support for multiple folder pairs with distinct configuration -7. Full support for Windows/Linux Symbolic Links and Windows Junction Points. -8. Lean & easily accessible UI: Highly optimized for speed and huge sets of data. -9. Algorithms coded in C++ completely. -10. Subfolders are also synchronized, including empty folders. -12. Progress indicators are updated only every 100ms for optimal performance! -12. Create Batch Jobs for automated synchronization with or without GUI. -13. Focus on usability: - - Only necessary functionality on UI: no overloaded menus or icon jungle. - - Select folders via drag & drop. - - Last configuration and screen settings are saved automatically. - - Maintain and load different configurations by drag&drop, load-button or during startup. - - Double-click to show file in explorer. (Windows only) - - Copy & paste support to export file-lists. - - Delete superfluous/temporary files directly on main grid. - - Right-click context menu. - - Status information and error reporting - - Sort file-lists by name, size or date. - - Display statistical data: total filesizes, amount of bytes that will be transfered with the current settings. -14. Support for filesizes larger than 4 GB. -15. Option to move files to Recycle Bin instead of deleting/overwriting them. -16. Automatically ignore directories "\RECYCLER" and "\System Volume Information" with default Filter. (Windows only) -17. Localized versions for many languages are available. -18. Delete before copy: Avoid disc space shortages with large sync-operations. -19. Based on wxWidgets framework => Portable to many operating systems. -20. Filter functionality to include/exclude files from synchronization (without re-compare!). -21. Include/exclude specific files from synchronization manually. -22. Create sync jobs via GUI to synchronize automatically (can be scheduled or executed directly). -23. Handle daylight saving time changes on FAT/FAT32 volumes correctly. -24. Portable version (.zip) available. -25. No Windows registry entries for portable version. -26. Support for \\?\ path prefix for unrestricted path length. (Windows only) -27. Check for updates from within FreeFileSync automatically. -28. Copy locked files using Windows Volume Shadow Copy. (Windows only) -29. Load file icons asynchronously for maximum display performance. -30. Create regular backups with macros %time%, %date% within directory names -31. Copy file and folder create/access/modification times when synchronizing - - - -------------------- -| Advanced topics | -------------------- - -1.) Synchronize in Batch Mode and send error notification via email: - -- Create a FreeFileSync batch file using "silent mode". -- Set error handling to "Exit with Returncode < 0" or "ignore errors" to avoid having a popup stop the program flow. - In case errors occur FreeFileSync will abort with a returncode < 0 which can be checked via the ERRORLEVEL command. -- Create a *.cmd or *.bat file and specify the location of FreeFileSync.exe and pass the name of the FreeFileSync batch file as first argument; e.g.: - - C:\Program Files\FreeFileSync\FreeFileSync.exe C:\SyncJob.ffs_batch - IF NOT ERRORLEVEL 0 echo An error occurred! && pause - -- Instead of displaying "An error occurred!" you can specify any other command like sending an email notification (using a third party tool). - - ------------------------------------------------------------------------------------- -2.) Schedule Batch Job in Windows Task Planner - -- Create a FreeFileSync batch file. (E.g. C:\SyncJob.ffs_batch) -- Create a new task in Windows Task planner for FreeFileSync.exe. -- Modify the task and adapt the execute-command specifying the path to the batch file; e.g.: - - C:\Program Files\FreeFileSync\FreeFileSync.exe C:\SyncJob.ffs_batch - - ------------------------------------------------------------------------------------- -3.) Drag & drop support - -FreeFileSync has a big focus on usability. Therefore drag & drop is supported in various situations: - -You can: - drag & drop any directory onto the main window to set the directory for comparison - - drag & drop any file onto the main window to set the directory for comparison - - drag & drop *.ffs_gui files onto the main window to load the configuration contained - - drag & drop *.ffs_batch files onto the main window to display and edit the batch configuration - - drag & drop *.ffs_batch files onto the batch dialog to display and edit the batch configuration - - ------------------------------------------------------------------------------------- -4.) Exclude all subfolders from synchronization - -If you want to synchronize all files from the base synchronization directories only, simply set up a filter like this: - - Include: * - Exclude: *\ - -This will exclude all objects within the two directories that end with a "\" character, which is interpreted as the end of a directory name, - - ------------------------------------------------------------------------------------- -5.) Synchronize with FTP - -FreeFileSync does not support FTP directly. But the FTP functionality can be easily activated by mapping the FTP webspace to a drive letter: - -Example: Use the free utility NetDrive (http://www.netdrive.net/) -- Add a "New Site" and specify site name, site URL, drive letter, account and password. -- Use the newly created drive as if it were a regular hard disk. -- Note: Most FTP drives set a file's timestamp to current time when synchronizing. As a workaround you can try a "compare by filesize", see below. - - ------------------------------------------------------------------------------------- -6.) Start external application on double-click - -FreeFileSync's default is to show files in the operating system's standard file browser on each double-click e.g. by invoking "explorer /select, %name" on Windows. -If some other application shall be started instead, just navigate to "Menu -> Advanced -> Global settings: External Applications" and replace the command string: - -Examples: - Start associated application: cmd /c start "" "%name" - - Start visual difference tool: C:\Program Files\WinMerge\WinMergeU.exe "%name" "%nameCo" -(Don't forget to use quotation marks if file names contain spaces!) - - ------------------------------------------------------------------------------------- -7. Synchronize USB sticks with variable drive letter - -USB sticks often have different volume names assigned to them when plugged into two distinct computers. In order to handle this flexibility FreeFileSync is able to -process directory names relative to the current working directory. Thus the following workflow is possible: - - - Replace the absolute USB directory name (variable) in your configuration by a relative one: E.g. "E:\SyncDir" -> "\SyncDir" - - Save and copy synchronization settings to the USB stick: "E:\settings.ffs_gui" - - Start FreeFileSync by double-clicking on "E:\settings.ffs_gui" - -=> Working directory automatically is set to "E:\" by the operating system so that "\SyncDir" is interpreted as "E:\SyncDir". Now start synchronization as usual. - - ------------------------------------------------------------------------------------- -8. Start RealtimeSync via commandline - -RealtimeSync can be used to load a configuration file and start processing immediately without additional user intervention. Just pass the name of a configuration file as -first commandline argument. - -Example: C:\Program Files\FreeFileSync\RealtimeSync.exe MyConfig.ffs_real - - ------------------------------------------------------------------------------------- -9. Compare by filesize - -Sometimes you might want to compare both sides by filesize only, ignoring the last modification timestamp. Here is how you can do this: Open your *.ffs_gui configuration file -and change the XML node <FileTimeTolerance> to some sufficiently large value. Now changed files will be detected as a conflict (same date, different filesize) and a default -synchronization direction for conflics can be used. - - ------------------------------------------------------------------------------------- -10. Create regular backups with time-stamped directory names - -You can use macros %time%, %date% within the directory names you want to synchronize: Assuming you have a directory "C:\Source" which you want to backup each day into a time-stamped target -directory like "C:\Target_2009-10-08", all that needs to be done is setting up base directories like this: - -Source folder: "C:\Source" -Target folder: "C:\Target_%date%" - -Latter will be interactively replaced with the current date. In order to further automate this process, you can create a *.ffs_batch file with this configuration and choose -"ignore errors" to avoid the warning that target directory is not (yet) existing. - - - ---------- -| Links | ---------- - -FreeFileSync on SourceForge: -http://sourceforge.net/projects/freefilesync/ - - ------------- -| Contact | ------------- - -For feedback, suggestions or bug-reports you can write an email to: -zhnmju123 [at] gmx [dot] de - -or report directly to: -http://sourceforge.net/projects/freefilesync/ - - -Have fun! --ZenJu diff --git a/BUILD/Resources.dat b/BUILD/Resources.dat Binary files differindex 1273a576..481a9f0f 100644 --- a/BUILD/Resources.dat +++ b/BUILD/Resources.dat diff --git a/BUILD/Shadow.zip b/BUILD/Shadow.zip Binary files differdeleted file mode 100644 index 24716c68..00000000 --- a/BUILD/Shadow.zip +++ /dev/null diff --git a/BUILD/Sync_Complete.wav b/BUILD/Sync_Complete.wav Binary files differnew file mode 100644 index 00000000..a6a9cc84 --- /dev/null +++ b/BUILD/Sync_Complete.wav diff --git a/BUILD/mingwm10.dll b/BUILD/mingwm10.dll Binary files differindex cf2113a1..9e609264 100644 --- a/BUILD/mingwm10.dll +++ b/BUILD/mingwm10.dll diff --git a/Cleanup.cmd b/Cleanup.cmd index 857e3e2d..298a8ed7 100644 --- a/Cleanup.cmd +++ b/Cleanup.cmd @@ -26,7 +26,8 @@ del BUILD\RealtimeSync.ilk del library\ShadowCopy\ShadowCopy.ncb attrib library\ShadowCopy\ShadowCopy.suo -h del library\ShadowCopy\ShadowCopy.suo -del library\ShadowCopy\ShadowDll.vcproj.*.user +del library\ShadowCopy\Shadow_2003.vcproj.*.user +del library\ShadowCopy\Shadow_XP.vcproj.*.user del library\ShadowCopy\ShadowTest.vcproj.*.user del library\ShadowCopy\Shadow.pdb del library\ShadowCopy\Shadow.ilk diff --git a/FreeFileSync.cbp b/FreeFileSync.cbp index f2201749..cad9426e 100644 --- a/FreeFileSync.cbp +++ b/FreeFileSync.cbp @@ -100,7 +100,7 @@ <Add option="-DZSTRING_WIDE_CHAR" /> <Add directory="C:\Programme\C++\wxWidgets\include" /> <Add directory="C:\Programme\C++\wxWidgets\contrib\include" /> - <Add directory="shared\boost_1_40_0" /> + <Add directory="shared\boost_1_x" /> <Add directory="shared" /> </Compiler> <ResourceCompiler> @@ -117,6 +117,7 @@ <Add library="libgdi32.a" /> <Add library="libcomdlg32.a" /> <Add library="libws2_32.a" /> + <Add library="libwinmm.a" /> <Add directory="C:\Programme\C++\wxWidgets\lib\gcc_lib" /> </Linker> <Unit filename="WxWizFrame.fbp"> @@ -245,6 +246,8 @@ <Option target="Debug" /> <Option target="Release" /> </Unit> + <Unit filename="shared\customComboBox.cpp" /> + <Unit filename="shared\customComboBox.h" /> <Unit filename="shared\customTooltip.cpp"> <Option target="Debug" /> <Option target="Release" /> @@ -253,6 +256,8 @@ <Option target="Debug" /> <Option target="Release" /> </Unit> + <Unit filename="shared\dllLoader.cpp" /> + <Unit filename="shared\dllLoader.h" /> <Unit filename="shared\dragAndDrop.cpp"> <Option target="Debug" /> <Option target="Release" /> @@ -272,6 +277,8 @@ <Unit filename="shared\guid.h" /> <Unit filename="shared\localization.cpp" /> <Unit filename="shared\localization.h" /> + <Unit filename="shared\serialize.cpp" /> + <Unit filename="shared\serialize.h" /> <Unit filename="shared\shadow.cpp" /> <Unit filename="shared\shadow.h" /> <Unit filename="shared\standardPaths.cpp" /> diff --git a/FreeFileSync.vcproj b/FreeFileSync.vcproj index 0ba7315c..6bf06d87 100644 --- a/FreeFileSync.vcproj +++ b/FreeFileSync.vcproj @@ -12,14 +12,17 @@ <Platform Name="Win32" /> + <Platform + Name="x64" + /> </Platforms> <ToolFiles> </ToolFiles> <Configurations> <Configuration Name="Debug|Win32" - OutputDirectory="OBJ\$(ConfigurationName)_FFS_VCPP" - IntermediateDirectory="OBJ\$(ConfigurationName)_FFS_VCPP" + OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)_VCPP" + IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)_VCPP" ConfigurationType="1" CharacterSet="1" > @@ -42,7 +45,7 @@ <Tool Name="VCCLCompilerTool" Optimization="0" - AdditionalIncludeDirectories=""C:\Programme\C++\wxWidgets\include";"C:\Programme\C++\wxWidgets\lib\vc_lib\mswud";.\shared\boost_1_40_0" + AdditionalIncludeDirectories=""C:\Programme\C++\wxWidgets\include";"C:\Programme\C++\wxWidgets\lib\vc_lib\mswud";.\shared\boost_1_x" PreprocessorDefinitions="wxUSE_UNICODE;__WXMSW__;FFS_WIN;__WXDEBUG__;TIXML_USE_STL;ZSTRING_WIDE_CHAR" MinimalRebuild="true" BasicRuntimeChecks="3" @@ -66,7 +69,7 @@ /> <Tool Name="VCLinkerTool" - AdditionalDependencies="wxmsw28ud_adv.lib 
wxmsw28ud_core.lib 
wxbase28ud.lib 
wxpngd.lib
 wxzlibd.lib 
wxbase28ud_net.lib comctl32.lib ws2_32.lib Rpcrt4.lib" + AdditionalDependencies="wxmsw28ud_adv.lib 
wxmsw28ud_core.lib 
wxbase28ud.lib 
wxpngd.lib
 wxzlibd.lib 
wxbase28ud_net.lib comctl32.lib ws2_32.lib Rpcrt4.lib winmm.lib" OutputFile="BUILD\$(ProjectName).exe" LinkIncremental="2" AdditionalLibraryDirectories="C:\Programme\C++\wxWidgets\lib\vc_lib" @@ -101,9 +104,94 @@ /> </Configuration> <Configuration + Name="Debug|x64" + OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)_VCPP" + IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)_VCPP" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + CommandLine="" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories=""D:\Programme\C++\wxWidgets-x64\include";"D:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswud";.\shared\boost_1_x" + PreprocessorDefinitions="wxUSE_UNICODE;__WXMSW__;FFS_WIN;__WXDEBUG__;TIXML_USE_STL;ZSTRING_WIDE_CHAR" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="4" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + DisableSpecificWarnings="4804;4100" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + Culture="0" + AdditionalIncludeDirectories="D:\Programme\C++\wxWidgets-x64\include;D:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswud" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="wxmsw28ud_adv.lib 
wxmsw28ud_core.lib 
wxbase28ud.lib 
wxpngd.lib
 wxzlibd.lib 
wxbase28ud_net.lib comctl32.lib ws2_32.lib Rpcrt4.lib winmm.lib" + OutputFile="BUILD\$(ProjectName).exe" + LinkIncremental="2" + AdditionalLibraryDirectories="D:\Programme\C++\wxWidgets-x64\lib\vc_lib" + GenerateManifest="true" + GenerateDebugInformation="true" + SubSystem="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + EmbedManifest="true" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + Description="clean up" + CommandLine="" + /> + </Configuration> + <Configuration Name="Release|Win32" - OutputDirectory="OBJ\$(ConfigurationName)_FFS_VCPP" - IntermediateDirectory="OBJ\$(ConfigurationName)_FFS_VCPP" + OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)_VCPP" + IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)_VCPP" ConfigurationType="1" CharacterSet="1" WholeProgramOptimization="1" @@ -128,7 +216,7 @@ Optimization="2" EnableIntrinsicFunctions="true" FavorSizeOrSpeed="1" - AdditionalIncludeDirectories=""C:\Programme\C++\wxWidgets\include";"C:\Programme\C++\wxWidgets\lib\vc_lib\mswu";.\shared\boost_1_40_0" + AdditionalIncludeDirectories=""C:\Programme\C++\wxWidgets\include";"C:\Programme\C++\wxWidgets\lib\vc_lib\mswu";.\shared\boost_1_x" PreprocessorDefinitions="wxUSE_UNICODE;__WXMSW__;FFS_WIN;NDEBUG;TIXML_USE_STL;ZSTRING_WIDE_CHAR" RuntimeLibrary="0" EnableFunctionLevelLinking="true" @@ -150,7 +238,7 @@ /> <Tool Name="VCLinkerTool" - AdditionalDependencies="wxmsw28u_adv.lib 
wxmsw28u_core.lib 
wxbase28u.lib 
wxpng.lib 
wxzlib.lib 
wxbase28u_net.lib comctl32.lib ws2_32.lib" + AdditionalDependencies="wxmsw28u_adv.lib 
wxmsw28u_core.lib 
wxbase28u.lib 
wxpng.lib 
wxzlib.lib 
wxbase28u_net.lib comctl32.lib ws2_32.lib winmm.lib" OutputFile="BUILD\$(ProjectName).exe" LinkIncremental="1" AdditionalLibraryDirectories="C:\Programme\C++\wxWidgets\lib\vc_lib" @@ -183,6 +271,90 @@ CommandLine="" /> </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)_VCPP" + IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)_VCPP" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories=""D:\Programme\C++\wxWidgets-x64\include";"D:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswu";.\shared\boost_1_x" + PreprocessorDefinitions="wxUSE_UNICODE;__WXMSW__;FFS_WIN;NDEBUG;TIXML_USE_STL;ZSTRING_WIDE_CHAR" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="3" + DisableSpecificWarnings="4804;4100" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + Culture="1033" + AdditionalIncludeDirectories=""D:\Programme\C++\wxWidgets-x64\include";"D:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswu"" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="wxmsw28u_adv.lib 
wxmsw28u_core.lib 
wxbase28u.lib 
wxpng.lib 
wxzlib.lib 
wxbase28u_net.lib comctl32.lib ws2_32.lib winmm.lib" + OutputFile="BUILD\$(ProjectName).exe" + LinkIncremental="1" + AdditionalLibraryDirectories="D:\Programme\C++\wxWidgets-x64\lib\vc_lib" + GenerateDebugInformation="false" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="" + /> + </Configuration> </Configurations> <References> </References> @@ -221,6 +393,10 @@ > </File> <File + RelativePath=".\shared\customComboBox.cpp" + > + </File> + <File RelativePath=".\library\customGrid.cpp" > </File> @@ -229,6 +405,10 @@ > </File> <File + RelativePath=".\shared\dllLoader.cpp" + > + </File> + <File RelativePath=".\shared\dragAndDrop.cpp" > </File> @@ -293,6 +473,10 @@ > </File> <File + RelativePath=".\shared\serialize.cpp" + > + </File> + <File RelativePath=".\ui\settingsDialog.cpp" > </File> @@ -312,6 +496,14 @@ /> </FileConfiguration> <FileConfiguration + Name="Debug|x64" + > + <Tool + Name="VCCLCompilerTool" + DisableSpecificWarnings="4706" + /> + </FileConfiguration> + <FileConfiguration Name="Release|Win32" > <Tool @@ -319,6 +511,14 @@ DisableSpecificWarnings="4706" /> </FileConfiguration> + <FileConfiguration + Name="Release|x64" + > + <Tool + Name="VCCLCompilerTool" + DisableSpecificWarnings="4706" + /> + </FileConfiguration> </File> <File RelativePath=".\shared\standardPaths.cpp" @@ -400,6 +600,16 @@ /> </FileConfiguration> <FileConfiguration + Name="Debug|x64" + > + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_UNICODE;UNICODE;wxUSE_NO_MANIFEST" + Culture="1033" + ResourceOutputFileName="$(IntDir)/Resource.res" + /> + </FileConfiguration> + <FileConfiguration Name="Release|Win32" > <Tool @@ -408,6 +618,15 @@ ResourceOutputFileName="$(IntDir)/Resource.res" /> </FileConfiguration> + <FileConfiguration + Name="Release|x64" + > + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_UNICODE;UNICODE;wxUSE_NO_MANIFEST" + ResourceOutputFileName="$(IntDir)/Resource.res" + /> + </FileConfiguration> </File> </Filter> </Files> @@ -1,4 +1,4 @@ -CPPFLAGS=-Wall -pipe -DNDEBUG -DwxUSE_UNICODE `wx-config --cxxflags --debug=no --unicode=yes` `pkg-config --cflags gtk+-2.0` -DFFS_LINUX -DTIXML_USE_STL -DZSTRING_CHAR -O3 -pthread -c -Ishared/boost_1_40_0 +CPPFLAGS=-Wall -pipe -DNDEBUG -DwxUSE_UNICODE `wx-config --cxxflags --debug=no --unicode=yes` `pkg-config --cflags gtk+-2.0` -DFFS_LINUX -DTIXML_USE_STL -DZSTRING_CHAR -O3 -pthread -c -Ishared/boost_1_x LINKFLAGS=`wx-config --libs --debug=no --unicode=yes` shared/ossp_uuid/.libs/libuuid++.a -O3 -pthread FILE_LIST= #internal list of all *.cpp files needed for compilation @@ -43,6 +43,8 @@ FILE_LIST+=shared/xmlBase.cpp FILE_LIST+=shared/appMain.cpp FILE_LIST+=shared/customButton.cpp FILE_LIST+=shared/toggleButton.cpp +FILE_LIST+=shared/customComboBox.cpp +FILE_LIST+=shared/serialize.cpp #list of all *.o files OBJECT_LIST=$(foreach file, $(FILE_LIST), OBJ/$(subst .cpp,.o,$(notdir $(file)))) diff --git a/RealtimeSync/RealtimeSync.cbp b/RealtimeSync/RealtimeSync.cbp index 47afabf3..d15a5ab2 100644 --- a/RealtimeSync/RealtimeSync.cbp +++ b/RealtimeSync/RealtimeSync.cbp @@ -72,7 +72,7 @@ <Add option="-DTIXML_USE_STL" /> <Add directory="C:\Programme\C++\wxWidgets\include" /> <Add directory="C:\Programme\C++\wxWidgets\contrib\include" /> - <Add directory="..\shared\boost_1_40_0" /> + <Add directory="..\shared\boost_1_x" /> </Compiler> <ResourceCompiler> <Add directory="C:\Programme\C++\wxWidgets\include" /> @@ -123,6 +123,8 @@ <Unit filename="..\Shared\zstring.cpp" /> <Unit filename="..\Shared\zstring.h" /> <Unit filename="..\library\processXml.cpp" /> + <Unit filename="..\shared\dllLoader.cpp" /> + <Unit filename="..\shared\dllLoader.h" /> <Unit filename="..\shared\fileError.h" /> <Unit filename="..\shared\fileHandling.cpp" /> <Unit filename="..\shared\fileHandling.h" /> diff --git a/RealtimeSync/RealtimeSync.vcproj b/RealtimeSync/RealtimeSync.vcproj index 7aebda01..f3501a17 100644 --- a/RealtimeSync/RealtimeSync.vcproj +++ b/RealtimeSync/RealtimeSync.vcproj @@ -12,14 +12,17 @@ <Platform Name="Win32" /> + <Platform + Name="x64" + /> </Platforms> <ToolFiles> </ToolFiles> <Configurations> <Configuration Name="Debug|Win32" - OutputDirectory="..\OBJ\$(ConfigurationName)_RTS_VCPP" - IntermediateDirectory="..\OBJ\$(ConfigurationName)_RTS_VCPP" + OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)_VCPP" + IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)_VCPP" ConfigurationType="1" CharacterSet="1" > @@ -42,7 +45,7 @@ <Tool Name="VCCLCompilerTool" Optimization="0" - AdditionalIncludeDirectories=""C:\Programme\C++\wxWidgets\include";"C:\Programme\C++\wxWidgets\lib\vc_lib\mswud";..\shared\boost_1_40_0" + AdditionalIncludeDirectories=""C:\Programme\C++\wxWidgets\include";"C:\Programme\C++\wxWidgets\lib\vc_lib\mswud";..\shared\boost_1_x" PreprocessorDefinitions="wxUSE_UNICODE;__WXMSW__;FFS_WIN;__WXDEBUG__;TIXML_USE_STL;ZSTRING_WIDE_CHAR" MinimalRebuild="true" BasicRuntimeChecks="3" @@ -100,9 +103,93 @@ /> </Configuration> <Configuration + Name="Debug|x64" + OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)_VCPP" + IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)_VCPP" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + CommandLine="" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories=""D:\Programme\C++\wxWidgets-x64\include";"D:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswud";..\shared\boost_1_x" + PreprocessorDefinitions="wxUSE_UNICODE;__WXMSW__;FFS_WIN;__WXDEBUG__;TIXML_USE_STL;ZSTRING_WIDE_CHAR" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + DisableSpecificWarnings="4804" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + Culture="0" + AdditionalIncludeDirectories="D:\Programme\C++\wxWidgets-x64\include;D:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswud" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="wxmsw28ud_adv.lib 
wxmsw28ud_core.lib 
wxbase28ud.lib 
wxpngd.lib
 wxzlibd.lib 
wxbase28ud_net.lib comctl32.lib ws2_32.lib Rpcrt4.lib" + OutputFile="..\BUILD\$(ProjectName).exe" + LinkIncremental="2" + AdditionalLibraryDirectories="D:\Programme\C++\wxWidgets-x64\lib\vc_lib" + GenerateManifest="true" + GenerateDebugInformation="true" + SubSystem="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + EmbedManifest="true" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + Description="clean up" + CommandLine="" + /> + </Configuration> + <Configuration Name="Release|Win32" - OutputDirectory="..\OBJ\$(ConfigurationName)_RTS_VCPP" - IntermediateDirectory="..\OBJ\$(ConfigurationName)_RTS_VCPP" + OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)_VCPP" + IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)_VCPP" ConfigurationType="1" CharacterSet="1" WholeProgramOptimization="1" @@ -127,7 +214,7 @@ Optimization="2" EnableIntrinsicFunctions="true" FavorSizeOrSpeed="1" - AdditionalIncludeDirectories=""C:\Programme\C++\wxWidgets\include";"C:\Programme\C++\wxWidgets\lib\vc_lib\mswu";..\shared\boost_1_40_0" + AdditionalIncludeDirectories=""C:\Programme\C++\wxWidgets\include";"C:\Programme\C++\wxWidgets\lib\vc_lib\mswu";..\shared\boost_1_x" PreprocessorDefinitions="wxUSE_UNICODE;__WXMSW__;FFS_WIN;NDEBUG;TIXML_USE_STL;ZSTRING_WIDE_CHAR" RuntimeLibrary="0" EnableFunctionLevelLinking="true" @@ -182,6 +269,90 @@ CommandLine="" /> </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)_VCPP" + IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)_VCPP" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + FavorSizeOrSpeed="1" + AdditionalIncludeDirectories=""D:\Programme\C++\wxWidgets-x64\include";"D:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswu";..\shared\boost_1_x" + PreprocessorDefinitions="wxUSE_UNICODE;__WXMSW__;FFS_WIN;NDEBUG;TIXML_USE_STL;ZSTRING_WIDE_CHAR" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + DisableSpecificWarnings="4804" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + Culture="1033" + AdditionalIncludeDirectories=""D:\Programme\C++\wxWidgets-x64\include";"D:\Programme\C++\wxWidgets-x64\lib\vc_lib\mswu"" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="wxmsw28u_adv.lib 
wxmsw28u_core.lib 
wxbase28u.lib 
wxpng.lib 
wxzlib.lib 
wxbase28u_net.lib comctl32.lib ws2_32.lib" + OutputFile="..\BUILD\$(ProjectName).exe" + LinkIncremental="1" + AdditionalLibraryDirectories="D:\Programme\C++\wxWidgets-x64\lib\vc_lib" + GenerateDebugInformation="false" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="" + /> + </Configuration> </Configurations> <References> </References> @@ -200,6 +371,10 @@ > </File> <File + RelativePath="..\shared\dllLoader.cpp" + > + </File> + <File RelativePath="..\shared\dragAndDrop.cpp" > </File> @@ -313,6 +488,14 @@ /> </FileConfiguration> <FileConfiguration + Name="Debug|x64" + > + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_UNICODE;UNICODE;wxUSE_NO_MANIFEST" + /> + </FileConfiguration> + <FileConfiguration Name="Release|Win32" > <Tool @@ -320,6 +503,14 @@ PreprocessorDefinitions="_UNICODE;UNICODE;wxUSE_NO_MANIFEST" /> </FileConfiguration> + <FileConfiguration + Name="Release|x64" + > + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_UNICODE;UNICODE;wxUSE_NO_MANIFEST" + /> + </FileConfiguration> </File> </Filter> </Files> diff --git a/RealtimeSync/application.cpp b/RealtimeSync/application.cpp index 827a54c6..b974fb89 100644 --- a/RealtimeSync/application.cpp +++ b/RealtimeSync/application.cpp @@ -43,6 +43,15 @@ void Application::OnStartApplication(wxIdleEvent& event) ::gtk_rc_parse("styles.rc"); //remove inner border from bitmap buttons #endif + //initialize help controller + helpController.reset(new wxHelpController); + helpController->Initialize(FreeFileSync::getInstallationDir() + +#ifdef FFS_WIN + wxT("FreeFileSync.chm")); +#elif defined FFS_LINUX + wxT("Help/FreeFileSync.hhp")); +#endif + //set program language FreeFileSync::CustomLocale::getInstance().setLanguage(RealtimeSync::getProgramLanguage()); @@ -67,7 +76,7 @@ void Application::OnStartApplication(wxIdleEvent& event) GlobalResources::getInstance().load(); //loads bitmap resources on program startup - MainDialog* frame = new MainDialog(NULL, cfgFilename); + MainDialog* frame = new MainDialog(NULL, cfgFilename, *helpController); frame->SetIcon(*GlobalResources::getInstance().programIcon); //set application icon frame->Show(); } diff --git a/RealtimeSync/application.h b/RealtimeSync/application.h index f6bfdd37..e7116156b 100644 --- a/RealtimeSync/application.h +++ b/RealtimeSync/application.h @@ -9,6 +9,8 @@ #define REALTIMESYNCAPP_H #include <wx/app.h> +#include <wx/help.h> +#include <memory> class Application : public wxApp { @@ -17,6 +19,8 @@ public: private: void OnStartApplication(wxIdleEvent& event); + + std::auto_ptr<wxHelpController> helpController; //global help controller }; #endif // REALTIMESYNCAPP_H diff --git a/RealtimeSync/functions.cpp b/RealtimeSync/functions.cpp index e5e3f5f5..93d075c0 100644 --- a/RealtimeSync/functions.cpp +++ b/RealtimeSync/functions.cpp @@ -1,7 +1,6 @@ #include "functions.h" #include <wx/textctrl.h> #include <wx/filepicker.h> -//#include "../shared/globalFunctions.h" #include "../shared/stringConv.h" #include "../shared/fileHandling.h" diff --git a/RealtimeSync/guiGenerated.cpp b/RealtimeSync/guiGenerated.cpp index 6954f01c..7e705927 100644 --- a/RealtimeSync/guiGenerated.cpp +++ b/RealtimeSync/guiGenerated.cpp @@ -34,7 +34,13 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr m_menubar1->Append( m_menuFile, _("&File") ); m_menuHelp = new wxMenu(); - m_menuItemAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( _("&About...") ) + wxT('\t') + wxT("F1"), wxEmptyString, wxITEM_NORMAL ); + wxMenuItem* m_menuItemContent; + m_menuItemContent = new wxMenuItem( m_menuHelp, wxID_ANY, wxString( _("&Content") ) + wxT('\t') + wxT("F1"), wxEmptyString, wxITEM_NORMAL ); + m_menuHelp->Append( m_menuItemContent ); + + m_menuHelp->AppendSeparator(); + + m_menuItemAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( _("&About...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuHelp->Append( m_menuItemAbout ); m_menubar1->Append( m_menuHelp, _("&Help") ); @@ -156,6 +162,7 @@ MainDlgGenerated::MainDlgGenerated( wxWindow* parent, wxWindowID id, const wxStr this->Connect( m_menuItem14->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnSaveConfig ) ); this->Connect( m_menuItem13->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnLoadConfig ) ); this->Connect( m_menuItem4->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnQuit ) ); + this->Connect( m_menuItemContent->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnShowHelp ) ); this->Connect( m_menuItemAbout->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnMenuAbout ) ); m_bpButtonAddFolder->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDlgGenerated::OnAddFolder ), NULL, this ); m_bpButtonRemoveTopFolder->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDlgGenerated::OnRemoveTopFolder ), NULL, this ); @@ -170,6 +177,7 @@ MainDlgGenerated::~MainDlgGenerated() this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnSaveConfig ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnLoadConfig ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnQuit ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnShowHelp ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDlgGenerated::OnMenuAbout ) ); m_bpButtonAddFolder->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDlgGenerated::OnAddFolder ), NULL, this ); m_bpButtonRemoveTopFolder->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDlgGenerated::OnRemoveTopFolder ), NULL, this ); diff --git a/RealtimeSync/guiGenerated.h b/RealtimeSync/guiGenerated.h index 17f28278..91669af8 100644 --- a/RealtimeSync/guiGenerated.h +++ b/RealtimeSync/guiGenerated.h @@ -70,6 +70,7 @@ class MainDlgGenerated : public wxFrame virtual void OnSaveConfig( wxCommandEvent& event ){ event.Skip(); } virtual void OnLoadConfig( wxCommandEvent& event ){ event.Skip(); } virtual void OnQuit( wxCommandEvent& event ){ event.Skip(); } + virtual void OnShowHelp( wxCommandEvent& event ){ event.Skip(); } virtual void OnMenuAbout( wxCommandEvent& event ){ event.Skip(); } virtual void OnAddFolder( wxCommandEvent& event ){ event.Skip(); } virtual void OnRemoveTopFolder( wxCommandEvent& event ){ event.Skip(); } diff --git a/RealtimeSync/mainDialog.cpp b/RealtimeSync/mainDialog.cpp index d849eee5..8d9c7d7a 100644 --- a/RealtimeSync/mainDialog.cpp +++ b/RealtimeSync/mainDialog.cpp @@ -17,8 +17,11 @@ using namespace FreeFileSync; -MainDialog::MainDialog(wxDialog *dlg, const wxString& cfgFilename) - : MainDlgGenerated(dlg) +MainDialog::MainDialog(wxDialog *dlg, + const wxString& cfgFilename, + wxHelpController& helpController) + : MainDlgGenerated(dlg), + helpController_(helpController) { wxWindowUpdateLocker dummy(this); //avoid display distortion @@ -93,7 +96,7 @@ MainDialog::~MainDialog() { writeRealConfig(currentCfg, lastConfigFileName()); } - catch (const FreeFileSync::FileError& error) + catch (const xmlAccess::XmlError& error) { wxMessageBox(error.show().c_str(), _("Error"), wxOK | wxICON_ERROR); } @@ -121,6 +124,16 @@ const wxString& MainDialog::lastConfigFileName() } +void MainDialog::OnShowHelp(wxCommandEvent& event) +{ + #ifdef FFS_WIN + helpController_.DisplaySection(wxT("html\\advanced\\RealtimeSync.html")); + #elif defined FFS_LINUX + helpController_.DisplaySection(wxT("html/advanced/RealtimeSync.html")); + #endif +} + + void MainDialog::OnMenuAbout(wxCommandEvent& event) { //build information diff --git a/RealtimeSync/mainDialog.h b/RealtimeSync/mainDialog.h index 9cf44a67..8447d269 100644 --- a/RealtimeSync/mainDialog.h +++ b/RealtimeSync/mainDialog.h @@ -12,6 +12,7 @@ #include <vector> #include <memory> #include "../shared/dragAndDrop.h" +#include <wx/help.h> namespace xmlAccess { @@ -36,7 +37,7 @@ private: class MainDialog: public MainDlgGenerated { public: - MainDialog(wxDialog *dlg, const wxString& cfgFilename); + MainDialog(wxDialog *dlg, const wxString& cfgFilename, wxHelpController& helpController); ~MainDialog(); void loadConfig(const wxString& filename); @@ -44,6 +45,7 @@ public: private: virtual void OnClose( wxCloseEvent& event); virtual void OnQuit( wxCommandEvent& event); + virtual void OnShowHelp( wxCommandEvent& event); virtual void OnMenuAbout( wxCommandEvent& event); virtual void OnAddFolder( wxCommandEvent& event); virtual void OnRemoveFolder( wxCommandEvent& event); @@ -68,6 +70,7 @@ private: //additional folders std::vector<FolderPanel*> additionalFolders; //additional pairs to the standard pair + wxHelpController& helpController_; //support for drag and drop on main folder std::auto_ptr<FreeFileSync::DragDropOnDlg> dragDropOnFolder; }; diff --git a/RealtimeSync/makefile b/RealtimeSync/makefile index 054bd3c1..25dd373f 100644 --- a/RealtimeSync/makefile +++ b/RealtimeSync/makefile @@ -1,4 +1,4 @@ -CPPFLAGS=-Wall -pipe -DNDEBUG -DwxUSE_UNICODE `wx-config --cxxflags --debug=no --unicode=yes` `pkg-config --cflags gtk+-2.0` -DFFS_LINUX -DTIXML_USE_STL -DZSTRING_CHAR -O3 -pthread -c -I../shared/boost_1_40_0 +CPPFLAGS=-Wall -pipe -DNDEBUG -DwxUSE_UNICODE `wx-config --cxxflags --debug=no --unicode=yes` `pkg-config --cflags gtk+-2.0` -DFFS_LINUX -DTIXML_USE_STL -DZSTRING_CHAR -O3 -pthread -c -I../shared/boost_1_x LINKFLAGS=`wx-config --libs --debug=no --unicode=yes` -O3 -pthread FILE_LIST= #internal list of all *.cpp files needed for compilation diff --git a/RealtimeSync/resources.cpp b/RealtimeSync/resources.cpp index 37a0bb43..fe2a5ced 100644 --- a/RealtimeSync/resources.cpp +++ b/RealtimeSync/resources.cpp @@ -4,7 +4,6 @@ #include <wx/image.h> #include <wx/icon.h> #include <memory> -#include "../shared/stringConv.h" #include "../shared/standardPaths.h" #include "../shared/systemConstants.h" @@ -42,7 +41,7 @@ GlobalResources::~GlobalResources() void GlobalResources::load() const { - wxFFileInputStream input(FreeFileSync::getInstallationDir() + zToWx(globalFunctions::FILE_NAME_SEPARATOR) + wxT("Resources.dat")); + wxFFileInputStream input(FreeFileSync::getInstallationDir() + wxT("Resources.dat")); if (input.IsOk()) //if not... we don't want to react too harsh here { //activate support for .png files diff --git a/RealtimeSync/xmlFreeFileSync.cpp b/RealtimeSync/xmlFreeFileSync.cpp index dc352135..d09e7a7a 100644 --- a/RealtimeSync/xmlFreeFileSync.cpp +++ b/RealtimeSync/xmlFreeFileSync.cpp @@ -34,8 +34,8 @@ xmlAccess::XmlRealConfig convertBatchToReal(const xmlAccess::XmlBatchConfig& bat #endif //add main folders - uniqueFolders.insert(zToWx(batchCfg.mainCfg.mainFolderPair.leftDirectory)); - uniqueFolders.insert(zToWx(batchCfg.mainCfg.mainFolderPair.rightDirectory)); + uniqueFolders.insert(zToWx(batchCfg.mainCfg.firstPair.leftDirectory)); + uniqueFolders.insert(zToWx(batchCfg.mainCfg.firstPair.rightDirectory)); //additional folders for (std::vector<FreeFileSync::FolderPairEnh>::const_iterator i = batchCfg.mainCfg.additionalPairs.begin(); @@ -47,8 +47,13 @@ xmlAccess::XmlRealConfig convertBatchToReal(const xmlAccess::XmlBatchConfig& bat output.directories.insert(output.directories.end(), uniqueFolders.begin(), uniqueFolders.end()); - output.commandline = FreeFileSync::getInstallationDir() + zToWx(globalFunctions::FILE_NAME_SEPARATOR) + wxT("FreeFileSync.exe ") + - wxT("\"") + filename + wxT("\""); + output.commandline = FreeFileSync::getInstallationDir() + +#ifdef FFS_WIN + wxT("FreeFileSync.exe") + +#elif defined FFS_LINUX + wxT("FreeFileSync") + +#endif + wxT(" \"") + filename + wxT("\""); return output; } @@ -76,7 +81,7 @@ void RealtimeSync::readRealOrBatchConfig(const wxString& filename, xmlAccess::Xm config = convertBatchToReal(batchCfg, filename); //do work despite parsing errors, then re-throw throw; // } - config = convertBatchToReal(batchCfg, filename); + config = convertBatchToReal(batchCfg, filename); } diff --git a/algorithm.cpp b/algorithm.cpp index f4f95396..566bae27 100644 --- a/algorithm.cpp +++ b/algorithm.cpp @@ -92,6 +92,49 @@ private: //--------------------------------------------------------------------------------------------------------------- +class FindNonEqual //test if non-equal items exist in scanned data +{ +public: + bool findNonEqual(const HierarchyObject& hierObj) const + { + //files + if (std::find_if(hierObj.subFiles.begin(), hierObj.subFiles.end(), *this) != hierObj.subFiles.end()) + return true; + + //directories + return std::find_if(hierObj.subDirs.begin(), hierObj.subDirs.end(), *this) != hierObj.subDirs.end(); + } + + bool operator()(const FileMapping& fileObj) const + { + return fileObj.getCategory() != FILE_EQUAL; + } + + bool operator()(const DirMapping& dirObj) const + { + if (dirObj.getDirCategory() != DIR_EQUAL) + return true; + + return findNonEqual(dirObj); //recursion + } +}; + + +struct AllElementsEqual : public std::unary_function<BaseDirMapping, bool> +{ + bool operator()(const BaseDirMapping& baseMapping) const + { + return !FindNonEqual().findNonEqual(baseMapping); + } +}; + + +bool FreeFileSync::allElementsEqual(const FolderComparison& folderCmp) +{ + return std::find_if(folderCmp.begin(), folderCmp.end(), std::not1(AllElementsEqual())) == folderCmp.end(); +} + +//--------------------------------------------------------------------------------------------------------------- enum Answer { CHANGE_DETECTED, @@ -105,7 +148,7 @@ class DetectChanges { public: DetectChanges(const DirContainer* dirCont, //DirContainer in sense of a HierarchyObject - const FilterProcess& dbFilter); + const FilterProcess::FilterRef& dbFilter); DetectChanges(const DirContainer* dirCont); //DirContainer in sense of a HierarchyObject @@ -123,14 +166,14 @@ public: private: const DirContainer* const dirCont_; //if NULL: did not exist during db creation - typename Loki::Select<respectFiltering, const FilterProcess&, Loki::NullType>::Result dbFilter_; //filter setting that was used when db was created + typename Loki::Select<respectFiltering, const FilterProcess::FilterRef, Loki::NullType>::Result dbFilter_; //filter setting that was used when db was created }; template <> inline DetectChanges<true>::DetectChanges(const DirContainer* dirCont, //DirContainer in sense of a HierarchyObject - const FilterProcess& dbFilter) : + const FilterProcess::FilterRef& dbFilter) : dirCont_(dirCont), dbFilter_(dbFilter) {} @@ -195,7 +238,7 @@ inline Answer DetectChanges<true>::detectFileChange(const FileMapping& fileObj) const { //if filtering would have excluded file during database creation, then we can't say anything about its former state - if (!dbFilter_.passFileFilter(fileObj.getObjShortName())) + if (!dbFilter_->passFileFilter(fileObj.getObjShortName())) return CANT_SAY_FILTERING_CHANGED; return detectFileChangeSub<side>(fileObj, dirCont_); @@ -250,7 +293,7 @@ template <SelectedSide side> DetectChanges<true>::DirAnswer DetectChanges<true>::detectDirChange(const DirMapping& dirObj) const { //if filtering would have excluded file during database creation, then we can't say anything about its former state - if (!dbFilter_.passDirFilter(dirObj.getObjShortName(), NULL)) + if (!dbFilter_->passDirFilter(dirObj.getObjShortName(), NULL)) return DirAnswer(CANT_SAY_FILTERING_CHANGED, DetectChanges<true>(NULL, dbFilter_)); const DirContainer* dbSubDir = NULL; @@ -322,7 +365,7 @@ public: txtFilterChanged(_("Cannot determine sync-direction: Changed filter settings!")), handler_(handler) { - if (baseDirectory.subFiles.empty() && baseDirectory.subDirs.empty()) //don't show nag-screens in this case + if (AllElementsEqual()(baseDirectory)) //nothing to do: abort and don't show any nag-screens return; //try to load sync-database files @@ -344,29 +387,21 @@ public: respectFiltering(baseDirectory, dirInfoRight)) { execute(baseDirectory, - DetectChanges<true>(&dirInfoLeft.baseDirContainer, - FilterProcess(dirInfoLeft.includeFilter, - dirInfoLeft.excludeFilter)), - DetectChanges<true>(&dirInfoRight.baseDirContainer, - FilterProcess(dirInfoRight.includeFilter, - dirInfoRight.excludeFilter))); + DetectChanges<true>(&dirInfoLeft.baseDirContainer, dirInfoLeft.filter), + DetectChanges<true>(&dirInfoRight.baseDirContainer, dirInfoRight.filter)); } else if ( !respectFiltering(baseDirectory, dirInfoLeft) && respectFiltering( baseDirectory, dirInfoRight)) { execute(baseDirectory, DetectChanges<false>(&dirInfoLeft.baseDirContainer), - DetectChanges<true>(&dirInfoRight.baseDirContainer, - FilterProcess(dirInfoRight.includeFilter, - dirInfoRight.excludeFilter))); + DetectChanges<true>( &dirInfoRight.baseDirContainer, dirInfoRight.filter)); } else if ( respectFiltering( baseDirectory, dirInfoLeft) && !respectFiltering(baseDirectory, dirInfoRight)) { execute(baseDirectory, - DetectChanges<true>(&dirInfoLeft.baseDirContainer, - FilterProcess(dirInfoLeft.includeFilter, - dirInfoLeft.excludeFilter)), + DetectChanges<true>( &dirInfoLeft.baseDirContainer, dirInfoLeft.filter), DetectChanges<false>(&dirInfoRight.baseDirContainer)); } else @@ -381,15 +416,10 @@ public: private: static bool respectFiltering(const BaseDirMapping& baseDirectory, const DirInformation& dirInfo) { - return dirInfo.filterActive && //respect filtering if sync-DB filter is active && different from baseDir's filter - - (!baseDirectory.getFilter().filterActive || - - FilterProcess(baseDirectory.getFilter().includeFilter, - baseDirectory.getFilter().excludeFilter) != - - FilterProcess(dirInfo.includeFilter, - dirInfo.excludeFilter)); + //respect filtering if sync-DB filter is active && different from baseDir's filter: + // in all other cases "view on files" is smaller for baseDirectory(current) than it was for dirInfo(old) + // => dirInfo can be queried as if it were a scan without filters + return !dirInfo.filter->isNull() && *dirInfo.filter != *baseDirectory.getFilter(); } std::pair<DirInfoPtr, DirInfoPtr> loadDBFile(const BaseDirMapping& baseDirectory) //return NULL on failure @@ -401,7 +431,7 @@ private: catch (FileError& error) //e.g. incompatible database version { if (handler_) handler_->reportWarning(error.show() + wxT(" \n\n") + - _("Using default synchronization directions. Please recheck.")); + _("Setting default synchronization directions. Please check whether they are appropriate for you.")); } return std::pair<DirInfoPtr, DirInfoPtr>(); //NULL } @@ -558,14 +588,17 @@ void FreeFileSync::redetermineSyncDirection(const MainConfiguration& currentMain else if (folderCmp.size() != currentMainCfg.additionalPairs.size() + 1) throw std::logic_error("Programming Error: Contract violation!"); - //main pair - redetermineSyncDirection(currentMainCfg.syncConfiguration, folderCmp[0], handler); + //merge first and additional pairs + std::vector<FolderPairEnh> allPairs; + allPairs.push_back(currentMainCfg.firstPair); + allPairs.insert(allPairs.end(), + currentMainCfg.additionalPairs.begin(), //add additional pairs + currentMainCfg.additionalPairs.end()); - //add. folder pairs - for (std::vector<FolderPairEnh>::const_iterator i = currentMainCfg.additionalPairs.begin(); i != currentMainCfg.additionalPairs.end(); ++i) + for (std::vector<FolderPairEnh>::const_iterator i = allPairs.begin(); i != allPairs.end(); ++i) { redetermineSyncDirection(i->altSyncConfig.get() ? i->altSyncConfig->syncConfiguration : currentMainCfg.syncConfiguration, - folderCmp[i - currentMainCfg.additionalPairs.begin() + 1], handler); + folderCmp[i - allPairs.begin()], handler); } } @@ -614,6 +647,109 @@ void FreeFileSync::setSyncDirectionRec(SyncDirection newDirection, FileSystemObj } +//--------------- functions related to filtering ------------------------------------------------------------------------------------ + +template <bool include> +class InOrExcludeAllRows +{ +public: + void operator()(FreeFileSync::BaseDirMapping& baseDirectory) const //be careful with operator() to no get called by std::for_each! + { + execute(baseDirectory); + } + + void execute(FreeFileSync::HierarchyObject& hierObj) const //don't create ambiguity by replacing with operator() + { + std::for_each(hierObj.subFiles.begin(), hierObj.subFiles.end(), *this); //files + std::for_each(hierObj.subDirs.begin(), hierObj.subDirs.end(), *this); //directories + } + +private: + template<typename Iterator, typename Function> + friend Function std::for_each(Iterator, Iterator, Function); + + void operator()(FreeFileSync::FileMapping& fileObj) const + { + fileObj.setActive(include); + } + + void operator()(FreeFileSync::DirMapping& dirObj) const + { + dirObj.setActive(include); + execute(dirObj); //recursion + } +}; + + +void FreeFileSync::setActiveStatus(bool newStatus, FreeFileSync::FolderComparison& folderCmp) +{ + if (newStatus) + std::for_each(folderCmp.begin(), folderCmp.end(), InOrExcludeAllRows<true>()); //include all rows + else + std::for_each(folderCmp.begin(), folderCmp.end(), InOrExcludeAllRows<false>()); //exclude all rows +} + + +void FreeFileSync::setActiveStatus(bool newStatus, FreeFileSync::FileSystemObject& fsObj) +{ + fsObj.setActive(newStatus); + + DirMapping* dirObj = dynamic_cast<DirMapping*>(&fsObj); + if (dirObj) //process subdirectories also! + { + if (newStatus) + InOrExcludeAllRows<true>().execute(*dirObj); + else + InOrExcludeAllRows<false>().execute(*dirObj); + } +} + + +class FilterData +{ +public: + FilterData(const FilterProcess& filterProcIn) : filterProc(filterProcIn) {} + + void execute(FreeFileSync::HierarchyObject& hierObj) + { + //files + std::for_each(hierObj.subFiles.begin(), hierObj.subFiles.end(), *this); + + //directories + std::for_each(hierObj.subDirs.begin(), hierObj.subDirs.end(), *this); + }; + +private: + template<typename Iterator, typename Function> + friend Function std::for_each(Iterator, Iterator, Function); + + + void operator()(FreeFileSync::FileMapping& fileObj) + { + fileObj.setActive(filterProc.passFileFilter(fileObj.getObjRelativeName())); + } + + void operator()(FreeFileSync::DirMapping& dirObj) + { + bool subObjMightMatch = true; + dirObj.setActive(filterProc.passDirFilter(dirObj.getObjRelativeName(), &subObjMightMatch)); + + if (subObjMightMatch) //use same logic as within directory traversing here: evaluate filter in subdirs only if objects could match + execute(dirObj); //recursion + else + InOrExcludeAllRows<false>().execute(dirObj); //exclude all files dirs in subfolders + } + + const FilterProcess& filterProc; +}; + + +void FreeFileSync::applyFiltering(const FilterProcess& filter, FreeFileSync::BaseDirMapping& baseDirectory) +{ + FilterData(filter).execute(baseDirectory); +} + + void FreeFileSync::applyFiltering(const MainConfiguration& currentMainCfg, FolderComparison& folderCmp) { if (folderCmp.size() == 0) @@ -621,18 +757,26 @@ void FreeFileSync::applyFiltering(const MainConfiguration& currentMainCfg, Folde else if (folderCmp.size() != currentMainCfg.additionalPairs.size() + 1) throw std::logic_error("Programming Error: Contract violation!"); - //main pair - FreeFileSync::FilterProcess(currentMainCfg.includeFilter, currentMainCfg.excludeFilter).filterAll(folderCmp[0]); - //add. folder pairs - for (std::vector<FolderPairEnh>::const_iterator i = currentMainCfg.additionalPairs.begin(); i != currentMainCfg.additionalPairs.end(); ++i) + //merge first and additional pairs + std::vector<FolderPairEnh> allPairs; + allPairs.push_back(currentMainCfg.firstPair); + allPairs.insert(allPairs.end(), + currentMainCfg.additionalPairs.begin(), //add additional pairs + currentMainCfg.additionalPairs.end()); + + + const FilterProcess::FilterRef globalFilter(new NameFilter(currentMainCfg.includeFilter, currentMainCfg.excludeFilter)); + + for (std::vector<FolderPairEnh>::const_iterator i = allPairs.begin(); i != allPairs.end(); ++i) { - HierarchyObject& baseDirectory = folderCmp[i - currentMainCfg.additionalPairs.begin() + 1]; + BaseDirMapping& baseDirectory = folderCmp[i - allPairs.begin()]; - if (i->altFilter.get()) - FreeFileSync::FilterProcess(i->altFilter->includeFilter, i->altFilter->excludeFilter).filterAll(baseDirectory); - else - FreeFileSync::FilterProcess(currentMainCfg.includeFilter, currentMainCfg.excludeFilter).filterAll(baseDirectory); + applyFiltering(*combineFilters(globalFilter, + FilterProcess::FilterRef(new NameFilter( + i->localFilter.includeFilter, + i->localFilter.excludeFilter))), + baseDirectory); } } diff --git a/algorithm.h b/algorithm.h index b2b0a4ef..580ad2dd 100644 --- a/algorithm.h +++ b/algorithm.h @@ -6,6 +6,8 @@ namespace FreeFileSync { +class FilterProcess; + void swapGrids(const MainConfiguration& config, FolderComparison& folderCmp); struct DeterminationProblem //callback @@ -18,7 +20,15 @@ void redetermineSyncDirection(const MainConfiguration& currentMainCfg, FolderCom void setSyncDirectionRec(SyncDirection newDirection, FileSystemObject& fsObj); //set new direction (recursively) +bool allElementsEqual(const FolderComparison& folderCmp); + +//filtering void applyFiltering(const MainConfiguration& currentMainCfg, FolderComparison& folderCmp); +void applyFiltering(const FilterProcess& filter, BaseDirMapping& baseDirectory); + +void setActiveStatus(bool newStatus, FolderComparison& folderCmp); //activate or deactivate all rows +void setActiveStatus(bool newStatus, FileSystemObject& fsObj); //activate or deactivate row: works recursively! + //manual deletion of files on main grid std::pair<wxString, int> deleteFromGridAndHDPreview( //returns wxString with elements to be deleted and total count diff --git a/comparison.cpp b/comparison.cpp index fb16d563..79105801 100644 --- a/comparison.cpp +++ b/comparison.cpp @@ -26,25 +26,29 @@ using namespace FreeFileSync; std::vector<FreeFileSync::FolderPairCfg> FreeFileSync::extractCompareCfg(const MainConfiguration& mainCfg) { - std::vector<FolderPairCfg> output; + //merge first and additional pairs + std::vector<FolderPairEnh> allPairs; + allPairs.push_back(mainCfg.firstPair); + allPairs.insert(allPairs.end(), + mainCfg.additionalPairs.begin(), //add additional pairs + mainCfg.additionalPairs.end()); + + const FilterProcess::FilterRef globalFilter(new NameFilter(mainCfg.includeFilter, mainCfg.excludeFilter)); - //add main pair - output.push_back( - FolderPairCfg(mainCfg.mainFolderPair.leftDirectory, - mainCfg.mainFolderPair.rightDirectory, - mainCfg.filterIsActive, - mainCfg.includeFilter, - mainCfg.excludeFilter, - mainCfg.syncConfiguration)); - - //add additional pairs - for (std::vector<FolderPairEnh>::const_iterator i = mainCfg.additionalPairs.begin(); i != mainCfg.additionalPairs.end(); ++i) + std::vector<FolderPairCfg> output; + for (std::vector<FolderPairEnh>::const_iterator i = allPairs.begin(); i != allPairs.end(); ++i) output.push_back( FolderPairCfg(i->leftDirectory, i->rightDirectory, - mainCfg.filterIsActive, - i->altFilter.get() ? i->altFilter->includeFilter : mainCfg.includeFilter, - i->altFilter.get() ? i->altFilter->excludeFilter : mainCfg.excludeFilter, + + mainCfg.filterIsActive ? + combineFilters(globalFilter, + FilterProcess::FilterRef( + new NameFilter( + i->localFilter.includeFilter, + i->localFilter.excludeFilter))) : + FilterProcess::FilterRef(new NullFilter), + i->altSyncConfig.get() ? i->altSyncConfig->syncConfiguration : mainCfg.syncConfiguration)); return output; @@ -52,19 +56,12 @@ std::vector<FreeFileSync::FolderPairCfg> FreeFileSync::extractCompareCfg(const M - - - - -template <bool filterActive> class BaseDirCallback; - -template <bool filterActive> class DirCallback : public FreeFileSync::TraverseCallback { public: - DirCallback(BaseDirCallback<filterActive>* baseCallback, + DirCallback(BaseDirCallback* baseCallback, const Zstring& relNameParentPf, //postfixed with FILE_NAME_SEPARATOR! DirContainer& output, StatusHandler* handler) : @@ -80,7 +77,7 @@ public: virtual ReturnValue onError(const wxString& errorText); private: - BaseDirCallback<filterActive>* const baseCallback_; + BaseDirCallback* const baseCallback_; const Zstring relNameParentPf_; DirContainer& output_; StatusHandler* const statusHandler; @@ -88,29 +85,28 @@ private: -template <bool filterActive> -class BaseDirCallback : public DirCallback<filterActive> +class BaseDirCallback : public DirCallback { - friend class DirCallback<filterActive>; + friend class DirCallback; public: - BaseDirCallback(DirContainer& output, const FilterProcess* filter, StatusHandler* handler) : - DirCallback<filterActive>(this, Zstring(), output, handler), + BaseDirCallback(DirContainer& output, const FilterProcess::FilterRef& filter, StatusHandler* handler) : + DirCallback(this, Zstring(), output, handler), textScanning(wxToZ(wxString(_("Scanning:")) + wxT(" \n"))), filterInstance(filter) {} virtual TraverseCallback::ReturnValue onFile(const DefaultChar* shortName, const Zstring& fullName, const TraverseCallback::FileInfo& details); private: - typedef boost::shared_ptr<const DirCallback<filterActive> > CallbackPointer; + typedef boost::shared_ptr<const DirCallback> CallbackPointer; const Zstring textScanning; std::vector<CallbackPointer> callBackBox; //collection of callback pointers to handle ownership - const FilterProcess* const filterInstance; //must NOT be NULL if (filterActive) + + const FilterProcess::FilterRef filterInstance; //always bound! }; -template <bool filterActive> -TraverseCallback::ReturnValue DirCallback<filterActive>::onFile(const DefaultChar* shortName, const Zstring& fullName, const FileInfo& details) +TraverseCallback::ReturnValue DirCallback::onFile(const DefaultChar* shortName, const Zstring& fullName, const FileInfo& details) { //assemble status message (performance optimized) = textScanning + wxT("\"") + fullName + wxT("\"") Zstring statusText = baseCallback_->textScanning; @@ -124,13 +120,10 @@ TraverseCallback::ReturnValue DirCallback<filterActive>::onFile(const DefaultCha //------------------------------------------------------------------------------------ //apply filter before processing (use relative name!) - if (filterActive) + if (!baseCallback_->filterInstance->passFileFilter(relNameParentPf_ + shortName)) { - if (!baseCallback_->filterInstance->passFileFilter(relNameParentPf_ + shortName)) - { - statusHandler->requestUiRefresh(); - return TRAVERSING_CONTINUE; - } + statusHandler->requestUiRefresh(); + return TRAVERSING_CONTINUE; } output_.addSubFile(shortName, FileDescriptor(details.lastWriteTimeRaw, details.fileSize)); @@ -144,8 +137,7 @@ TraverseCallback::ReturnValue DirCallback<filterActive>::onFile(const DefaultCha } -template <bool filterActive> -TraverseCallback::ReturnValDir DirCallback<filterActive>::onDir(const DefaultChar* shortName, const Zstring& fullName) +TraverseCallback::ReturnValDir DirCallback::onDir(const DefaultChar* shortName, const Zstring& fullName) { using globalFunctions::FILE_NAME_SEPARATOR; @@ -164,28 +156,26 @@ TraverseCallback::ReturnValDir DirCallback<filterActive>::onDir(const DefaultCha relName += shortName; //apply filter before processing (use relative name!) - if (filterActive) + bool subObjMightMatch = true; + if (!baseCallback_->filterInstance->passDirFilter(relName, &subObjMightMatch)) { - bool subObjMightMatch = true; - if (!baseCallback_->filterInstance->passDirFilter(relName, &subObjMightMatch)) - { - statusHandler->requestUiRefresh(); + statusHandler->requestUiRefresh(); - if (subObjMightMatch) - { - DirContainer& subDir = output_.addSubDir(shortName); + if (subObjMightMatch) + { + DirContainer& subDir = output_.addSubDir(shortName); - DirCallback* subDirCallback = new DirCallback(baseCallback_, relName += FILE_NAME_SEPARATOR, subDir, statusHandler); - baseCallback_->callBackBox.push_back(typename BaseDirCallback<filterActive>::CallbackPointer(subDirCallback)); //handle ownership + DirCallback* subDirCallback = new DirCallback(baseCallback_, relName += FILE_NAME_SEPARATOR, subDir, statusHandler); + baseCallback_->callBackBox.push_back(BaseDirCallback::CallbackPointer(subDirCallback)); //handle ownership - //attention: ensure directory filtering is applied to exclude actually filtered directories - return ReturnValDir(ReturnValDir::Continue(), subDirCallback); - } - else - return ReturnValDir::Ignore(); //do NOT traverse subdirs + //attention: ensure directory filtering is applied later to exclude actually filtered directories + return ReturnValDir(ReturnValDir::Continue(), subDirCallback); } + else + return ReturnValDir::Ignore(); //do NOT traverse subdirs } + DirContainer& subDir = output_.addSubDir(shortName); //add 1 element to the progress indicator @@ -194,14 +184,13 @@ TraverseCallback::ReturnValDir DirCallback<filterActive>::onDir(const DefaultCha statusHandler->requestUiRefresh(); DirCallback* subDirCallback = new DirCallback(baseCallback_, relName += FILE_NAME_SEPARATOR, subDir, statusHandler); - baseCallback_->callBackBox.push_back(typename BaseDirCallback<filterActive>::CallbackPointer(subDirCallback)); //handle ownership + baseCallback_->callBackBox.push_back(BaseDirCallback::CallbackPointer(subDirCallback)); //handle ownership return ReturnValDir(ReturnValDir::Continue(), subDirCallback); } -template <bool filterActive> -TraverseCallback::ReturnValue DirCallback<filterActive>::onError(const wxString& errorText) +TraverseCallback::ReturnValue DirCallback::onError(const wxString& errorText) { while (true) { @@ -218,8 +207,7 @@ TraverseCallback::ReturnValue DirCallback<filterActive>::onError(const wxString& } -template <bool filterActive> -TraverseCallback::ReturnValue BaseDirCallback<filterActive>::onFile( +TraverseCallback::ReturnValue BaseDirCallback::onFile( const DefaultChar* shortName, const Zstring& fullName, const TraverseCallback::FileInfo& details) @@ -232,7 +220,7 @@ TraverseCallback::ReturnValue BaseDirCallback<filterActive>::onFile( #endif return TraverseCallback::TRAVERSING_CONTINUE; - return DirCallback<filterActive>::onFile(shortName, fullName, details); + return DirCallback::onFile(shortName, fullName, details); } @@ -240,12 +228,14 @@ TraverseCallback::ReturnValue BaseDirCallback<filterActive>::onFile( struct DirBufferKey { DirBufferKey(const Zstring& dirname, - boost::shared_ptr<const FilterProcess>& filterInst) : + const FilterProcess::FilterRef& filterIn) : //filter interface: always bound by design! directoryName(dirname), - filterInstance(filterInst) {} + filter(filterIn->isNull() ? //some optimization of "Null" filter + FilterProcess::FilterRef(new NullFilter) : + filterIn) {} - Zstring directoryName; - boost::shared_ptr<const FilterProcess> filterInstance; //buffering has to consider filtering! + const Zstring directoryName; + const FilterProcess::FilterRef filter; //buffering has to consider filtering! bool operator < (const DirBufferKey& b) const { @@ -257,9 +247,7 @@ struct DirBufferKey if (rv != 0) return rv < 0; - return filterInstance.get() && b.filterInstance.get() ? - *filterInstance < *b.filterInstance : - filterInstance.get() < b.filterInstance.get(); //at least one of these is NULL + return *filter < *b.filter; } }; @@ -272,13 +260,12 @@ public: m_traverseDirectorySymlinks(traverseDirectorySymlinks), m_statusUpdater(statusUpdater) {} - const DirContainer& getDirectoryDescription(const Zstring& directoryPostfixed, bool filterActive, const Zstring& includeFilter, const Zstring& excludeFilter); + const DirContainer& getDirectoryDescription(const Zstring& directoryPostfixed, const FilterProcess::FilterRef& filter); private: typedef boost::shared_ptr<DirContainer> DirBufferValue; //exception safety: avoid memory leak typedef std::map<DirBufferKey, DirBufferValue> BufferType; - static DirBufferKey createKey(const Zstring& directoryPostfixed, bool filterActive, const Zstring& includeFilter, const Zstring& excludeFilter); DirContainer& insertIntoBuffer(const DirBufferKey& newKey); BufferType buffer; @@ -288,17 +275,6 @@ private: }; //------------------------------------------------------------------------------------------ - -DirBufferKey CompareProcess::DirectoryBuffer::createKey(const Zstring& directoryPostfixed, bool filterActive, const Zstring& includeFilter, const Zstring& excludeFilter) -{ - boost::shared_ptr<const FilterProcess> filterInstance( - filterActive && FilterProcess(includeFilter, excludeFilter) != FilterProcess::nullFilter() ? //nullfilter: in: '*', ex '' - new FilterProcess(includeFilter, excludeFilter) : NULL); - - return DirBufferKey(directoryPostfixed, filterInstance); -} - - DirContainer& CompareProcess::DirectoryBuffer::insertIntoBuffer(const DirBufferKey& newKey) { DirBufferValue baseContainer(new DirContainer); @@ -306,9 +282,7 @@ DirContainer& CompareProcess::DirectoryBuffer::insertIntoBuffer(const DirBufferK if (FreeFileSync::dirExists(newKey.directoryName.c_str())) //folder existence already checked in startCompareProcess(): do not treat as error when arriving here! { - std::auto_ptr<TraverseCallback> traverser(newKey.filterInstance.get() ? - static_cast<TraverseCallback*>(new BaseDirCallback<true>(*baseContainer.get(), newKey.filterInstance.get(), m_statusUpdater)) : - static_cast<TraverseCallback*>(new BaseDirCallback<false>(*baseContainer.get(), NULL, m_statusUpdater))); + std::auto_ptr<TraverseCallback> traverser(new BaseDirCallback(*baseContainer, newKey.filter, m_statusUpdater)); //get all files and folders from directoryPostfixed (and subdirectories) traverseFolder(newKey.directoryName, m_traverseDirectorySymlinks, traverser.get()); //exceptions may be thrown! @@ -319,11 +293,9 @@ DirContainer& CompareProcess::DirectoryBuffer::insertIntoBuffer(const DirBufferK const DirContainer& CompareProcess::DirectoryBuffer::getDirectoryDescription( const Zstring& directoryPostfixed, - bool filterActive, - const Zstring& includeFilter, - const Zstring& excludeFilter) + const FilterProcess::FilterRef& filter) { - const DirBufferKey searchKey = createKey(directoryPostfixed, filterActive, includeFilter, excludeFilter); + const DirBufferKey searchKey(directoryPostfixed, filter); BufferType::const_iterator entryFound = buffer.find(searchKey); if (entryFound != buffer.end()) @@ -396,13 +368,24 @@ void foldersAreValidForComparison(const std::vector<FolderPairCfg>& folderPairsF bool dependencyExists(const std::set<Zstring>& folders, const Zstring& newFolder, wxString& warningMessage) { for (std::set<Zstring>::const_iterator i = folders.begin(); i != folders.end(); ++i) - if (newFolder.StartsWith(*i) || i->StartsWith(newFolder)) + { + Zstring newFolderFmt = newFolder; + Zstring refFolderFmt = *i; +#ifdef FFS_WIN //Windows does NOT distinguish between upper/lower-case + newFolderFmt.MakeLower(); + refFolderFmt.MakeLower(); +#elif defined FFS_LINUX //Linux DOES distinguish between upper/lower-case + //nothing to do here +#endif + + if (newFolderFmt.StartsWith(refFolderFmt) || refFolderFmt.StartsWith(newFolderFmt)) { warningMessage = wxString(_("Directories are dependent! Be careful when setting up synchronization rules:")) + wxT("\n") + - wxT("\"") + zToWx(*i) + wxT("\",\n") + + wxT("\"") + zToWx(*i) + wxT("\"\n") + wxT("\"") + zToWx(newFolder) + wxT("\""); return true; } + } return false; } @@ -607,15 +590,6 @@ void formatPair(FolderPairCfg& input) //############################################################################################################################# -//filters and removes all excluded directories (but keeps those serving as parent folders) -void filterAndRemoveDirs(BaseDirMapping& baseDir, const Zstring& include, const Zstring& exclude) -{ - FilterProcess filterProc(include, exclude); - - RemoveFilteredDirs(filterProc).execute(baseDir); -} - - void CompareProcess::startCompareProcess(const std::vector<FolderPairCfg>& directoryPairs, const CompareVariant cmpVar, FolderComparison& output) @@ -669,8 +643,11 @@ void CompareProcess::startCompareProcess(const std::vector<FolderPairCfg>& direc const FolderPairCfg& fpCfg = directoryPairsFormatted[j - output_tmp.begin()]; //attention: some filtered directories are still in the comparison result! (see include filter handling!) - if (fpCfg.filterIsActive) //let's filter them now... (and remove those that contain excluded elements only) - filterAndRemoveDirs(*j, fpCfg.includeFilter.c_str(), fpCfg.excludeFilter.c_str()); + if (!fpCfg.filter->isNull()) //let's filter them now... (and remove those that contain excluded elements only) + { + //filters and removes all excluded directories (but keeps those serving as parent folders) + RemoveFilteredDirs(*fpCfg.filter).execute(*j); + } //set initial sync-direction class RedetermineCallback : public DeterminationProblem @@ -778,9 +755,7 @@ void CompareProcess::compareByTimeSize(const std::vector<FolderPairCfg>& directo { BaseDirMapping newEntry(pair->leftDirectory, pair->rightDirectory, - pair->filterIsActive, - pair->includeFilter, - pair->excludeFilter); + pair->filter); output.push_back(newEntry); //attention: push_back() copies by value!!! performance: append BEFORE writing values into fileCmp! //do basis scan and retrieve files existing on both sides as "compareCandidates" @@ -881,9 +856,7 @@ void CompareProcess::compareByContent(const std::vector<FolderPairCfg>& director { BaseDirMapping newEntry(pair->leftDirectory, pair->rightDirectory, - pair->filterIsActive, - pair->includeFilter, - pair->excludeFilter); + pair->filter); output.push_back(newEntry); //attention: push_back() copies by value!!! performance: append BEFORE writing values into fileCmp! //do basis scan and retrieve candidates for binary comparison (files existing on both sides) @@ -1072,15 +1045,11 @@ void CompareProcess::performBaseComparison(BaseDirMapping& output, std::vector<F //scan directories const DirContainer& directoryLeft = directoryBuffer->getDirectoryDescription( output.getBaseDir<LEFT_SIDE>(), - output.getFilter().filterActive, - output.getFilter().includeFilter, - output.getFilter().excludeFilter); + output.getFilter()); const DirContainer& directoryRight = directoryBuffer->getDirectoryDescription( output.getBaseDir<RIGHT_SIDE>(), - output.getFilter().filterActive, - output.getFilter().includeFilter, - output.getFilter().excludeFilter); + output.getFilter()); statusUpdater->updateStatusText(wxToZ(_("Generating file list..."))); @@ -1090,3 +1059,5 @@ void CompareProcess::performBaseComparison(BaseDirMapping& output, std::vector<F MergeSides(appendUndefined).execute(directoryLeft, directoryRight, output); } + + diff --git a/comparison.h b/comparison.h index 28f9d8a3..3a7492c6 100644 --- a/comparison.h +++ b/comparison.h @@ -8,32 +8,25 @@ class StatusHandler; namespace FreeFileSync { -class FilterProcess; struct FolderPairCfg { FolderPairCfg(const Zstring& leftDir, const Zstring& rightDir, - bool filterAct, - const Zstring& include, - const Zstring& exclude, + const FilterProcess::FilterRef& filterIn, const SyncConfiguration& syncCfg) : leftDirectory(leftDir), rightDirectory(rightDir), - filterIsActive(filterAct), - includeFilter(include), - excludeFilter(exclude), + filter(filterIn), syncConfiguration(syncCfg) {} Zstring leftDirectory; Zstring rightDirectory; - bool filterIsActive; - Zstring includeFilter; - Zstring excludeFilter; - + FilterProcess::FilterRef filter; //filter interface: always bound by design! SyncConfiguration syncConfiguration; }; + std::vector<FolderPairCfg> extractCompareCfg(const MainConfiguration& mainCfg); diff --git a/fileHierarchy.cpp b/fileHierarchy.cpp index f0458b8e..e27d9421 100644 --- a/fileHierarchy.cpp +++ b/fileHierarchy.cpp @@ -3,11 +3,11 @@ #include <wx/zstream.h> #include "shared/globalFunctions.h" #include "shared/fileError.h" -#include <boost/scoped_array.hpp> #include <wx/intl.h> #include "shared/stringConv.h" #include "shared/fileHandling.h" #include <wx/mstream.h> +#include "shared/serialize.h" #ifdef FFS_WIN #include <wx/msw/wrapwin.h> //includes "windows.h" @@ -192,98 +192,20 @@ const Zstring& FreeFileSync::getSyncDBFilename() } -inline -Zstring readString(wxInputStream& stream) //read string from file stream -{ - const size_t strLength = readNumber<size_t>(stream); - if (strLength <= 1000) - { - DefaultChar buffer[1000]; - stream.Read(buffer, sizeof(DefaultChar) * strLength); - return Zstring(buffer, strLength); - } - else - { - boost::scoped_array<DefaultChar> buffer(new DefaultChar[strLength]); - stream.Read(buffer.get(), sizeof(DefaultChar) * strLength); - return Zstring(buffer.get(), strLength); - } -} - - -inline -void writeString(wxOutputStream& stream, const Zstring& str) //write string to filestream -{ - globalFunctions::writeNumber<size_t>(stream, str.length()); - stream.Write(str.c_str(), sizeof(DefaultChar) * str.length()); -} - - //------------------------------------------------------------------------------------------------------------------------------- const char FILE_FORMAT_DESCR[] = "FreeFileSync"; -const int FILE_FORMAT_VER = 2; +const int FILE_FORMAT_VER = 3; //------------------------------------------------------------------------------------------------------------------------------- -class ReadInputStream -{ -protected: - ReadInputStream(wxInputStream& stream, const Zstring& errorObjName) : stream_(stream), errorObjName_(errorObjName) {} - - void check() - { - if (stream_.GetLastError() != wxSTREAM_NO_ERROR) - throw FileError(wxString(_("Error reading from synchronization database:")) + wxT(" \n") + - wxT("\"") + zToWx(errorObjName_) + wxT("\"")); - } - - template <class T> - T readNumberC() //checked read operation - { - T output = readNumber<T>(stream_); - check(); - return output; - } - - Zstring readStringC() //checked read operation - { - Zstring output = readString(stream_); - check(); - return output; - } - - typedef boost::shared_ptr<std::vector<char> > CharArray; - CharArray readArrayC() - { - CharArray buffer(new std::vector<char>); - const size_t byteCount = readNumberC<size_t>(); - if (byteCount > 0) - { - buffer->resize(byteCount); - stream_.Read(&(*buffer)[0], byteCount); - check(); - if (stream_.LastRead() != byteCount) //some additional check - throw FileError(wxString(_("Error reading from synchronization database:")) + wxT(" \n") + - wxT("\"") + zToWx(errorObjName_) + wxT("\"")); - } - return buffer; - } - -protected: - wxInputStream& stream_; -private: - const Zstring& errorObjName_; //used for error text only -}; - -class ReadDirInfo : public ReadInputStream +class ReadDirInfo : public Utility::ReadInputStream { public: - ReadDirInfo(wxInputStream& stream, const Zstring& errorObjName, DirInformation& dirInfo) : ReadInputStream(stream, errorObjName) + ReadDirInfo(wxInputStream& stream, const wxString& errorObjName, DirInformation& dirInfo) : ReadInputStream(stream, errorObjName) { - //save filter settings - dirInfo.filterActive = readNumberC<bool>(); - dirInfo.includeFilter = readStringC(); - dirInfo.excludeFilter = readStringC(); + //read filter settings + dirInfo.filter = FilterProcess::loadFilter(stream_); + check(); //start recursion execute(dirInfo.baseDirContainer); @@ -334,17 +256,17 @@ left side right side DB-ID 123 <-\ /-> DB-ID 567 \/ Partner-ID 111 /\ Partner-ID 222 -Partner-ID 567 -/ \- Partner-ID 123 +Partner-ID 567 _/ \_ Partner-ID 123 ... ... */ -class ReadFileStream : public ReadInputStream +class ReadFileStream : public Utility::ReadInputStream { public: - ReadFileStream(wxInputStream& stream, const Zstring& filename, DbStreamData& output) : ReadInputStream(stream, filename) + ReadFileStream(wxInputStream& stream, const wxString& filename, DbStreamData& output) : ReadInputStream(stream, filename) { if (readNumberC<int>() != FILE_FORMAT_VER) //read file format version - throw FileError(wxString(_("Incompatible synchronization database format:")) + wxT(" \n") + wxT("\"") + zToWx(filename) + wxT("\"")); + throw FileError(wxString(_("Incompatible synchronization database format:")) + wxT(" \n") + wxT("\"") + filename + wxT("\"")); //read DB id output.first = Utility::UniqueId(stream_); @@ -370,8 +292,9 @@ public: DbStreamData loadFile(const Zstring& filename) //throw (FileError) { if (!FreeFileSync::fileExists(filename)) - throw FileError(wxString(_("Initial synchronization.")) + wxT(" \n") + - wxT("(") + _("No database file existing yet:") + wxT(" \"") + zToWx(filename) + wxT("\")")); + throw FileError(wxString(_("Initial synchronization:")) + wxT(" ") + + _("The database file is not yet existing, but will be created during synchronization:") + wxT("\n") + + wxT(" \"") + zToWx(filename) + wxT("\"")); //read format description (uncompressed) @@ -389,7 +312,7 @@ DbStreamData loadFile(const Zstring& filename) //throw (FileError) wxZlibInputStream input(uncompressed, wxZLIB_ZLIB); DbStreamData output; - ReadFileStream(input, filename, output); + ReadFileStream(input, zToWx(filename), output); return output; } @@ -406,22 +329,24 @@ std::pair<DirInfoPtr, DirInfoPtr> FreeFileSync::loadFromDisk(const BaseDirMappin //find associated DirInfo-streams DirectoryTOC::const_iterator dbLeft = dbEntriesLeft.second.find(dbEntriesRight.first); //find left db-entry that corresponds to right database if (dbLeft == dbEntriesLeft.second.end()) - throw FileError(wxString(_("Initial synchronization.")) + wxT(" \n") + - wxT("(") + _("No database entry existing in file:") + wxT(" \"") + zToWx(fileNameLeft) + wxT("\")")); + throw FileError(wxString(_("Initial synchronization:")) + wxT(" ") + + _("The required database entry is not yet existing, but will be created during synchronization:") + wxT("\n") + + wxT(" \"") + zToWx(fileNameLeft) + wxT("\"")); DirectoryTOC::const_iterator dbRight = dbEntriesRight.second.find(dbEntriesLeft.first); //find left db-entry that corresponds to right database if (dbRight == dbEntriesRight.second.end()) - throw FileError(wxString(_("Initial synchronization.")) + wxT(" \n") + - wxT("(") + _("No database entry existing in file:") + wxT(" \"") + zToWx(fileNameRight) + wxT("\")")); + throw FileError(wxString(_("Initial synchronization:")) + wxT(" ") + + _("The required database entry is not yet existing, but will be created during synchronization:") + wxT("\n") + + wxT(" \"") + zToWx(fileNameRight) + wxT("\"")); //read streams into DirInfo boost::shared_ptr<DirInformation> dirInfoLeft(new DirInformation); wxMemoryInputStream buffer(&(*dbLeft->second)[0], dbLeft->second->size()); //convert char-array to inputstream: no copying, ownership not transferred - ReadDirInfo(buffer, fileNameLeft, *dirInfoLeft); //read file/dir information + ReadDirInfo(buffer, zToWx(fileNameLeft), *dirInfoLeft); //read file/dir information boost::shared_ptr<DirInformation> dirInfoRight(new DirInformation); wxMemoryInputStream buffer2(&(*dbRight->second)[0], dbRight->second->size()); //convert char-array to inputstream: no copying, ownership not transferred - ReadDirInfo(buffer2, fileNameRight, *dirInfoRight); //read file/dir information + ReadDirInfo(buffer2, zToWx(fileNameRight), *dirInfoRight); //read file/dir information return std::make_pair(dirInfoLeft, dirInfoRight); } @@ -439,61 +364,15 @@ struct IsNonEmpty }; -class WriteOutputStream -{ -protected: - WriteOutputStream(const Zstring& errorObjName, wxOutputStream& stream) : stream_(stream), errorObjName_(errorObjName) {} - - void check() - { - if (stream_.GetLastError() != wxSTREAM_NO_ERROR) - throw FileError(wxString(_("Error writing to synchronization database:")) + wxT(" \n") + - wxT("\"") + zToWx(errorObjName_) + wxT("\"")); - } - - template <class T> - void writeNumberC(T number) //checked write operation - { - writeNumber<T>(stream_, number); - check(); - } - - void writeStringC(const Zstring& str) //checked write operation - { - writeString(stream_, str); - check(); - } - - void writeArrayC(const std::vector<char>& buffer) - { - writeNumberC<size_t>(buffer.size()); - if (buffer.size() > 0) - { - stream_.Write(&buffer[0], buffer.size()); - check(); - if (stream_.LastWrite() != buffer.size()) //some additional check - throw FileError(wxString(_("Error writing to synchronization database:")) + wxT(" \n") + - wxT("\"") + zToWx(errorObjName_) + wxT("\"")); - } - } - -protected: - wxOutputStream& stream_; -private: - const Zstring& errorObjName_; //used for error text only! -}; - - template <SelectedSide side> -class SaveDirInfo : public WriteOutputStream +class SaveDirInfo : public Utility::WriteOutputStream { public: - SaveDirInfo(const BaseDirMapping& baseMapping, const Zstring& errorObjName, wxOutputStream& stream) : WriteOutputStream(errorObjName, stream) + SaveDirInfo(const BaseDirMapping& baseMapping, const wxString& errorObjName, wxOutputStream& stream) : WriteOutputStream(errorObjName, stream) { //save filter settings - writeNumberC<bool>(baseMapping.getFilter().filterActive); - writeStringC(baseMapping.getFilter().includeFilter.c_str()); - writeStringC(baseMapping.getFilter().excludeFilter.c_str()); + baseMapping.getFilter()->saveFilter(stream_); + check(); //start recursion execute(baseMapping); @@ -535,10 +414,10 @@ private: }; -class WriteFileStream : public WriteOutputStream +class WriteFileStream : public Utility::WriteOutputStream { public: - WriteFileStream(const DbStreamData& input, const Zstring& filename, wxOutputStream& stream) : WriteOutputStream(filename, stream) + WriteFileStream(const DbStreamData& input, const wxString& filename, wxOutputStream& stream) : WriteOutputStream(filename, stream) { //save file format version writeNumberC<int>(FILE_FORMAT_VER); @@ -580,7 +459,7 @@ void saveFile(const DbStreamData& dbStream, const Zstring& filename) //throw (Fi 6 1,77 MB - 613 ms 9 (maximal compression) 1,74 MB - 3330 ms */ - WriteFileStream(dbStream, filename, output); + WriteFileStream(dbStream, zToWx(filename), output); //(try to) hide database file #ifdef FFS_WIN @@ -627,7 +506,7 @@ void FreeFileSync::saveToDisk(const BaseDirMapping& baseMapping) //throw (FileEr MemoryStreamPtr dbEntryLeft(new std::vector<char>); { wxMemoryOutputStream buffer; - SaveDirInfo<LEFT_SIDE>(baseMapping, baseMapping.getDBFilename<LEFT_SIDE>(), buffer); + SaveDirInfo<LEFT_SIDE>(baseMapping, zToWx(baseMapping.getDBFilename<LEFT_SIDE>()), buffer); dbEntryLeft->resize(buffer.GetSize()); //convert output stream to char-array buffer.CopyTo(&(*dbEntryLeft)[0], buffer.GetSize()); // } @@ -635,7 +514,7 @@ void FreeFileSync::saveToDisk(const BaseDirMapping& baseMapping) //throw (FileEr MemoryStreamPtr dbEntryRight(new std::vector<char>); { wxMemoryOutputStream buffer; - SaveDirInfo<RIGHT_SIDE>(baseMapping, baseMapping.getDBFilename<RIGHT_SIDE>(), buffer); + SaveDirInfo<RIGHT_SIDE>(baseMapping, zToWx(baseMapping.getDBFilename<RIGHT_SIDE>()), buffer); dbEntryRight->resize(buffer.GetSize()); //convert output stream to char-array buffer.CopyTo(&(*dbEntryRight)[0], buffer.GetSize()); // } @@ -650,7 +529,7 @@ void FreeFileSync::saveToDisk(const BaseDirMapping& baseMapping) //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(baseMapping.getDBFilename<LEFT_SIDE>(), false); + removeFile(baseMapping.getDBFilename<LEFT_SIDE>(), false); removeFile(baseMapping.getDBFilename<RIGHT_SIDE>(), false); renameFile(fileNameLeftTmp, baseMapping.getDBFilename<LEFT_SIDE>()); //throw (FileError); renameFile(fileNameRightTmp, baseMapping.getDBFilename<RIGHT_SIDE>()); //throw (FileError); @@ -660,7 +539,7 @@ void FreeFileSync::saveToDisk(const BaseDirMapping& baseMapping) //throw (FileEr { try //clean up: (try to) delete old tmp file { - removeFile(fileNameLeftTmp, false); + removeFile(fileNameLeftTmp, false); removeFile(fileNameRightTmp, false); } catch (...) {} diff --git a/fileHierarchy.h b/fileHierarchy.h index 9f0aec4c..d26d527e 100644 --- a/fileHierarchy.h +++ b/fileHierarchy.h @@ -10,6 +10,7 @@ #include "structures.h" #include <boost/shared_ptr.hpp> #include "shared/guid.h" +#include "library/filter.h" class DirectoryBuffer; @@ -95,9 +96,8 @@ private: struct DirInformation { //filter settings (used when retrieving directory data) - bool filterActive; - Zstring includeFilter; - Zstring excludeFilter; + FilterProcess::FilterRef filter; + //hierarchical directory information DirContainer baseDirContainer; }; @@ -209,10 +209,10 @@ public: //comparison result virtual CompareFilesResult getCategory() const = 0; - virtual const wxString& getCatConflict() const = 0; //only filled if cmpResult == FILE_CONFLICT + virtual const wxString& getCatConflict() const = 0; //only filled if getCategory() == FILE_CONFLICT //sync operation SyncOperation getSyncOperation() const; - const wxString& getSyncOpConflict() const; //only filled if syncDir == SYNC_DIR_INT_CONFLICT + const wxString& getSyncOpConflict() const; //only filled if getSyncOperation() == SYNC_DIR_INT_CONFLICT SyncOperation testSyncOperation(bool selected, SyncDirection syncDir) const; //get syncOp with provided settings //sync settings @@ -367,31 +367,16 @@ class BaseDirMapping : public HierarchyObject //synchronization base directory public: BaseDirMapping(const Zstring& dirPostfixedLeft, const Zstring& dirPostfixedRight, - bool filterActive, - const Zstring& includeFilter, - const Zstring& excludeFilter) : + const FilterProcess::FilterRef& filterIn) : HierarchyObject(dirPostfixedLeft, dirPostfixedRight), - filter(filterActive, includeFilter, excludeFilter) {} - - struct FilterSettings - { - FilterSettings(bool active, - const Zstring& include, - const Zstring& exclude) : - filterActive(active), - includeFilter(include), - excludeFilter(exclude) {} - bool filterActive; - Zstring includeFilter; - Zstring excludeFilter; - }; + filter(filterIn) {} - const FilterSettings& getFilter() const; + const FilterProcess::FilterRef& getFilter() const; template <SelectedSide side> Zstring getDBFilename() const; virtual void swap(); private: - FilterSettings filter; + FilterProcess::FilterRef filter; }; @@ -834,7 +819,7 @@ void DirMapping::copyToR() inline -const BaseDirMapping::FilterSettings& BaseDirMapping::getFilter() const +const FilterProcess::FilterRef& BaseDirMapping::getFilter() const { return filter; } diff --git a/library/CustomGrid.cpp b/library/CustomGrid.cpp index 74ceb07f..6c72859c 100644 --- a/library/CustomGrid.cpp +++ b/library/CustomGrid.cpp @@ -2,7 +2,6 @@ #include "../shared/systemConstants.h" #include "resources.h" #include <wx/dc.h> -//#include "../algorithm.h" #include "../ui/util.h" #include "../shared/stringConv.h" #include "resources.h" @@ -76,7 +75,7 @@ public: virtual int GetNumberRows() { if (gridDataView) - return std::max(gridDataView->rowsOnView(), MIN_ROW_COUNT); + return std::max(static_cast<unsigned int>(gridDataView->rowsOnView()), MIN_ROW_COUNT); else return 0; //grid is initialized with zero number of rows } @@ -242,7 +241,8 @@ public: return xmlAccess::ColumnTypes(1000); } - virtual Zstring getFileName(const unsigned int row) const = 0; + //get filename in order to retrieve the icon from it + virtual Zstring getIconFile(const unsigned int row) const = 0; protected: template <SelectedSide side> @@ -332,7 +332,7 @@ public: return CustomGridTableRim::GetValueSub<LEFT_SIDE>(row, col); } - virtual Zstring getFileName(const unsigned int row) const + virtual Zstring getIconFile(const unsigned int row) const { const FileSystemObject* fsObj = getRawData(row); if (fsObj && !fsObj->isEmpty<LEFT_SIDE>()) @@ -351,11 +351,18 @@ public: return CustomGridTableRim::GetValueSub<RIGHT_SIDE>(row, col); } - virtual Zstring getFileName(const unsigned int row) const + virtual Zstring getIconFile(const unsigned int row) const { const FileSystemObject* fsObj = getRawData(row); if (fsObj && !fsObj->isEmpty<RIGHT_SIDE>()) - return fsObj->getFullName<RIGHT_SIDE>(); + { + //Optimization: if filename exists on both sides, always use left side's file: + //Icon should be the same on both sides anyway... + if (!fsObj->isEmpty<LEFT_SIDE>()) + return fsObj->getFullName<LEFT_SIDE>(); + else + return fsObj->getFullName<RIGHT_SIDE>(); + } else return Zstring(); } @@ -511,6 +518,9 @@ void CustomGrid::initSettings(CustomGridLeft* gridLeft, GetGridWindow()->Connect(wxEVT_RIGHT_DOWN, wxEventHandler(CustomGrid::onGridAccess), NULL, this); GetGridWindow()->Connect(wxEVT_ENTER_WINDOW, wxEventHandler(CustomGrid::adjustGridHeights), NULL, this); + + //parallel grid scrolling: do NOT use DoPrepareDC() to align grids! GDI resource leak! Use regular paint event instead: + GetGridWindow()->Connect(wxEVT_PAINT, wxEventHandler(CustomGrid::OnPaintGrid), NULL, this); } @@ -530,12 +540,11 @@ void CustomGrid::RefreshCell(int row, int col) } -void CustomGrid::DoPrepareDC(wxDC& dc) +void CustomGrid::OnPaintGrid(wxEvent& event) { - wxScrollHelper::DoPrepareDC(dc); - if (isLeadGrid()) //avoid back coupling alignOtherGrids(m_gridLeft, m_gridMiddle, m_gridRight); //scroll other grids + event.Skip(); } @@ -652,7 +661,11 @@ void execGridCommands(wxEvent& event, wxGrid* grid) } } - else //button without shift is pressed + else if (keyEvent->AltDown()) + ; + else if (keyEvent->ControlDown()) + ; + else //button without additonal control keys pressed { switch (keyEvent->GetKeyCode()) { @@ -746,7 +759,7 @@ bool gridsShouldBeCleared(const wxEvent& event) const wxKeyEvent* keyEvent = dynamic_cast<const wxKeyEvent*>(&event); if (keyEvent) { - if (keyEvent->ControlDown() || keyEvent->ShiftDown()) + if (keyEvent->ControlDown() || keyEvent->AltDown() || keyEvent->ShiftDown()) return false; switch (keyEvent->GetKeyCode()) @@ -964,7 +977,7 @@ public: //try to draw icon //retrieve grid data - const Zstring fileName = m_gridDataTable->getFileName(row); + const Zstring fileName = m_gridDataTable->getIconFile(row); if (!fileName.empty()) { wxIcon icon; @@ -1347,7 +1360,7 @@ void CustomGridRim::getIconsToBeLoaded(std::vector<Zstring>& newLoad) //loads al LoadSuccess::const_iterator j = loadIconSuccess.find(currentRow); if (j != loadIconSuccess.end() && j->second == false) //find failed attempts to load icon { - const Zstring fileName = gridDataTable->getFileName(currentRow); + const Zstring fileName = gridDataTable->getIconFile(currentRow); if (!fileName.empty()) { //test if they are already loaded in buffer: @@ -1446,6 +1459,7 @@ void CustomGridLeft::alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddl int x = 0; int y = 0; GetViewStart(&x, &y); + gridMiddle->Scroll(-1, y); //scroll in y-direction only gridRight->Scroll(x, y); } diff --git a/library/CustomGrid.h b/library/CustomGrid.h index d5db71a1..2b78a6c3 100644 --- a/library/CustomGrid.h +++ b/library/CustomGrid.h @@ -83,8 +83,8 @@ protected: private: virtual void setGridDataTable(const FreeFileSync::GridView* gridDataView) = 0; -//this method is called when grid view changes: useful for parallel updating of multiple grids - virtual void DoPrepareDC(wxDC& dc); + //this method is called when grid view changes: useful for parallel updating of multiple grids + void OnPaintGrid(wxEvent& event); virtual void alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight) = 0; diff --git a/library/ShadowCopy/ShadowDll.vcproj b/library/ShadowCopy/ShadowDll.vcproj deleted file mode 100644 index 637aad0c..00000000 --- a/library/ShadowCopy/ShadowDll.vcproj +++ /dev/null @@ -1,219 +0,0 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="9,00" - Name="ShadowDll" - ProjectGUID="{70394AEF-5897-4911-AFA1-82EAF0581EFA}" - RootNamespace="ShadowDll" - Keyword="Win32Proj" - TargetFrameworkVersion="196613" - > - <Platforms> - <Platform - Name="Win32" - /> - </Platforms> - <ToolFiles> - </ToolFiles> - <Configurations> - <Configuration - Name="Debug|Win32" - OutputDirectory="obj\$(SolutionDir)$(ConfigurationName)" - IntermediateDirectory="obj\$(ConfigurationName)" - ConfigurationType="2" - CharacterSet="1" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - Optimization="0" - PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS" - MinimalRebuild="true" - BasicRuntimeChecks="3" - RuntimeLibrary="3" - UsePrecompiledHeader="0" - WarningLevel="3" - DebugInformationFormat="4" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - OutputFile="Shadow.dll" - LinkIncremental="2" - GenerateDebugInformation="true" - SubSystem="2" - TargetMachine="1" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - <Configuration - Name="Release|Win32" - OutputDirectory="obj\$(ConfigurationName)" - IntermediateDirectory="obj\$(ConfigurationName)" - ConfigurationType="2" - CharacterSet="1" - WholeProgramOptimization="1" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - Optimization="2" - EnableIntrinsicFunctions="true" - PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS" - RuntimeLibrary="2" - EnableFunctionLevelLinking="true" - UsePrecompiledHeader="0" - WarningLevel="3" - DebugInformationFormat="3" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - OutputFile="Shadow.dll" - LinkIncremental="1" - GenerateDebugInformation="true" - SubSystem="2" - OptimizeReferences="2" - EnableCOMDATFolding="2" - TargetMachine="1" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - </Configurations> - <References> - </References> - <Files> - <Filter - Name="Quelldateien" - Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" - UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" - > - <File - RelativePath=".\dllmain.cpp" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - UsePrecompiledHeader="0" - CompileAsManaged="0" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - UsePrecompiledHeader="0" - CompileAsManaged="0" - /> - </FileConfiguration> - </File> - <File - RelativePath=".\shadow.cpp" - > - </File> - </Filter> - <Filter - Name="Headerdateien" - Filter="h;hpp;hxx;hm;inl;inc;xsd" - UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" - > - <File - RelativePath=".\shadow.h" - > - </File> - </Filter> - <File - RelativePath=".\lib\vssapi.lib" - > - </File> - </Files> - <Globals> - </Globals> -</VisualStudioProject> diff --git a/library/ShadowCopy/Shadow_2003.vcproj b/library/ShadowCopy/Shadow_2003.vcproj new file mode 100644 index 00000000..560deb8d --- /dev/null +++ b/library/ShadowCopy/Shadow_2003.vcproj @@ -0,0 +1,413 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="Server2003" + ProjectGUID="{2F2994D6-FB89-4BAA-A5DF-03BAF7337FF2}" + RootNamespace="ShadowDll" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\" + IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\" + ConfigurationType="2" + CharacterSet="1" + BuildLogFile="$(IntDir)\Build.html" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + SuppressStartupBanner="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="Shadow_$(ProjectName)_$(PlatformName).dll" + LinkIncremental="1" + SuppressStartupBanner="false" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(IntDir)$(TargetName).pdb" + SubSystem="2" + ProfileGuidedDatabase="" + ImportLibrary="$(IntDir)$(TargetName).lib" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\" + IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\" + ConfigurationType="2" + CharacterSet="1" + BuildLogFile="$(IntDir)\Build.html" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + SuppressStartupBanner="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="Shadow_$(ProjectName)_$(PlatformName).dll" + LinkIncremental="1" + SuppressStartupBanner="false" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(IntDir)$(TargetName).pdb" + SubSystem="2" + ProfileGuidedDatabase="" + ImportLibrary="$(IntDir)$(TargetName).lib" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\" + IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\" + ConfigurationType="2" + CharacterSet="1" + WholeProgramOptimization="1" + BuildLogFile="$(IntDir)\Build.html" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + PreprocessorDefinitions="NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + SuppressStartupBanner="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="Shadow_$(ProjectName)_$(PlatformName).dll" + LinkIncremental="1" + SuppressStartupBanner="false" + GenerateDebugInformation="false" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" + ProfileGuidedDatabase="" + ImportLibrary="$(IntDir)$(TargetName).lib" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\" + IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\" + ConfigurationType="2" + CharacterSet="1" + WholeProgramOptimization="1" + BuildLogFile="$(IntDir)\Build.html" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + PreprocessorDefinitions="NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + SuppressStartupBanner="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="Shadow_$(ProjectName)_$(PlatformName).dll" + LinkIncremental="1" + SuppressStartupBanner="false" + GenerateDebugInformation="false" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" + ProfileGuidedDatabase="" + ImportLibrary="$(IntDir)$(TargetName).lib" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Quelldateien" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\dllmain.cpp" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="0" + CompileAsManaged="0" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|x64" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="0" + CompileAsManaged="0" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="0" + CompileAsManaged="0" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|x64" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="0" + CompileAsManaged="0" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\shadow.cpp" + > + </File> + </Filter> + <Filter + Name="Headerdateien" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\shadow.h" + > + </File> + </Filter> + <File + RelativePath=".\Server 2003\lib\$(PlatformName)\vssapi.lib" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/library/ShadowCopy/Shadow_XP.vcproj b/library/ShadowCopy/Shadow_XP.vcproj new file mode 100644 index 00000000..6c1cbaaa --- /dev/null +++ b/library/ShadowCopy/Shadow_XP.vcproj @@ -0,0 +1,413 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9,00" + Name="XP" + ProjectGUID="{70394AEF-5897-4911-AFA1-82EAF0581EFA}" + RootNamespace="ShadowDll" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\" + IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\" + ConfigurationType="2" + CharacterSet="1" + BuildLogFile="$(IntDir)\Build.html" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + SuppressStartupBanner="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="Shadow_$(ProjectName)_$(PlatformName).dll" + LinkIncremental="1" + SuppressStartupBanner="false" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(IntDir)$(TargetName).pdb" + SubSystem="2" + ProfileGuidedDatabase="" + ImportLibrary="$(IntDir)$(TargetName).lib" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\" + IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\" + ConfigurationType="2" + CharacterSet="1" + BuildLogFile="$(IntDir)\Build.html" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + SuppressStartupBanner="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="Shadow_$(ProjectName)_$(PlatformName).dll" + LinkIncremental="1" + SuppressStartupBanner="false" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(IntDir)$(TargetName).pdb" + SubSystem="2" + ProfileGuidedDatabase="" + ImportLibrary="$(IntDir)$(TargetName).lib" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\" + IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\" + ConfigurationType="2" + CharacterSet="1" + WholeProgramOptimization="1" + BuildLogFile="$(IntDir)\Build.html" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + PreprocessorDefinitions="NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + SuppressStartupBanner="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="Shadow_$(ProjectName)_$(PlatformName).dll" + LinkIncremental="1" + SuppressStartupBanner="false" + GenerateDebugInformation="false" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" + ProfileGuidedDatabase="" + ImportLibrary="$(IntDir)$(TargetName).lib" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\" + IntermediateDirectory="OBJ\$(ProjectName)_$(ConfigurationName)_$(PlatformName)\" + ConfigurationType="2" + CharacterSet="1" + WholeProgramOptimization="1" + BuildLogFile="$(IntDir)\Build.html" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + PreprocessorDefinitions="NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + SuppressStartupBanner="false" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="Shadow_$(ProjectName)_$(PlatformName).dll" + LinkIncremental="1" + SuppressStartupBanner="false" + GenerateDebugInformation="false" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + LinkTimeCodeGeneration="1" + ProfileGuidedDatabase="" + ImportLibrary="$(IntDir)$(TargetName).lib" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Quelldateien" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\dllmain.cpp" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="0" + CompileAsManaged="0" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug|x64" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="0" + CompileAsManaged="0" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="0" + CompileAsManaged="0" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|x64" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="0" + CompileAsManaged="0" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\shadow.cpp" + > + </File> + </Filter> + <Filter + Name="Headerdateien" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\shadow.h" + > + </File> + </Filter> + <File + RelativePath=".\XP\lib\$(PlatformName)\vssapi.lib" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/library/ShadowCopy/shadow.cpp b/library/ShadowCopy/shadow.cpp index edc62e8b..cbc4b085 100644 --- a/library/ShadowCopy/shadow.cpp +++ b/library/ShadowCopy/shadow.cpp @@ -2,9 +2,20 @@ #define WIN32_LEAN_AND_MEAN #include "windows.h" -#include "inc/vss.h" -#include "inc/vswriter.h" -#include "inc/vsbackup.h" + +#ifdef USE_SHADOW_XP +#include "xp/inc/vss.h" +#include "xp/inc/vswriter.h" +#include "xp/inc/vsbackup.h" + +#elif defined USE_SHADOW_2003 +#include "Server 2003/inc/vss.h" +#include "Server 2003/inc/vswriter.h" +#include "Server 2003/inc/vsbackup.h" +#else +adapt! +#endif + #include <algorithm> #include <string> #include <cstdio> @@ -15,7 +26,7 @@ void writeString(const wchar_t* input, wchar_t* output, unsigned int outputBufferLen) { - const unsigned int newSize = min(wcslen(input) + 1, outputBufferLen); //including null-termination + const size_t newSize = min(wcslen(input) + 1, outputBufferLen); //including null-termination memcpy(output, input, newSize * sizeof(wchar_t)); } @@ -73,10 +84,9 @@ bool shadow::createShadowCopy(const wchar_t* volumeName, IVssAsync* pWriteMetaData = NULL; if (FAILED(hr = pBackupComponents->GatherWriterMetadata( &pWriteMetaData ))) - { + { //this can happen if XP-version of VSS is used on Windows Vista (which needs at least VSS-Server2003 build) releaseShadowCopy(pBackupComponents); - writeErrorMsg(L"\"Shadow.dll\" might be incompatible with this Operating System!\n\ - Error calling \"GatherWriterMetadata\".", hr, errorMessage, errorBufferLen); + writeErrorMsg(L"Error calling \"GatherWriterMetadata\".", hr, errorMessage, errorBufferLen); return false; } diff --git a/library/filter.cpp b/library/filter.cpp index c2d972d4..6565da2e 100644 --- a/library/filter.cpp +++ b/library/filter.cpp @@ -2,14 +2,69 @@ #include "../shared/zstring.h" #include <wx/string.h> #include <set> +#include <stdexcept> #include <vector> #include "../shared/systemConstants.h" #include "../structures.h" #include <boost/bind.hpp> +#include "../shared/loki/LokiTypeInfo.h" +#include "../shared/serialize.h" using FreeFileSync::FilterProcess; +using FreeFileSync::NameFilter; +//-------------------------------------------------------------------------------------------------- +bool FilterProcess::operator==(const FilterProcess& other) const +{ + return !(*this < other) && !(other < *this); +} + + +bool FilterProcess::operator!=(const FilterProcess& other) const +{ + return !(*this == other); +} + + +bool FilterProcess::operator<(const FilterProcess& other) const +{ + if (Loki::TypeInfo(typeid(*this)) != typeid(other)) + return Loki::TypeInfo(typeid(*this)) < typeid(other); + + //this and other are same type: + return cmpLessSameType(other); +} + + +void FilterProcess::saveFilter(wxOutputStream& stream) const //serialize derived object +{ + //save type information + Utility::writeString(stream, uniqueClassIdentifier()); + + //save actual object + save(stream); +} + + +FilterProcess::FilterRef FilterProcess::loadFilter(wxInputStream& stream) +{ + //read type information + const Zstring uniqueClassId = Utility::readString(stream); + + //read actual object + if (uniqueClassId == DefaultStr("NullFilter")) + return NullFilter::load(stream); + else if (uniqueClassId == DefaultStr("NameFilter")) + return NameFilter::load(stream); + else if (uniqueClassId == DefaultStr("CombinedFilter")) + return CombinedFilter::load(stream); + else + throw std::logic_error("Programming Error: Unknown filter!"); +} + + +//-------------------------------------------------------------------------------------------------- inline void addFilterEntry(const Zstring& filtername, std::set<Zstring>& fileFilter, std::set<Zstring>& directoryFilter) { @@ -149,10 +204,11 @@ std::vector<Zstring> compoundStringToFilter(const Zstring& filterString) return output; } -//############################################################## - -FilterProcess::FilterProcess(const Zstring& includeFilter, const Zstring& excludeFilter) +//################################################################################################# +NameFilter::NameFilter(const Zstring& includeFilter, const Zstring& excludeFilter) : + includeFilterTmp(includeFilter), //save constructor arguments for serialization + excludeFilterTmp(excludeFilter) { //no need for regular expressions! In tests wxRegex was by factor of 10 slower than wxString::Matches()!! @@ -167,15 +223,17 @@ FilterProcess::FilterProcess(const Zstring& includeFilter, const Zstring& exclud } -bool FilterProcess::passFileFilter(const DefaultChar* relFilename) const +bool NameFilter::passFileFilter(const DefaultChar* relFilename) const { return matchesFilter(relFilename, filterFileIn) && //process include filters !matchesFilter(relFilename, filterFileEx); //process exclude filters } -bool FilterProcess::passDirFilter(const DefaultChar* relDirname, bool* subObjMightMatch) const +bool NameFilter::passDirFilter(const DefaultChar* relDirname, bool* subObjMightMatch) const { + assert(subObjMightMatch == NULL || *subObjMightMatch == true); //check correct usage + if (matchesFilter(relDirname, filterFolderEx)) //process exclude filters { if (subObjMightMatch) @@ -196,147 +254,56 @@ bool FilterProcess::passDirFilter(const DefaultChar* relDirname, bool* subObjMig return false; } - assert(subObjMightMatch == NULL || *subObjMightMatch == true); return true; } -template <bool include> -class InOrExcludeAllRows +bool NameFilter::isNull() const { -public: - void operator()(FreeFileSync::BaseDirMapping& baseDirectory) const //be careful with operator() to no get called by std::for_each! - { - execute(baseDirectory); - } - - void execute(FreeFileSync::HierarchyObject& hierObj) const //don't create ambiguity by replacing with operator() - { - std::for_each(hierObj.subFiles.begin(), hierObj.subFiles.end(), *this); //files - std::for_each(hierObj.subDirs.begin(), hierObj.subDirs.end(), *this); //directories - } - -private: - template<typename Iterator, typename Function> - friend Function std::for_each(Iterator, Iterator, Function); - - void operator()(FreeFileSync::FileMapping& fileObj) const - { - fileObj.setActive(include); - } - - void operator()(FreeFileSync::DirMapping& dirObj) const - { - dirObj.setActive(include); - execute(dirObj); //recursion - } -}; - - -class FilterData -{ -public: - FilterData(const FilterProcess& filterProcIn) : filterProc(filterProcIn) {} - - void execute(FreeFileSync::HierarchyObject& hierObj) - { - //files - std::for_each(hierObj.subFiles.begin(), hierObj.subFiles.end(), *this); - - //directories - std::for_each(hierObj.subDirs.begin(), hierObj.subDirs.end(), *this); - }; - -private: - template<typename Iterator, typename Function> - friend Function std::for_each(Iterator, Iterator, Function); - - - void operator()(FreeFileSync::FileMapping& fileObj) - { - fileObj.setActive(filterProc.passFileFilter(fileObj.getObjRelativeName())); - } - - void operator()(FreeFileSync::DirMapping& dirObj) - { - bool subObjMightMatch = true; - dirObj.setActive(filterProc.passDirFilter(dirObj.getObjRelativeName(), &subObjMightMatch)); - - if (subObjMightMatch) //use same logic as within directory traversing here: evaluate filter in subdirs only if objects could match - execute(dirObj); //recursion - else - InOrExcludeAllRows<false>().execute(dirObj); //exclude all files dirs in subfolders - } - - const FilterProcess& filterProc; -}; - - -void FilterProcess::filterAll(FreeFileSync::HierarchyObject& baseDirectory) const -{ - FilterData(*this).execute(baseDirectory); + static NameFilter output(DefaultStr("*"), Zstring()); + return *this == output; } -void FilterProcess::setActiveStatus(bool newStatus, FreeFileSync::FolderComparison& folderCmp) +bool NameFilter::cmpLessSameType(const FilterProcess& other) const { - if (newStatus) - std::for_each(folderCmp.begin(), folderCmp.end(), InOrExcludeAllRows<true>()); //include all rows - else - std::for_each(folderCmp.begin(), folderCmp.end(), InOrExcludeAllRows<false>()); //exclude all rows -} + //typeid(*this) == typeid(other) in this context! + assert(typeid(*this) == typeid(other)); + const NameFilter& otherNameFilt = static_cast<const NameFilter&>(other); + if (filterFileIn != otherNameFilt.filterFileIn) + return filterFileIn < otherNameFilt.filterFileIn; -void FilterProcess::setActiveStatus(bool newStatus, FreeFileSync::FileSystemObject& fsObj) -{ - fsObj.setActive(newStatus); + if (filterFolderIn != otherNameFilt.filterFolderIn) + return filterFolderIn < otherNameFilt.filterFolderIn; - DirMapping* dirObj = dynamic_cast<DirMapping*>(&fsObj); - if (dirObj) //process subdirectories also! - { - if (newStatus) - InOrExcludeAllRows<true>().execute(*dirObj); - else - InOrExcludeAllRows<false>().execute(*dirObj); - } -} + if (filterFileEx != otherNameFilt.filterFileEx) + return filterFileEx < otherNameFilt.filterFileEx; + if (filterFolderEx != otherNameFilt.filterFolderEx) + return filterFolderEx < otherNameFilt.filterFolderEx; -const FilterProcess& FilterProcess::nullFilter() //filter equivalent to include '*', exclude '' -{ - static FilterProcess output(DefaultStr("*"), Zstring()); - return output; + return false; //vectors equal } -bool FilterProcess::operator==(const FilterProcess& other) const +Zstring NameFilter::uniqueClassIdentifier() const { - return filterFileIn == other.filterFileIn && - filterFolderIn == other.filterFolderIn && - filterFileEx == other.filterFileEx && - filterFolderEx == other.filterFolderEx; + return DefaultStr("NameFilter"); } -bool FilterProcess::operator!=(const FilterProcess& other) const +void NameFilter::save(wxOutputStream& stream) const { - return !(*this == other); + Utility::writeString(stream, includeFilterTmp); + Utility::writeString(stream, excludeFilterTmp); } -bool FilterProcess::operator<(const FilterProcess& other) const +FilterProcess::FilterRef NameFilter::load(wxInputStream& stream) //"constructor" { - if (filterFileIn != other.filterFileIn) - return filterFileIn < other.filterFileIn; - - if (filterFolderIn != other.filterFolderIn) - return filterFolderIn < other.filterFolderIn; - - if (filterFileEx != other.filterFileEx) - return filterFileEx < other.filterFileEx; + const Zstring include = Utility::readString(stream); + const Zstring exclude = Utility::readString(stream); - if (filterFolderEx != other.filterFolderEx) - return filterFolderEx < other.filterFolderEx; - - return false; //vectors equal + return FilterRef(new NameFilter(include, exclude)); } diff --git a/library/filter.h b/library/filter.h index 45aff69b..efdb01fd 100644 --- a/library/filter.h +++ b/library/filter.h @@ -3,36 +3,264 @@ #include "../shared/zstring.h" #include <set> -#include "../fileHierarchy.h" - +#include <boost/shared_ptr.hpp> +#include <wx/stream.h> namespace FreeFileSync { -class FilterProcess //relative filtering +//------------------------------------------------------------------ +/* class hierarchy: + + FilterProcess (interface) + /|\ + _________|_____________ + | | | +NullFilter NameFilter CombinedFilter +*/ + +class FilterProcess //interface for filtering { public: - FilterProcess(const Zstring& includeFilter, const Zstring& excludeFilter); + virtual ~FilterProcess() {} - bool passFileFilter(const DefaultChar* relFilename) const; - bool passDirFilter(const DefaultChar* relDirname, bool* subObjMightMatch) const; //subObjMightMatch: file/dir in subdirectories could(!) match + //filtering + virtual bool passFileFilter(const DefaultChar* relFilename) const = 0; + virtual bool passDirFilter(const DefaultChar* relDirname, bool* subObjMightMatch) const = 0; + //subObjMightMatch: file/dir in subdirectories could(!) match //note: variable is only set if passDirFilter returns false! - void filterAll(HierarchyObject& baseDirectory) const; //filter complete data: files and dirs - static void setActiveStatus(bool newStatus, FolderComparison& folderCmp); //activate or deactivate all rows - static void setActiveStatus(bool newStatus, FileSystemObject& fsObj); //activate or deactivate row: works recursively! + virtual bool isNull() const = 0; //filter is equivalent to NullFilter, but may be technically slower - static const FilterProcess& nullFilter(); //filter equivalent to include '*', exclude '' + //comparison + bool operator<(const FilterProcess& other) const; bool operator==(const FilterProcess& other) const; bool operator!=(const FilterProcess& other) const; - bool operator<(const FilterProcess& other) const; + + typedef boost::shared_ptr<const FilterProcess> FilterRef; //always bound by design! + + //serialization + void saveFilter(wxOutputStream& stream) const; //serialize derived object + static FilterRef loadFilter(wxInputStream& stream); //CAVEAT!!! adapt this method for each new derivation!!! + +private: + virtual Zstring uniqueClassIdentifier() const = 0; //get identifier, used for serialization + virtual void save(wxOutputStream& stream) const = 0; //serialization + virtual bool cmpLessSameType(const FilterProcess& other) const = 0; //typeid(*this) == typeid(other) in this context! +}; + + +class NullFilter : public FilterProcess //no filtering at all +{ +public: + static FilterRef load(wxInputStream& stream); //"serial constructor" + virtual bool passFileFilter(const DefaultChar* relFilename) const; + virtual bool passDirFilter(const DefaultChar* relDirname, bool* subObjMightMatch) const; + virtual bool isNull() const; + +private: + virtual Zstring uniqueClassIdentifier() const; + virtual void save(wxOutputStream& stream) const {} + virtual bool cmpLessSameType(const FilterProcess& other) const; +}; + + +class NameFilter : public FilterProcess //standard filter by filename +{ +public: + NameFilter(const Zstring& includeFilter, const Zstring& excludeFilter); + static FilterRef load(wxInputStream& stream); //"serial constructor" + + virtual bool passFileFilter(const DefaultChar* relFilename) const; + virtual bool passDirFilter(const DefaultChar* relDirname, bool* subObjMightMatch) const; + virtual bool isNull() const; private: + virtual Zstring uniqueClassIdentifier() const; + virtual void save(wxOutputStream& stream) const; + virtual bool cmpLessSameType(const FilterProcess& other) const; + std::set<Zstring> filterFileIn; std::set<Zstring> filterFolderIn; std::set<Zstring> filterFileEx; std::set<Zstring> filterFolderEx; + + const Zstring includeFilterTmp; //save constructor arguments for serialization + const Zstring excludeFilterTmp; // +}; + + +class CombinedFilter : public FilterProcess //combine two filters to match if and only if both match +{ +public: + CombinedFilter(const FilterRef& first, const FilterRef& second) : first_(first), second_(second) {} + static FilterRef load(wxInputStream& stream); //"serial constructor" + + virtual bool passFileFilter(const DefaultChar* relFilename) const; + virtual bool passDirFilter(const DefaultChar* relDirname, bool* subObjMightMatch) const; + virtual bool isNull() const; + +private: + virtual Zstring uniqueClassIdentifier() const; + virtual void save(wxOutputStream& stream) const; + virtual bool cmpLessSameType(const FilterProcess& other) const; + + const FilterRef first_; + const FilterRef second_; }; + + +//small helper method: remove Null-filters +FilterProcess::FilterRef combineFilters(const FilterProcess::FilterRef& first, + const FilterProcess::FilterRef& second); + + + + + + + + + + + + + + + + + + +//---------------Inline Implementation--------------------------------------------------- +inline +FilterProcess::FilterRef NullFilter::load(wxInputStream& stream) //"serial constructor" +{ + return FilterRef(new NullFilter); +} + + +inline +bool NullFilter::passFileFilter(const DefaultChar* relFilename) const +{ + return true; +} + + +inline +bool NullFilter::passDirFilter(const DefaultChar* relDirname, bool* subObjMightMatch) const +{ + assert(subObjMightMatch == NULL || *subObjMightMatch == true); //check correct usage + return true; +} + + +inline +bool NullFilter::isNull() const +{ + return true; +} + + +inline +bool NullFilter::cmpLessSameType(const FilterProcess& other) const +{ + //typeid(*this) == typeid(other) in this context! + assert(typeid(*this) == typeid(other)); + return false; +} + + +inline +Zstring NullFilter::uniqueClassIdentifier() const +{ + return DefaultStr("NullFilter"); +} + + +inline +bool CombinedFilter::passFileFilter(const DefaultChar* relFilename) const +{ + return first_->passFileFilter(relFilename) && //short-circuit behavior + second_->passFileFilter(relFilename); +} + + +inline +bool CombinedFilter::passDirFilter(const DefaultChar* relDirname, bool* subObjMightMatch) const +{ + return first_->passDirFilter(relDirname, subObjMightMatch) && //short-circuit behavior: subObjMightMatch handled correctly! + second_->passDirFilter(relDirname, subObjMightMatch); +} + + +inline +bool CombinedFilter::isNull() const +{ + return first_->isNull() && second_->isNull(); +} + + +inline +bool CombinedFilter::cmpLessSameType(const FilterProcess& other) const +{ + //typeid(*this) == typeid(other) in this context! + assert(typeid(*this) == typeid(other)); + const CombinedFilter& otherCombFilt = static_cast<const CombinedFilter&>(other); + + if (*first_ != *otherCombFilt.first_) + return *first_ < *otherCombFilt.first_; + + return *second_ < *otherCombFilt.second_; +} + + +inline +Zstring CombinedFilter::uniqueClassIdentifier() const +{ + return DefaultStr("CombinedFilter"); +} + + +inline +void CombinedFilter::save(wxOutputStream& stream) const +{ + first_->saveFilter(stream); + second_->saveFilter(stream); +} + + +inline +FilterProcess::FilterRef CombinedFilter::load(wxInputStream& stream) //"constructor" +{ + FilterRef first = loadFilter(stream); + FilterRef second = loadFilter(stream); + + return combineFilters(first, second); +} + + +inline +FilterProcess::FilterRef combineFilters(const FilterProcess::FilterRef& first, + const FilterProcess::FilterRef& second) +{ + if (first->isNull()) + { + if (second->isNull()) + return FilterProcess::FilterRef(new NullFilter); + else + return second; + } + else + { + if (second->isNull()) + return first; + else + return FilterProcess::FilterRef(new CombinedFilter(first, second)); + } +} + + } #endif // FFS_FILTER_H_INCLUDED + diff --git a/library/iconBuffer.cpp b/library/iconBuffer.cpp index 2f1e2915..d386c85a 100644 --- a/library/iconBuffer.cpp +++ b/library/iconBuffer.cpp @@ -143,14 +143,14 @@ void WorkerThread::doWork() break; //icon already in buffer: enter waiting state //despite what docu says about SHGetFileInfo() it can't handle all relative filenames, e.g. "\DirName" - const unsigned int BUFFER_SIZE = 10000; - DefaultChar fullName[BUFFER_SIZE]; + const unsigned int MAX_SIZE = 10000; + DefaultChar fullName[MAX_SIZE]; const DWORD rv = ::GetFullPathName( &fileName[0], //__in LPCTSTR lpFileName, - BUFFER_SIZE, //__in DWORD nBufferLength, + MAX_SIZE, //__in DWORD nBufferLength, fullName, //__out LPTSTR lpBuffer, NULL); //__out LPTSTR *lpFilePart - if (rv < BUFFER_SIZE && rv != 0) + if (rv < MAX_SIZE && rv != 0) { //load icon SHFILEINFO fileInfo; @@ -251,7 +251,7 @@ void IconBuffer::insertIntoBuffer(const DefaultChar* fileName, const wxIcon& ico assert(buffer->size() == bufSequence->size()); //remove elements if buffer becomes too big: - if (buffer->size() > 1000) //limit buffer size: critical because large buffers seem to cause various wxIcon/wxBitmap issues! + if (buffer->size() > BUFFER_SIZE) //limit buffer size: critical because GDI resources are limited (e.g. 10000 on XP per process) { //remove oldest element buffer->erase(bufSequence->front()); diff --git a/library/iconBuffer.h b/library/iconBuffer.h index 0604060e..e6d2bcaf 100644 --- a/library/iconBuffer.h +++ b/library/iconBuffer.h @@ -28,7 +28,8 @@ public: bool requestIcon(const Zstring& fileName, wxIcon* icon = NULL); //returns false if icon is not in buffer void setWorkload(const std::vector<Zstring>& load); //(re-)set new workload of icons to be retrieved; - static const int ICON_SIZE = 16; //size in pixel + static const int ICON_SIZE = 16; //size in pixel + static const size_t BUFFER_SIZE = 800; //maximum number if icons to buffer private: IconBuffer(); diff --git a/library/pch.h b/library/pch.h index 966bc103..af086418 100644 --- a/library/pch.h +++ b/library/pch.h @@ -85,6 +85,7 @@ do NOT use in release build! #include <wx/zipstrm.h> #include <wx/scrolwin.h> #include <wx/notebook.h> +#include <wx/help.h> //other #include "../shared/tinyxml/tinyxml.h" diff --git a/library/processXml.cpp b/library/processXml.cpp index b248cf62..af16f91e 100644 --- a/library/processXml.cpp +++ b/library/processXml.cpp @@ -29,7 +29,7 @@ public: private: //read alternate configuration (optional) => might point to NULL - void readXmlAlternateConfig(const TiXmlElement& folderPair, FolderPairEnh& enhPair); + void readXmlLocalConfig(const TiXmlElement& folderPair, FolderPairEnh& enhPair); //read basic FreefileSync settings (used by commandline and GUI), return true if ALL values have been retrieved successfully void readXmlMainConfig(MainConfiguration& mainCfg); @@ -43,7 +43,7 @@ bool writeXmlBatchConfig(const xmlAccess::XmlBatchConfig& outputCfg, TiXmlDocume //write global settings bool writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings& outputCfg, TiXmlDocument& doc); //write alternate configuration (optional) => might point to NULL -void writeXmlAlternateConfig(const FolderPairEnh& enhPair, TiXmlElement& parent); +void writeXmlLocalConfig(const FolderPairEnh& enhPair, TiXmlElement& parent); //write basic FreefileSync settings (used by commandline and GUI), return true if everything was written successfully bool writeXmlMainConfig(const MainConfiguration& mainCfg, TiXmlDocument& doc); @@ -247,7 +247,7 @@ bool readXmlAttribute(const std::string& name, const TiXmlElement* node, xmlAcce //################################################################################################################ -void FfsXmlParser::readXmlAlternateConfig(const TiXmlElement& folderPair, FolderPairEnh& enhPair) +void FfsXmlParser::readXmlLocalConfig(const TiXmlElement& folderPair, FolderPairEnh& enhPair) { //read folder pairs readXmlElementLogging("Left", &folderPair, enhPair.leftDirectory); @@ -281,15 +281,12 @@ void FfsXmlParser::readXmlAlternateConfig(const TiXmlElement& folderPair, Folder //########################################################### //alternate filter configuration - const TiXmlElement* filterCfg = TiXmlHandleConst(&folderPair).FirstChild("AlternateFilter").ToElement(); + const TiXmlElement* filterCfg = TiXmlHandleConst(&folderPair).FirstChild("LocalFilter").ToElement(); if (filterCfg) { - AlternateFilter* altFilterCfg = new AlternateFilter; - enhPair.altFilter.reset(altFilterCfg); - //read filter settings - readXmlElementLogging("Include", filterCfg, altFilterCfg->includeFilter); - readXmlElementLogging("Exclude", filterCfg, altFilterCfg->excludeFilter); + readXmlElementLogging("Include", filterCfg, enhPair.localFilter.includeFilter); + readXmlElementLogging("Exclude", filterCfg, enhPair.localFilter.excludeFilter); } } @@ -349,24 +346,21 @@ void FfsXmlParser::readXmlMainConfig(MainConfiguration& mainCfg) //########################################################### const TiXmlElement* pairs = hRoot.FirstChild("MainConfig").FirstChild("FolderPairs").FirstChild("Pair").ToElement(); - //read main folder pair - if (pairs) - { - readXmlElementLogging("Left", pairs, mainCfg.mainFolderPair.leftDirectory); - readXmlElementLogging("Right", pairs, mainCfg.mainFolderPair.rightDirectory); - pairs = pairs->NextSiblingElement(); - } - else - logError("Pair"); - - - //read additional folder pairs + //read all folder pairs mainCfg.additionalPairs.clear(); + bool firstLoop = true; while (pairs) { FolderPairEnh newPair; - readXmlAlternateConfig(*pairs, newPair); - mainCfg.additionalPairs.push_back(newPair); + readXmlLocalConfig(*pairs, newPair); + + if (firstLoop) //read first folder pair + { + firstLoop = false; + mainCfg.firstPair = newPair; + } + else //read additional folder pairs + mainCfg.additionalPairs.push_back(newPair); pairs = pairs->NextSiblingElement(); } @@ -416,6 +410,9 @@ void FfsXmlParser::readXmlGlobalSettings(xmlAccess::XmlGlobalSettings& outputCfg //ignore +/- 1 hour due to DST change readXmlElementLogging("IgnoreOneHourDifference", global, outputCfg.ignoreOneHourDiff); + //copy locked files using VSS + readXmlElementLogging("CopyLockedFiles", global, outputCfg.copyLockedFiles); + //last update check readXmlElementLogging("LastCheckForUpdates", global, outputCfg.lastUpdateCheck); @@ -617,7 +614,7 @@ void addXmlAttribute(const std::string& name, const xmlAccess::ColumnTypes value } -void writeXmlAlternateConfig(const FolderPairEnh& enhPair, TiXmlElement& parent) +void writeXmlLocalConfig(const FolderPairEnh& enhPair, TiXmlElement& parent) { //write folder pairs TiXmlElement* newfolderPair = new TiXmlElement("Pair"); @@ -661,16 +658,12 @@ void writeXmlAlternateConfig(const FolderPairEnh& enhPair, TiXmlElement& parent) //########################################################### //alternate filter configuration - const AlternateFilter* altFilter = enhPair.altFilter.get(); - if (altFilter) - { - TiXmlElement* filterCfg = new TiXmlElement("AlternateFilter"); - newfolderPair->LinkEndChild(filterCfg); + TiXmlElement* filterCfg = new TiXmlElement("LocalFilter"); + newfolderPair->LinkEndChild(filterCfg); - //write filter settings - addXmlElement("Include", altFilter->includeFilter, filterCfg); - addXmlElement("Exclude", altFilter->excludeFilter, filterCfg); - } + //write filter settings + addXmlElement("Include", enhPair.localFilter.includeFilter, filterCfg); + addXmlElement("Exclude", enhPair.localFilter.excludeFilter, filterCfg); } @@ -744,16 +737,12 @@ bool writeXmlMainConfig(const MainConfiguration& mainCfg, TiXmlDocument& doc) TiXmlElement* pairs = new TiXmlElement("FolderPairs"); settings->LinkEndChild(pairs); - //write main folder pair - TiXmlElement* mainPair = new TiXmlElement("Pair"); - pairs->LinkEndChild(mainPair); - - addXmlElement("Left", mainCfgLocal.mainFolderPair.leftDirectory, mainPair); - addXmlElement("Right", mainCfgLocal.mainFolderPair.rightDirectory, mainPair); + //write first folder pair + writeXmlLocalConfig(mainCfgLocal.firstPair, *pairs); //write additional folder pairs for (std::vector<FolderPairEnh>::const_iterator i = mainCfgLocal.additionalPairs.begin(); i != mainCfgLocal.additionalPairs.end(); ++i) - writeXmlAlternateConfig(*i, *pairs); + writeXmlLocalConfig(*i, *pairs); return true; } @@ -819,6 +808,9 @@ bool writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings& inputCfg, TiXmlD //ignore +/- 1 hour due to DST change addXmlElement("IgnoreOneHourDifference", inputCfg.ignoreOneHourDiff, global); + //copy locked files using VSS + addXmlElement("CopyLockedFiles", inputCfg.copyLockedFiles, global); + //last update check addXmlElement("LastCheckForUpdates", inputCfg.lastUpdateCheck, global); diff --git a/library/processXml.h b/library/processXml.h index aafd3131..80db71a3 100644 --- a/library/processXml.h +++ b/library/processXml.h @@ -108,10 +108,12 @@ struct XmlGlobalSettings XmlGlobalSettings() : programLanguage(retrieveSystemLanguage()), ignoreOneHourDiff(false), + copyLockedFiles(true), lastUpdateCheck(0) {} int programLanguage; bool ignoreOneHourDiff; //ignore +/- 1 hour due to DST change + bool copyLockedFiles; //VSS usage long lastUpdateCheck; //time of last update check OptionalDialogs optDialogs; @@ -137,7 +139,7 @@ struct XmlGlobalSettings showFileIconsRight(true) { #ifdef FFS_WIN - externelApplications.push_back(std::make_pair(_("Open with Explorer"), wxT("explorer /select, %name"))); + externelApplications.push_back(std::make_pair(_("Open with Explorer"), wxT("explorer /select, \"%name\""))); externelApplications.push_back(std::make_pair(_("Open directly"), wxT("cmd /c start \"\" \"%name\""))); #elif defined FFS_LINUX externelApplications.push_back(std::make_pair(_("Open with Konqueror"), wxT("konqueror \"%dir\""))); diff --git a/library/resources.cpp b/library/resources.cpp index a42f2788..02f5d701 100644 --- a/library/resources.cpp +++ b/library/resources.cpp @@ -22,6 +22,8 @@ const GlobalResources& GlobalResources::getInstance() GlobalResources::GlobalResources() { //map, allocate and initialize pictures + bitmapResource[wxT("CmpByTime.png")] = (bitmapCmpByTime = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("CmpByContent.png")] = (bitmapCmpByContent = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("left arrow.png")] = (bitmapArrowLeft = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("right arrow.png")] = (bitmapArrowRight = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("left arrow create.png")] = (bitmapArrowLeftCr = new wxBitmap(wxNullBitmap)); @@ -41,7 +43,7 @@ GlobalResources::GlobalResources() bitmapResource[wxT("sync.png")] = (bitmapSync = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("sync disabled.png")] = (bitmapSyncDisabled = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("swap.png")] = (bitmapSwap = new wxBitmap(wxNullBitmap)); - bitmapResource[wxT("swapSmall.png")] = (bitmapSwapSmall = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("swap_slim.png")] = (bitmapSwapSlim = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("help.png")] = (bitmapHelp = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("leftOnly.png")] = (bitmapLeftOnly = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("leftOnlyAct.png")] = (bitmapLeftOnlyAct = new wxBitmap(wxNullBitmap)); @@ -81,8 +83,7 @@ GlobalResources::GlobalResources() bitmapResource[wxT("saveSmall.png")] = (bitmapSaveSmall = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("loadSmall.png")] = (bitmapLoadSmall = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("newSmall.png")] = (bitmapNewSmall = new wxBitmap(wxNullBitmap)); - bitmapResource[wxT("FFS.png")] = (bitmapFFS = new wxBitmap(wxNullBitmap)); - bitmapResource[wxT("FFS paused.png")] = (bitmapFFSPaused = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("FreeFileSync.png")] = (bitmapFFS = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("deleteFile.png")] = (bitmapDeleteFile = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("gpl.png")] = (bitmapGPL = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("statusPause.png")] = (bitmapStatusPause = new wxBitmap(wxNullBitmap)); @@ -103,7 +104,6 @@ GlobalResources::GlobalResources() bitmapResource[wxT("sync_small.png")] = (bitmapSyncSmall = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("clock_small.png")] = (bitmapClockSmall = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("clock.png")] = (bitmapClock = new wxBitmap(wxNullBitmap)); - bitmapResource[wxT("filter.png")] = (bitmapFilter = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("batch.png")] = (bitmapBatch = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("batch_small.png")] = (bitmapBatchSmall = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("move up.png")] = (bitmapMoveUp = new wxBitmap(wxNullBitmap)); @@ -128,6 +128,7 @@ GlobalResources::GlobalResources() bitmapResource[wxT("holland.png")] = (bitmapHolland = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("england.png")] = (bitmapEngland = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("france.png")] = (bitmapFrance = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("finland.png")] = (bitmapFinland = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("germany.png")] = (bitmapGermany = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("hungary.png")] = (bitmapHungary = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("romania.png")] = (bitmapRomania = new wxBitmap(wxNullBitmap)); @@ -218,7 +219,7 @@ void loadAnimFromZip(wxZipInputStream& zipInput, wxAnimation* animation) void GlobalResources::load() const { - wxFFileInputStream input(FreeFileSync::getInstallationDir() + zToWx(globalFunctions::FILE_NAME_SEPARATOR) + wxT("Resources.dat")); + wxFFileInputStream input(FreeFileSync::getInstallationDir() + wxT("Resources.dat")); if (input.IsOk()) //if not... we don't want to react too harsh here { //activate support for .png files @@ -246,10 +247,14 @@ void GlobalResources::load() const } #ifdef FFS_WIN + //for compatibility it seems we need to stick with a "real" icon *programIcon = wxIcon(wxT("A_PROGRAM_ICON")); #else -#include "FreeFileSync.xpm" - *programIcon = wxIcon(FreeFileSync_xpm); + //#include "FreeFileSync.xpm" + //*programIcon = wxIcon(FreeFileSync_xpm); + + //use big FFS logo bitmap for better quality + programIcon->CopyFromBitmap(*bitmapFFS); #endif } diff --git a/library/resources.h b/library/resources.h index 432498a3..512d7ed9 100644 --- a/library/resources.h +++ b/library/resources.h @@ -15,6 +15,8 @@ public: const wxBitmap& getImageByName(const wxString& imageName) const; //image resource objects + wxBitmap* bitmapCmpByTime; + wxBitmap* bitmapCmpByContent; wxBitmap* bitmapArrowLeft; wxBitmap* bitmapArrowRight; wxBitmap* bitmapArrowLeftCr; @@ -34,7 +36,7 @@ public: wxBitmap* bitmapSync; wxBitmap* bitmapSyncDisabled; wxBitmap* bitmapSwap; - wxBitmap* bitmapSwapSmall; + wxBitmap* bitmapSwapSlim; wxBitmap* bitmapHelp; wxBitmap* bitmapLeftOnly; wxBitmap* bitmapLeftOnlyAct; @@ -75,7 +77,6 @@ public: wxBitmap* bitmapLoadSmall; wxBitmap* bitmapNewSmall; wxBitmap* bitmapFFS; - wxBitmap* bitmapFFSPaused; wxBitmap* bitmapDeleteFile; wxBitmap* bitmapGPL; wxBitmap* bitmapStatusPause; @@ -96,7 +97,6 @@ public: wxBitmap* bitmapSyncSmall; wxBitmap* bitmapClockSmall; wxBitmap* bitmapClock; - wxBitmap* bitmapFilter; wxBitmap* bitmapBatch; wxBitmap* bitmapBatchSmall; wxBitmap* bitmapMoveUp; @@ -121,6 +121,7 @@ public: wxBitmap* bitmapHolland; wxBitmap* bitmapEngland; wxBitmap* bitmapFrance; + wxBitmap* bitmapFinland; wxBitmap* bitmapGermany; wxBitmap* bitmapHungary; wxBitmap* bitmapRomania; diff --git a/library/statistics.cpp b/library/statistics.cpp index fb7f5ba4..53a75fce 100644 --- a/library/statistics.cpp +++ b/library/statistics.cpp @@ -113,6 +113,10 @@ Statistics::Statistics(const int totalObjectCount, remainingTimeLast(256*256*256*100), //something "big" timer(new wxStopWatch) {} + Statistics::~Statistics() + { + delete timer; + } void Statistics::addMeasurement(const int objectsCurrent, const double dataCurrent) { diff --git a/library/statistics.h b/library/statistics.h index fe247b47..d1b8b98b 100644 --- a/library/statistics.h +++ b/library/statistics.h @@ -39,6 +39,8 @@ public: const unsigned windowSizeRemainingTime, //time in ms const unsigned windowSizeBytesPerSecond); //time in ms + ~Statistics(); + void addMeasurement(const int objectsCurrent, const double dataCurrent); wxString getRemainingTime() const; //returns the remaining time in milliseconds wxString getBytesPerSecond() const; @@ -66,7 +68,7 @@ private: }; std::list<record> measurements; - std::auto_ptr<wxStopWatch> timer; + wxStopWatch* timer; }; #endif // STATISTICS_H_INCLUDED diff --git a/shared/customComboBox.cpp b/shared/customComboBox.cpp new file mode 100644 index 00000000..f2eec7a9 --- /dev/null +++ b/shared/customComboBox.cpp @@ -0,0 +1,73 @@ +#include "customComboBox.h" + + +CustomComboBox::CustomComboBox(wxWindow* parent, + wxWindowID id, + const wxString& value, + const wxPoint& pos, + const wxSize& size, + int n, + const wxString choices[], + long style, + const wxValidator& validator, + const wxString& name) : + wxComboBox(parent, id, value, pos, size, n, choices, style, validator, name) +{ + //register key event to enable item deletion + this->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CustomComboBox::OnKeyEvent), NULL, this ); +} + + +void CustomComboBox::OnKeyEvent(wxKeyEvent& event) +{ + const int keyCode = event.GetKeyCode(); + if (keyCode == WXK_DELETE || keyCode == WXK_NUMPAD_DELETE) + { + //try to delete the currently selected config history item + const int selectedItem = this->GetCurrentSelection(); + if (0 <= selectedItem && selectedItem < static_cast<int>(this->GetCount()) && + (GetValue() != GetString(selectedItem) || //avoid problems when letter shall be deleted instead of list item + GetValue() == wxEmptyString) //exception: always allow removing empty entry + ) + { + //save old (selected) value: deletion seems to have influence on this + const wxString currentVal = this->GetValue(); + this->SetSelection(wxNOT_FOUND); + + //delete selected row + this->Delete(selectedItem); + + //(re-)set value + this->SetValue(currentVal); + + //eat up key event + return; + } + } + event.Skip(); +} + + +void CustomComboBox::addPairToFolderHistory(const wxString& newFolder, unsigned int maxHistSize) +{ + const wxString oldVal = this->GetValue(); + + //insert new folder or put it to the front if already existing +#ifdef FFS_WIN //don't respect case in windows build + const int pos = FindString(newFolder, false); +#elif defined FFS_LINUX + const int pos = FindString(newFolder, true); +#endif + if (pos != wxNOT_FOUND) + this->Delete(pos); + + this->Insert(newFolder, 0); + + //keep maximal size of history list + if (this->GetCount() > maxHistSize) + this->Delete(maxHistSize); + + this->SetSelection(wxNOT_FOUND); //don't select anything + this->SetValue(oldVal); //but preserve main text! +} + diff --git a/shared/customComboBox.h b/shared/customComboBox.h new file mode 100644 index 00000000..b6af43bf --- /dev/null +++ b/shared/customComboBox.h @@ -0,0 +1,29 @@ +#ifndef CUSTOMCOMBOBOX_H_INCLUDED +#define CUSTOMCOMBOBOX_H_INCLUDED + +#include <wx/combobox.h> + +//combobox with history function + functionality to delete items (DEL) + +class CustomComboBox : public wxComboBox +{ +public: + CustomComboBox(wxWindow* parent, + wxWindowID id, + const wxString& value = wxEmptyString, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + int n = 0, + const wxString choices[] = (const wxString *) NULL, + long style = 0, + const wxValidator& validator = wxDefaultValidator, + const wxString& name = wxComboBoxNameStr); + + void addPairToFolderHistory(const wxString& newFolder, unsigned int maxHistSize); + +private: + void OnKeyEvent(wxKeyEvent& event); +}; + + +#endif // CUSTOMCOMBOBOX_H_INCLUDED diff --git a/shared/dllLoader.cpp b/shared/dllLoader.cpp new file mode 100644 index 00000000..e37ded54 --- /dev/null +++ b/shared/dllLoader.cpp @@ -0,0 +1,44 @@ +#include "dllLoader.h" +#include <wx/msw/wrapwin.h> //includes "windows.h" + +namespace +{ +class KernelDllHandler //dynamically load "kernel32.dll" +{ +public: + static const KernelDllHandler& getInstance() + { + static KernelDllHandler instance; + return instance; + } + + HINSTANCE getHandle() const + { + return hKernel; + } + +private: + KernelDllHandler() : + hKernel(NULL) + { + //get a handle to the DLL module containing required functionality + hKernel = ::LoadLibrary(L"kernel32.dll"); + } + + ~KernelDllHandler() + { + if (hKernel) ::FreeLibrary(hKernel); + } + + HINSTANCE hKernel; +}; +} + + +void* Utility::loadSymbolKernel(const std::string& functionName) +{ + if (KernelDllHandler::getInstance().getHandle() != NULL) + return reinterpret_cast<void*>(::GetProcAddress(KernelDllHandler::getInstance().getHandle(), functionName.c_str())); + else + return NULL; +} diff --git a/shared/dllLoader.h b/shared/dllLoader.h new file mode 100644 index 00000000..bf62b542 --- /dev/null +++ b/shared/dllLoader.h @@ -0,0 +1,40 @@ +#ifndef DLLLOADER_H_INCLUDED +#define DLLLOADER_H_INCLUDED + +#include <string> + +namespace Utility +{ + //load kernel dll functions +template <typename FunctionType> +FunctionType loadDllFunKernel(const std::string& functionName); + + + + + + + + + + + + + +//---------------Inline Implementation--------------------------------------------------- +void* loadSymbolKernel(const std::string& functionName); + +template <typename FunctionType> +inline +FunctionType loadDllFunKernel(const std::string& functionName) +{ + return reinterpret_cast<FunctionType>(loadSymbolKernel(functionName)); +} + +#ifndef FFS_WIN +use in windows build only! +#endif + +} + +#endif // DLLLOADER_H_INCLUDED diff --git a/shared/fileHandling.cpp b/shared/fileHandling.cpp index 495e3d49..4b9901e0 100644 --- a/shared/fileHandling.cpp +++ b/shared/fileHandling.cpp @@ -11,8 +11,10 @@ #include <wx/log.h> #include <wx/datetime.h> #include "stringConv.h" +#include <wx/utils.h> #ifdef FFS_WIN +#include "dllLoader.h" #include <wx/msw/wrapwin.h> //includes "windows.h" #include "shadow.h" @@ -30,10 +32,70 @@ using FreeFileSync::FileError; +bool replaceMacro(wxString& macro) //macro without %-characters, return true if replaced successfully +{ + if (macro.IsEmpty()) + return false; + + //there are equally named environment variables %TIME%, %DATE% existing, so replace these first! + if (macro.CmpNoCase(wxT("time")) == 0) + { + macro = wxDateTime::Now().FormatISOTime(); + macro.Replace(wxT(":"), wxT("-")); + return true; + } + + if (macro.CmpNoCase(wxT("date")) == 0) + { + macro = wxDateTime::Now().FormatISODate(); + return true; + } + + //try to apply environment variables + wxString envValue; + if (wxGetEnv(macro, &envValue)) + { + macro = envValue; + return true; + } + + return false; +} + + +void expandMacros(wxString& text) +{ + const wxChar SEPARATOR = '%'; + + if (text.Find(SEPARATOR) != wxNOT_FOUND) + { + wxString prefix = text.BeforeFirst(SEPARATOR); + wxString postfix = text.AfterFirst(SEPARATOR); + if (postfix.Find(SEPARATOR) != wxNOT_FOUND) + { + wxString potentialMacro = postfix.BeforeFirst(SEPARATOR); + wxString rest = postfix.AfterFirst(SEPARATOR); //text == prefix + SEPARATOR + potentialMacro + SEPARATOR + rest + + if (replaceMacro(potentialMacro)) + { + expandMacros(rest); + text = prefix + potentialMacro + rest; + } + else + { + rest = wxString() + SEPARATOR + rest; + expandMacros(rest); + text = prefix + SEPARATOR + potentialMacro + rest; + } + } + } +} + + Zstring FreeFileSync::getFormattedDirectoryName(const Zstring& dirname) { //Formatting is needed since functions expect the directory to end with '\' to be able to split the relative names. - //Also improves usability. + //note: don't do directory formatting with wxFileName, as it doesn't respect //?/ - prefix! wxString dirnameTmp = zToWx(dirname); dirnameTmp.Trim(true); //remove whitespace characters from right @@ -46,14 +108,8 @@ Zstring FreeFileSync::getFormattedDirectoryName(const Zstring& dirname) dirnameTmp += zToWx(globalFunctions::FILE_NAME_SEPARATOR); //replace macros - wxString timeNow = wxDateTime::Now().FormatISOTime(); - timeNow.Replace(wxT(":"), wxT("-")); - dirnameTmp.Replace(wxT("%time%"), timeNow.c_str()); - - const wxString dateToday = wxDateTime::Now().FormatISODate(); - dirnameTmp.Replace(wxT("%date%"), dateToday.c_str()); + expandMacros(dirnameTmp); - //don't do directory formatting with wxFileName, as it doesn't respect //?/ - prefix return wxToZ(dirnameTmp); } @@ -717,57 +773,16 @@ void FreeFileSync::copyFileTimes(const Zstring& sourceDir, const Zstring& target #ifdef FFS_WIN -class KernelDllHandler //dynamically load windows API functions -{ - typedef DWORD (WINAPI *GetFinalPath)( - HANDLE hFile, - LPTSTR lpszFilePath, - DWORD cchFilePath, - DWORD dwFlags); - -public: - static const KernelDllHandler& getInstance() //lazy creation of KernelDllHandler - { - static KernelDllHandler instance; - - if (instance.getFinalPathNameByHandle == NULL) - throw FileError(wxString(_("Error loading library function:")) + wxT("\n\"") + wxT("GetFinalPathNameByHandleW") + wxT("\"")); - - return instance; - } - - GetFinalPath getFinalPathNameByHandle; - -private: - KernelDllHandler() : - getFinalPathNameByHandle(NULL), - hKernel(NULL) - { - //get a handle to the DLL module containing required functionality - hKernel = ::LoadLibrary(wxT("kernel32.dll")); - if (hKernel) - getFinalPathNameByHandle = reinterpret_cast<GetFinalPath>(::GetProcAddress(hKernel, "GetFinalPathNameByHandleW")); //load unicode version! - } - - ~KernelDllHandler() - { - if (hKernel) ::FreeLibrary(hKernel); - } - - HINSTANCE hKernel; -}; - - Zstring resolveDirectorySymlink(const Zstring& dirLinkName) //get full target path of symbolic link to a directory { //open handle to target of symbolic link - HANDLE hDir = CreateFile(dirLinkName.c_str(), - 0, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - NULL); + HANDLE hDir = ::CreateFile(dirLinkName.c_str(), + 0, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL); if (hDir == INVALID_HANDLE_VALUE) return Zstring(); @@ -776,7 +791,20 @@ Zstring resolveDirectorySymlink(const Zstring& dirLinkName) //get full target pa const unsigned int BUFFER_SIZE = 10000; TCHAR targetPath[BUFFER_SIZE]; - const DWORD rv = KernelDllHandler::getInstance().getFinalPathNameByHandle( + + //dynamically load windows API function + typedef DWORD (WINAPI *GetFinalPathNameByHandleWFunc)( + HANDLE hFile, + LPTSTR lpszFilePath, + DWORD cchFilePath, + DWORD dwFlags); + static const GetFinalPathNameByHandleWFunc getFinalPathNameByHandle = + Utility::loadDllFunKernel<GetFinalPathNameByHandleWFunc>("GetFinalPathNameByHandleW"); + + if (getFinalPathNameByHandle == NULL) + throw FileError(wxString(_("Error loading library function:")) + wxT("\n\"") + wxT("GetFinalPathNameByHandleW") + wxT("\"")); + + const DWORD rv = (*getFinalPathNameByHandle)( hDir, targetPath, BUFFER_SIZE, @@ -987,7 +1015,7 @@ void FreeFileSync::createDirectory(const Zstring& directory, const Zstring& temp Zstring createTempName(const Zstring& filename) { - Zstring output = filename + DefaultStr(".tmp"); + Zstring output = filename + DefaultStr(".ffs_tmp"); //ensure uniqueness if (FreeFileSync::fileExists(output)) @@ -1007,7 +1035,7 @@ Zstring createTempName(const Zstring& filename) #ifdef FFS_WIN #ifndef COPY_FILE_COPY_SYMLINK -const DWORD COPY_FILE_COPY_SYMLINK = 0x00000800; +#define COPY_FILE_COPY_SYMLINK 0x00000800 #endif DWORD CALLBACK copyCallbackInternal( @@ -1063,7 +1091,26 @@ bool supportForSymbolicLinks() //symbolic links are supported starting with Vista if (GetVersionEx(&osvi)) return osvi.dwMajorVersion > 5; //XP has majorVersion == 5, minorVersion == 1, Vista majorVersion == 6 + //overview: http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx + return false; +} + +#ifndef COPY_FILE_ALLOW_DECRYPTED_DESTINATION +#define COPY_FILE_ALLOW_DECRYPTED_DESTINATION 0x00000008 +#endif + + +bool supportForNonEncryptedDestination() +{ + OSVERSIONINFO osvi; + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + + //symbolic links are supported starting with Vista + if (GetVersionEx(&osvi)) + return osvi.dwMajorVersion >= 5 && osvi.dwMinorVersion >= 1; //XP has majorVersion == 5, minorVersion == 1, Vista majorVersion == 6 + //overview: http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx return false; } @@ -1081,6 +1128,12 @@ void FreeFileSync::copyFile(const Zstring& sourceFile, if (copyFileSymLinks && symlinksSupported) copyFlags |= COPY_FILE_COPY_SYMLINK; + //allow copying from encrypted to non-encrytped location + static const bool nonEncSupported = supportForNonEncryptedDestination(); + if (nonEncSupported) + copyFlags |= COPY_FILE_ALLOW_DECRYPTED_DESTINATION; + + const Zstring temporary = createTempName(targetFile); //use temporary file until a correct date has been set if (!::CopyFileEx( //same performance as CopyFile() sourceFile.c_str(), @@ -1312,3 +1365,4 @@ bool FreeFileSync::isFatDrive(const Zstring& directoryName) } #endif //FFS_WIN */ + diff --git a/shared/globalFunctions.h b/shared/globalFunctions.h index 74387959..06238236 100644 --- a/shared/globalFunctions.h +++ b/shared/globalFunctions.h @@ -10,10 +10,7 @@ #include <memory> #include <sstream> #include <fstream> -#include <wx/stream.h> -class wxInputStream; -class wxOutputStream; class wxStopWatch; @@ -61,9 +58,6 @@ unsigned int getDigitCount(const unsigned int number); //count number of digits template <class T> T readNumber(std::ifstream& stream); template <class T> void writeNumber(std::ofstream& stream, T number); -template <class T> T readNumber(wxInputStream& stream); -template <class T> void writeNumber(wxOutputStream& stream, T number); - inline wxLongLong convertToSigned(const wxULongLong number) { @@ -221,24 +215,6 @@ void globalFunctions::writeNumber(std::ofstream& stream, T number) } -template <class T> -inline -T globalFunctions::readNumber(wxInputStream& stream) -{ - T result = 0; - stream.Read(&result, sizeof(T)); - return result; -} - - -template <class T> -inline -void globalFunctions::writeNumber(wxOutputStream& stream, T number) -{ - stream.Write(&number, sizeof(T)); -} - - inline wxString globalFunctions::numberToWxString(const unsigned int number) { diff --git a/shared/inotify/inotify-cxx.cpp b/shared/inotify/inotify-cxx.cpp index 7870e825..7c523afb 100644 --- a/shared/inotify/inotify-cxx.cpp +++ b/shared/inotify/inotify-cxx.cpp @@ -18,7 +18,9 @@ * please visit http://www.gnu.org/licenses/license-list.html. * */ - + +//added by ZenJu +#include <cstdio> #include <errno.h> #include <unistd.h> diff --git a/shared/localization.cpp b/shared/localization.cpp index ff14c980..ad3cbb99 100644 --- a/shared/localization.cpp +++ b/shared/localization.cpp @@ -127,6 +127,13 @@ LocalizationInfo::LocalizationInfo() newEntry.languageFlag = wxT("slovakia.png"); locMapping.push_back(newEntry); + newEntry.languageID = wxLANGUAGE_FINNISH; + newEntry.languageName = wxT("Suomi"); + newEntry.languageFile = wxT("finnish.lng"); + newEntry.translatorName = wxT("Nalle Juslén"); + newEntry.languageFlag = wxT("finland.png"); + locMapping.push_back(newEntry); + newEntry.languageID = wxLANGUAGE_TURKISH; newEntry.languageName = wxT("Türkçe"); newEntry.languageFile = wxT("turkish.lng"); @@ -224,6 +231,7 @@ int mapLanguageDialect(const int language) return wxLANGUAGE_SPANISH; //case wxLANGUAGE_CZECH: + //case wxLANGUAGE_FINNISH: //case wxLANGUAGE_JAPANESE: //case wxLANGUAGE_POLISH: //case wxLANGUAGE_SLOVENIAN: @@ -378,8 +386,8 @@ void CustomLocale::setLanguage(const int language) translationDB->clear(); if (!languageFile.empty()) { - UnicodeFileReader langFile(FreeFileSync::getInstallationDir() + zToWx(globalFunctions::FILE_NAME_SEPARATOR) + - wxT("Languages") + zToWx(globalFunctions::FILE_NAME_SEPARATOR) + languageFile); + UnicodeFileReader langFile(FreeFileSync::getInstallationDir() + wxT("Languages") + + zToWx(globalFunctions::FILE_NAME_SEPARATOR) + languageFile); if (langFile.isOkay()) { int rowNumber = 0; diff --git a/shared/serialize.cpp b/shared/serialize.cpp new file mode 100644 index 00000000..616d244d --- /dev/null +++ b/shared/serialize.cpp @@ -0,0 +1,50 @@ +#include "serialize.h" +#include <wx/intl.h> + +using namespace Utility; + + +void ReadInputStream::throwReadError() //throw FileError() +{ + throw FreeFileSync::FileError(wxString(_("Error reading from synchronization database:")) + wxT(" \n") + + wxT("\"") + errorObjName_ + wxT("\"")); +} + + +ReadInputStream::CharArray ReadInputStream::readArrayC() +{ + CharArray buffer(new std::vector<char>); + const size_t byteCount = readNumberC<size_t>(); + if (byteCount > 0) + { + buffer->resize(byteCount); + stream_.Read(&(*buffer)[0], byteCount); + check(); + if (stream_.LastRead() != byteCount) //some additional check + throwReadError(); + } + return buffer; +} + + +//-------------------------------------------------------------------------------------------------------- +void WriteOutputStream::throwWriteError() //throw FileError() +{ + throw FreeFileSync::FileError(wxString(_("Error writing to synchronization database:")) + wxT(" \n") + + wxT("\"") + errorObjName_ + wxT("\"")); +} + + +void WriteOutputStream::writeArrayC(const std::vector<char>& buffer) +{ + writeNumberC<size_t>(buffer.size()); + if (buffer.size() > 0) + { + stream_.Write(&buffer[0], buffer.size()); + check(); + if (stream_.LastWrite() != buffer.size()) //some additional check + throwWriteError(); + } +} + + diff --git a/shared/serialize.h b/shared/serialize.h new file mode 100644 index 00000000..85f57370 --- /dev/null +++ b/shared/serialize.h @@ -0,0 +1,198 @@ +#ifndef SERIALIZE_H_INCLUDED +#define SERIALIZE_H_INCLUDED + +#include "zstring.h" +#include <wx/stream.h> +#include "fileError.h" +#include <boost/scoped_array.hpp> +#include <boost/shared_ptr.hpp> + +namespace Utility +{ +template <class T> +T readNumber(wxInputStream& stream); + +template <class T> +void writeNumber(wxOutputStream& stream, T number); + + +Zstring readString(wxInputStream& stream); +void writeString(wxOutputStream& stream, const Zstring& str); + + +class ReadInputStream //throw FileError() +{ +protected: + ReadInputStream(wxInputStream& stream, const wxString& errorObjName) : stream_(stream), errorObjName_(errorObjName) {} + + template <class T> + T readNumberC(); //checked read operation + + Zstring readStringC(); //checked read operation + + typedef boost::shared_ptr<std::vector<char> > CharArray; + CharArray readArrayC(); + + void check(); + +protected: + wxInputStream& stream_; + +private: + void throwReadError(); //throw FileError() + const wxString& errorObjName_; //used for error text only +}; + + +class WriteOutputStream //throw FileError() +{ +protected: + WriteOutputStream(const wxString& errorObjName, wxOutputStream& stream) : stream_(stream), errorObjName_(errorObjName) {} + + template <class T> + void writeNumberC(T number); //checked write operation + + void writeStringC(const Zstring& str); //checked write operation + + void writeArrayC(const std::vector<char>& buffer); + + void check(); + +protected: + wxOutputStream& stream_; + +private: + void throwWriteError(); //throw FileError() + const wxString& errorObjName_; //used for error text only! +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +//---------------Inline Implementation--------------------------------------------------- +template <class T> +inline +T readNumber(wxInputStream& stream) +{ + T result = 0; + stream.Read(&result, sizeof(T)); + return result; +} + + +template <class T> +inline +void writeNumber(wxOutputStream& stream, T number) +{ + stream.Write(&number, sizeof(T)); +} + + +inline +Zstring readString(wxInputStream& stream) //read string from file stream +{ + const size_t strLength = readNumber<size_t>(stream); + if (strLength <= 1000) + { + DefaultChar buffer[1000]; + stream.Read(buffer, sizeof(DefaultChar) * strLength); + return Zstring(buffer, strLength); + } + else + { + boost::scoped_array<DefaultChar> buffer(new DefaultChar[strLength]); + stream.Read(buffer.get(), sizeof(DefaultChar) * strLength); + return Zstring(buffer.get(), strLength); + } +} + + +inline +void writeString(wxOutputStream& stream, const Zstring& str) //write string to filestream +{ + writeNumber<size_t>(stream, str.length()); + stream.Write(str.c_str(), sizeof(DefaultChar) * str.length()); +} + + +inline +void ReadInputStream::check() +{ + if (stream_.GetLastError() != wxSTREAM_NO_ERROR) + throwReadError(); +} + + +template <class T> +inline +T ReadInputStream::readNumberC() //checked read operation +{ + T output = readNumber<T>(stream_); + check(); + return output; +} + + +inline +Zstring ReadInputStream::readStringC() //checked read operation +{ + Zstring output = readString(stream_); + check(); + return output; +} + + +template <class T> +inline +void WriteOutputStream::writeNumberC(T number) //checked write operation +{ + writeNumber<T>(stream_, number); + check(); +} + + +inline +void WriteOutputStream::writeStringC(const Zstring& str) //checked write operation +{ + writeString(stream_, str); + check(); +} + + + +inline +void WriteOutputStream::check() +{ + if (stream_.GetLastError() != wxSTREAM_NO_ERROR) + throwWriteError(); +} + + +} + +#endif // SERIALIZE_H_INCLUDED diff --git a/shared/shadow.cpp b/shared/shadow.cpp index da7cfd99..29eec53b 100644 --- a/shared/shadow.cpp +++ b/shared/shadow.cpp @@ -6,7 +6,43 @@ using FreeFileSync::ShadowCopy; -class ShadowlDllHandler //dynamically load windows API functions +bool newerThanXP() +{ + OSVERSIONINFO osvi; + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + + //symbolic links are supported starting with Vista + if (GetVersionEx(&osvi)) + return osvi.dwMajorVersion > 5 || + (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion > 1) ; + //XP has majorVersion == 5, minorVersion == 1 + //Server 2003 has majorVersion == 5, minorVersion == 2 + //version overview: http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx + return false; +} + + +bool runningWOW64() //test if process is running under WOW64 (reference http://msdn.microsoft.com/en-us/library/ms684139(VS.85).aspx) +{ + typedef BOOL (WINAPI *IsWow64ProcessFunc)( + HANDLE hProcess, + PBOOL Wow64Process); + + const IsWow64ProcessFunc isWow64Process = reinterpret_cast<IsWow64ProcessFunc>( + ::GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process")); + if (isWow64Process != NULL) + { + BOOL isWow64 = FALSE; + if ((*isWow64Process)(::GetCurrentProcess(), &isWow64)) + return isWow64 == TRUE; + } + + return false; +} + + +class ShadowCopy::ShadowlDllHandler //dynamically load windows API functions { typedef bool (*CreateShadowCopyFct)( //volumeName must end with "\", while shadowVolName does not end with "\" const wchar_t* volumeName, @@ -19,23 +55,33 @@ class ShadowlDllHandler //dynamically load windows API functions typedef void (*ReleaseShadowCopyFct)(void* backupHandle); public: - static const ShadowlDllHandler& getInstance() + static const wxString& getShadowDllName() { - static ShadowlDllHandler instance; - return instance; + /* + distinguish a bunch of VSS builds: we use XP and Server 2003 implementations... + VSS version and compatibility overview: http://msdn.microsoft.com/en-us/library/aa384627(VS.85).aspx + */ +#if defined _WIN64 //note: _WIN32 is defined for 64-bit compilations, too, while _WIN64 only for 64-bit + static const wxString filename(newerThanXP() ? + wxT("Shadow_Server2003_x64.dll") : + wxT("Shadow_XP_x64.dll")); +#elif defined(_WIN32) + static const wxString filename(newerThanXP() ? + wxT("Shadow_Server2003_win32.dll") : + wxT("Shadow_XP_win32.dll")); +#else + Are we at 128 bit already? +#endif + return filename; } - CreateShadowCopyFct createShadowCopy; - ReleaseShadowCopyFct releaseShadowCopy; - -private: ShadowlDllHandler() : createShadowCopy(NULL), releaseShadowCopy(NULL), hShadow(NULL) { //get a handle to the DLL module containing the required functionality - hShadow = ::LoadLibrary(L"Shadow.dll"); + hShadow = ::LoadLibrary(getShadowDllName().c_str()); if (hShadow) { createShadowCopy = reinterpret_cast<CreateShadowCopyFct>(::GetProcAddress(hShadow, "createShadowCopy")); @@ -48,41 +94,56 @@ private: if (hShadow) ::FreeLibrary(hShadow); } + CreateShadowCopyFct createShadowCopy; + ReleaseShadowCopyFct releaseShadowCopy; + +private: HINSTANCE hShadow; }; +//############################################################################################################# ShadowCopy::ShadowCopy() : - backupHandle(NULL) {} + backupHandle(NULL) +{ + shadowDll = new ShadowlDllHandler; +} ShadowCopy::~ShadowCopy() { if (backupHandle != NULL) - ShadowlDllHandler::getInstance().releaseShadowCopy(backupHandle); -} - + shadowDll->releaseShadowCopy(backupHandle); -bool ShadowCopy::isOkay() -{ - //check that all functions could be loaded - return ShadowlDllHandler::getInstance().createShadowCopy != NULL && - ShadowlDllHandler::getInstance().releaseShadowCopy != NULL; + delete shadowDll; } Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile) { //check if shadow copy dll was loaded correctly - if (!isOkay()) + if ( shadowDll->createShadowCopy == NULL || + shadowDll->releaseShadowCopy == NULL) { wxString errorMsg = _("Error copying locked file %x!"); errorMsg.Replace(wxT("%x"), wxString(wxT("\"")) + inputFile.c_str() + wxT("\"")); throw FileError(errorMsg + wxT("\n\n") + _("Error starting Volume Shadow Copy Service!") + wxT("\n") + - _("Please copy the appropriate \"Shadow.dll\" (located in \"Shadow.zip\" archive) into the FreeFileSync installation directory to enable this feature.")); + _("Could not load a required DLL:") + wxT(" \"") + ShadowlDllHandler::getShadowDllName() + wxT("\"")); + } + + //VSS does not support running under WOW64 except for Windows XP and Windows Server 2003 + //(Reference: http://msdn.microsoft.com/en-us/library/aa384627(VS.85).aspx) + static const bool wow64Active = runningWOW64(); + if (wow64Active) + { + wxString errorMsg = _("Error copying locked file %x!"); + errorMsg.Replace(wxT("%x"), wxString(wxT("\"")) + inputFile.c_str() + wxT("\"")); + throw FileError(errorMsg + wxT("\n\n") + _("Error starting Volume Shadow Copy Service!") + wxT("\n") + + _("Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version.")); } +//--------------------------------------------------------------------------------------------------------- wchar_t volumeNameRaw[1000]; if (!GetVolumePathName(inputFile.c_str(), //__in LPCTSTR lpszFileName, @@ -103,7 +164,7 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile) //release old shadow copy if (backupHandle != NULL) { - ShadowlDllHandler::getInstance().releaseShadowCopy(backupHandle); + shadowDll->releaseShadowCopy(backupHandle); backupHandle = NULL; } realVolumeLast.clear(); //...if next call fails... @@ -114,7 +175,7 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile) void* backupHandleTmp = NULL; wchar_t errorMessage[1000]; - if (!ShadowlDllHandler::getInstance().createShadowCopy( + if (!shadowDll->createShadowCopy( volumeNameFormatted.c_str(), shadowVolName, 1000, @@ -149,10 +210,3 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile) } - - - - - - - diff --git a/shared/shadow.h b/shared/shadow.h index ddb329bd..79e0e59c 100644 --- a/shared/shadow.h +++ b/shared/shadow.h @@ -23,7 +23,8 @@ private: ShadowCopy(const ShadowCopy&); ShadowCopy& operator=(const ShadowCopy&); - bool isOkay(); + class ShadowlDllHandler; + const ShadowlDllHandler* shadowDll; Zstring realVolumeLast; //buffer last volume name Zstring shadowVolumeLast; //buffer last created shadow volume diff --git a/shared/standardPaths.cpp b/shared/standardPaths.cpp index 3d5cfdb5..3c57f5b9 100644 --- a/shared/standardPaths.cpp +++ b/shared/standardPaths.cpp @@ -9,7 +9,7 @@ using namespace FreeFileSync; wxString assembleFileForUserData(const wxString fileName) { - static const bool isPortableVersion = !wxFileExists(FreeFileSync::getInstallationDir() + zToWx(globalFunctions::FILE_NAME_SEPARATOR) + wxT("uninstall.exe")); //this check is a bit lame... + static const bool isPortableVersion = !wxFileExists(FreeFileSync::getInstallationDir() + wxT("uninstall.exe")); //this check is a bit lame... if (isPortableVersion) //use current working directory return wxString(wxT(".")) + zToWx(globalFunctions::FILE_NAME_SEPARATOR) + fileName; @@ -51,7 +51,7 @@ const wxString& FreeFileSync::getLastErrorTxtFile() const wxString& FreeFileSync::getInstallationDir() { - static wxString instance = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath(); + static wxString instance = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath() + zToWx(globalFunctions::FILE_NAME_SEPARATOR); return instance; } diff --git a/shared/standardPaths.h b/shared/standardPaths.h index 34f6ab48..2af802a9 100644 --- a/shared/standardPaths.h +++ b/shared/standardPaths.h @@ -12,7 +12,7 @@ namespace FreeFileSync const wxString& getGlobalConfigFile(); const wxString& getDefaultLogDirectory(); const wxString& getLastErrorTxtFile(); -const wxString& getInstallationDir(); //FreeFileSync installation directory without path separator +const wxString& getInstallationDir(); //FreeFileSync installation directory WITH path separator at end const wxString& getConfigDir(); //------------------------------------------------------------------------------ } diff --git a/shared/zstring.cpp b/shared/zstring.cpp index 04c79b6f..cb288ea2 100644 --- a/shared/zstring.cpp +++ b/shared/zstring.cpp @@ -3,6 +3,7 @@ #ifdef FFS_WIN #include <wx/msw/wrapwin.h> //includes "windows.h" +#include "dllLoader.h" #endif //FFS_WIN #ifdef __WXDEBUG__ @@ -46,24 +47,58 @@ AllocationCount& AllocationCount::getInstance() #ifdef FFS_WIN + +#ifndef LOCALE_INVARIANT +#define LOCALE_INVARIANT 0x007f +#endif + + inline int compareStringsWin32(const wchar_t* a, const wchar_t* b, const int aCount = -1, const int bCount = -1) { - //DON'T use lstrcmpi() here! It uses word sort, which unfortunately is NOT always a strict weak sorting function for some locales (e.g. swedish) - //Use CompareString() with "SORT_STRINGSORT" instead!!! - - const int rv = CompareString( - LOCALE_USER_DEFAULT, //locale identifier - NORM_IGNORECASE | SORT_STRINGSORT, //comparison-style options - a, //pointer to first string - aCount, //size, in bytes or characters, of first string - b, //pointer to second string - bCount); //size, in bytes or characters, of second string - - if (rv == 0) - throw std::runtime_error("Error comparing strings!"); - else - return rv - 2; //convert to C-style string compare result + //try to call "CompareStringOrdinal" first for low-level string comparison: unfortunately available not before Windows Vista! + typedef int (WINAPI *CompareStringOrdinalFunc)( + LPCWSTR lpString1, + int cchCount1, + LPCWSTR lpString2, + int cchCount2, + BOOL bIgnoreCase); + static const CompareStringOrdinalFunc ordinalCompare = Utility::loadDllFunKernel<CompareStringOrdinalFunc>("CompareStringOrdinal"); + + + //we're lucky here! This additional test for "CompareStringOrdinal" has no noticeable performance impact!! + if (ordinalCompare != NULL) + { + const int rv = (*ordinalCompare)( + a, //pointer to first string + aCount, //size, in bytes or characters, of first string + b, //pointer to second string + bCount, //size, in bytes or characters, of second string + true); //ignore case + + if (rv == 0) + throw std::runtime_error("Error comparing strings (ordinal)!"); + else + return rv - 2; //convert to C-style string compare result + } + else //fallback to "CompareString". Attention: this function is NOT accurate: for example "weiß" == "weiss"!!! + { + //DON'T use lstrcmpi() here! It uses word sort and is locale dependent! + //Use CompareString() with "SORT_STRINGSORT" instead!!! + + const int rv = CompareString( + LOCALE_INVARIANT, //locale independent + NORM_IGNORECASE | SORT_STRINGSORT, //comparison-style options + a, //pointer to first string + aCount, //size, in bytes or characters, of first string + b, //pointer to second string + bCount); //size, in bytes or characters, of second string + + if (rv == 0) + throw std::runtime_error("Error comparing strings!"); + else + return rv - 2; //convert to C-style string compare result + } } #endif diff --git a/shared/zstring.h b/shared/zstring.h index 68b72060..d0be30bf 100644 --- a/shared/zstring.h +++ b/shared/zstring.h @@ -61,7 +61,7 @@ public: Zstring BeforeLast( DefaultChar ch) const; //returns empty string if ch not found Zstring AfterFirst( DefaultChar ch) const; //returns empty string if ch not found Zstring BeforeFirst(DefaultChar ch) const; //returns the whole string if ch not found - size_t Find(DefaultChar ch, bool fromEnd) const; + size_t Find(DefaultChar ch, bool fromEnd) const; //returns npos if not found bool Matches(const DefaultChar* mask) const; static bool Matches(const DefaultChar* name, const DefaultChar* mask); Zstring& Trim(bool fromRight); //from right or left @@ -333,6 +333,7 @@ Zstring::~Zstring() inline void Zstring::initAndCopy(const DefaultChar* source, size_t sourceLen) { + assert(source); descr = allocate(sourceLen); ::memcpy(data(), source, sourceLen * sizeof(DefaultChar)); data()[sourceLen] = 0; diff --git a/structures.cpp b/structures.cpp index a9d386f5..8653f43a 100644 --- a/structures.cpp +++ b/structures.cpp @@ -7,14 +7,7 @@ using FreeFileSync::SyncConfiguration; using FreeFileSync::MainConfiguration; -Zstring FreeFileSync::defaultIncludeFilter() -{ - static Zstring include(DefaultStr("*")); //include all files/folders - return include; -} - - -Zstring FreeFileSync::defaultExcludeFilter() +Zstring FreeFileSync::standardExcludeFilter() { #ifdef FFS_WIN static Zstring exclude(wxT("\ @@ -145,15 +138,27 @@ wxString SyncConfiguration::getVariantName() const wxString MainConfiguration::getSyncVariantName() { - const SyncConfiguration::Variant mainVariant = syncConfiguration.getVariant(); + const SyncConfiguration firstSyncCfg = + firstPair.altSyncConfig.get() ? + firstPair.altSyncConfig->syncConfiguration : + syncConfiguration; //fallback to main sync cfg + + const SyncConfiguration::Variant firstVariant = firstSyncCfg.getVariant(); //test if there's a deviating variant within the additional folder pairs for (std::vector<FolderPairEnh>::const_iterator i = additionalPairs.begin(); i != additionalPairs.end(); ++i) - if (i->altSyncConfig.get() && i->altSyncConfig->syncConfiguration.getVariant() != mainVariant) + { + const SyncConfiguration::Variant thisVariant = + i->altSyncConfig.get() ? + i->altSyncConfig->syncConfiguration.getVariant() : + syncConfiguration.getVariant(); + + if (thisVariant != firstVariant) return _("Multiple..."); + } //seems to be all in sync... - return syncConfiguration.getVariantName(); + return firstSyncCfg.getVariantName(); } @@ -260,3 +265,4 @@ wxString FreeFileSync::getSymbol(SyncOperation op) return wxEmptyString; } + diff --git a/structures.h b/structures.h index 180fa90c..ba9c3ada 100644 --- a/structures.h +++ b/structures.h @@ -134,25 +134,23 @@ struct AlternateSyncConfig } }; -//standard filter settings, OS dependent -Zstring defaultIncludeFilter(); -Zstring defaultExcludeFilter(); +//standard exclude filter settings, OS dependent +Zstring standardExcludeFilter(); -struct AlternateFilter +struct FilterConfig { - AlternateFilter(const Zstring& include, const Zstring& exclude) : + FilterConfig(const Zstring& include, const Zstring& exclude) : includeFilter(include), excludeFilter(exclude) {} - AlternateFilter() : //construct with default values - includeFilter(defaultIncludeFilter()), - excludeFilter(defaultExcludeFilter()) {} + FilterConfig() : //construct with default values + includeFilter(DefaultStr("*")) {} Zstring includeFilter; Zstring excludeFilter; - bool operator==(const AlternateFilter& other) const + bool operator==(const FilterConfig& other) const { return includeFilter == other.includeFilter && excludeFilter == other.excludeFilter; @@ -160,23 +158,6 @@ struct AlternateFilter }; -struct FolderPair -{ - FolderPair(const Zstring& leftDir, const Zstring& rightDir) : - leftDirectory(leftDir), - rightDirectory(rightDir) {} - - Zstring leftDirectory; - Zstring rightDirectory; - - bool operator==(const FolderPair& other) const - { - return leftDirectory == other.leftDirectory && - rightDirectory == other.rightDirectory; - } -}; - - struct FolderPairEnh //enhanced folder pairs with (optional) alternate configuration { FolderPairEnh() {} @@ -184,17 +165,17 @@ struct FolderPairEnh //enhanced folder pairs with (optional) alternate configura FolderPairEnh(const Zstring& leftDir, const Zstring& rightDir, const boost::shared_ptr<const AlternateSyncConfig>& syncConfig, - const boost::shared_ptr<const AlternateFilter>& filter) : + const FilterConfig& filter) : leftDirectory(leftDir), rightDirectory(rightDir) , altSyncConfig(syncConfig), - altFilter(filter) {} + localFilter(filter) {} Zstring leftDirectory; Zstring rightDirectory; boost::shared_ptr<const AlternateSyncConfig> altSyncConfig; //optional - boost::shared_ptr<const AlternateFilter> altFilter; //optional + FilterConfig localFilter; bool operator==(const FolderPairEnh& other) const { @@ -205,9 +186,7 @@ struct FolderPairEnh //enhanced folder pairs with (optional) alternate configura *altSyncConfig == *other.altSyncConfig : altSyncConfig.get() == other.altSyncConfig.get()) && - (altFilter.get() && other.altFilter.get() ? - *altFilter == *other.altFilter : - altFilter.get() == other.altFilter.get()); + localFilter == other.localFilter; } }; @@ -215,18 +194,13 @@ struct FolderPairEnh //enhanced folder pairs with (optional) alternate configura struct MainConfiguration { MainConfiguration() : - mainFolderPair(Zstring(), Zstring()), compareVar(CMP_BY_TIME_SIZE), -#ifdef FFS_WIN filterIsActive(true), -#elif defined FFS_LINUX - filterIsActive(false), -#endif - includeFilter(defaultIncludeFilter()), - excludeFilter(defaultExcludeFilter()), + includeFilter(DefaultStr("*")), + excludeFilter(standardExcludeFilter()), handleDeletion(FreeFileSync::recycleBinExistsWrap() ? MOVE_TO_RECYCLE_BIN : DELETE_PERMANENTLY) {} //enable if OS supports it; else user will have to activate first and then get an error message - FolderPair mainFolderPair; + FolderPairEnh firstPair; //there needs to be at least one pair! std::vector<FolderPairEnh> additionalPairs; //Compare setting @@ -235,7 +209,7 @@ struct MainConfiguration //Synchronisation settings SyncConfiguration syncConfiguration; - //Filter setting + //GLOBAL filter settings bool filterIsActive; Zstring includeFilter; Zstring excludeFilter; @@ -250,7 +224,7 @@ struct MainConfiguration bool operator==(const MainConfiguration& other) const { - return mainFolderPair == other.mainFolderPair && + return firstPair == other.firstPair && additionalPairs == other.additionalPairs && compareVar == other.compareVar && syncConfiguration == other.syncConfiguration && diff --git a/synchronization.cpp b/synchronization.cpp index 896de7ce..fac3d9a4 100644 --- a/synchronization.cpp +++ b/synchronization.cpp @@ -363,14 +363,16 @@ Zstring getSessionDeletionDir(const Zstring& customDeletionDirectory) } -SyncProcess::SyncProcess(const bool copyFileSymLinks, - const bool traverseDirSymLinks, +SyncProcess::SyncProcess(bool copyFileSymLinks, + bool traverseDirSymLinks, xmlAccess::OptionalDialogs& warnings, - const bool verifyCopiedFiles, + bool verifyCopiedFiles, + bool copyLockedFiles, StatusHandler& handler) : m_copyFileSymLinks(copyFileSymLinks), m_traverseDirSymLinks(traverseDirSymLinks), m_verifyCopiedFiles(verifyCopiedFiles), + copyLockedFiles_(copyLockedFiles), m_warnings(warnings), statusUpdater(handler) {} @@ -453,7 +455,7 @@ class FreeFileSync::SyncRecursively public: SyncRecursively(const SyncProcess& syncProc, #ifdef FFS_WIN - ShadowCopy& shadowCopyHandler, + ShadowCopy* shadowCopyHandler, #endif const DeletionHandling& delHandling) : statusUpdater_(syncProc.statusUpdater), @@ -536,7 +538,7 @@ private: StatusHandler& statusUpdater_; #ifdef FFS_WIN - ShadowCopy& shadowCopyHandler_; + ShadowCopy* shadowCopyHandler_; //optional! #endif const DeletionHandling& delHandling_; @@ -983,7 +985,7 @@ void SyncProcess::startSynchronizationProcess(const std::vector<FolderPairSyncCf #ifdef FFS_WIN //shadow copy buffer: per sync-instance, not folder pair - std::auto_ptr<ShadowCopy> shadowCopyHandler(new ShadowCopy); + std::auto_ptr<ShadowCopy> shadowCopyHandler(copyLockedFiles_ ? new ShadowCopy : NULL); #endif try @@ -997,18 +999,21 @@ void SyncProcess::startSynchronizationProcess(const std::vector<FolderPairSyncCf //generate name of alternate deletion directory (unique for session AND folder pair) const DeletionHandling currentDelHandling(folderPairCfg.handleDeletion, folderPairCfg.custDelFolder); + //exclude some pathological case (leftdir, rightdir are empty) + if (j->getBaseDir<LEFT_SIDE>() == j->getBaseDir<RIGHT_SIDE>()) + continue; //------------------------------------------------------------------------------------------ //execute synchronization recursively //loop through all files twice; reason: first delete, then copy SyncRecursively( *this, #ifdef FFS_WIN - *shadowCopyHandler, + shadowCopyHandler.get(), #endif currentDelHandling).execute<true>(*j); SyncRecursively(*this, #ifdef FFS_WIN - *shadowCopyHandler, + shadowCopyHandler.get(), #endif currentDelHandling).execute<false>(*j); //------------------------------------------------------------------------------------------ @@ -1090,7 +1095,7 @@ void SyncRecursively::copyFileUpdating(const Zstring& source, const Zstring& tar try { #ifdef FFS_WIN - FreeFileSync::copyFile(source, target, copyFileSymLinks_, &shadowCopyHandler_, &callback); + FreeFileSync::copyFile(source, target, copyFileSymLinks_, shadowCopyHandler_, &callback); #elif defined FFS_LINUX FreeFileSync::copyFile(source, target, copyFileSymLinks_, &callback); #endif @@ -1211,10 +1216,3 @@ void SyncRecursively::verifyFileCopy(const Zstring& source, const Zstring& targe } - - - - - - - diff --git a/synchronization.h b/synchronization.h index 87842249..53b17091 100644 --- a/synchronization.h +++ b/synchronization.h @@ -63,10 +63,11 @@ std::vector<FolderPairSyncCfg> extractSyncCfg(const MainConfiguration& mainCfg); class SyncProcess { public: - SyncProcess(const bool copyFileSymLinks, - const bool traverseDirSymLinks, + SyncProcess(bool copyFileSymLinks, + bool traverseDirSymLinks, xmlAccess::OptionalDialogs& warnings, - const bool verifyCopiedFiles, + bool verifyCopiedFiles, + bool copyLockedFiles, StatusHandler& handler); //CONTRACT: syncConfig must have SAME SIZE folderCmp and correspond per row! @@ -78,6 +79,7 @@ private: const bool m_copyFileSymLinks; const bool m_traverseDirSymLinks; const bool m_verifyCopiedFiles; + const bool copyLockedFiles_; //warnings xmlAccess::OptionalDialogs& m_warnings; diff --git a/ui/MainDialog.cpp b/ui/MainDialog.cpp index 7948da85..0d203453 100644 --- a/ui/MainDialog.cpp +++ b/ui/MainDialog.cpp @@ -7,6 +7,7 @@ #include <wx/ffile.h> #include "../library/customGrid.h" #include "../shared/customButton.h" +#include "../shared/customComboBox.h" #include <wx/msgdlg.h> #include "../comparison.h" #include "../synchronization.h" @@ -31,104 +32,159 @@ #include "../shared/toggleButton.h" #include "folderPair.h" #include "../shared/globalFunctions.h" +#include <wx/sound.h> using namespace FreeFileSync; using FreeFileSync::CustomLocale; -typedef FreeFileSync::FolderPairPanelBasic<FolderPairGenerated> FolderPairParent; +class MainFolderDragDrop : public DragDropOnMainDlg +{ +public: + MainFolderDragDrop(MainDialog& mainDlg, + wxWindow* dropWindow1, + wxWindow* dropWindow2, + wxDirPickerCtrl* dirPicker, + wxComboBox* dirName) : + + DragDropOnMainDlg(dropWindow1, dropWindow2, dirPicker, dirName), + mainDlg_(mainDlg) {} + + virtual bool AcceptDrop(const wxString& dropName) + { + const xmlAccess::XmlType fileType = xmlAccess::getXmlType(dropName); + + //test if ffs config file has been dropped + if (fileType == xmlAccess::XML_GUI_CONFIG) + { + mainDlg_.loadConfiguration(dropName); + return false; + } + //...or a ffs batch file + else if (fileType == xmlAccess::XML_BATCH_CONFIG) + { + BatchDialog* batchDlg = new BatchDialog(&mainDlg_, dropName); + if (batchDlg->ShowModal() == BatchDialog::BATCH_FILE_SAVED) + mainDlg_.pushStatusInformation(_("Batch file created successfully!")); + return false; + } + + //disable the sync button + mainDlg_.syncPreview.enableSynchronization(false); + + //clear grids + mainDlg_.gridDataView->clearAllRows(); + mainDlg_.updateGuiGrid(); + + return true; + } + +private: + MainFolderDragDrop(const MainFolderDragDrop&); + + MainDialog& mainDlg_; +}; + +//------------------------------------------------------------------ +/* class hierarchy: -class FolderPairPanel : public FolderPairParent + template<> + FolderPairPanelBasic + /|\ + | + template<> + FolderPairCallback FolderPairGenerated + /|\ /|\ + _________|________ ________| + | | | + FirstFolderPairCfg FolderPairPanel +*/ + +template <class GuiPanel> +class FolderPairCallback : public FolderPairPanelBasic<GuiPanel> //implements callback functionality to MainDialog as imposed by FolderPairPanelBasic { public: - FolderPairPanel(wxWindow* parent, MainDialog* mainDialog) : - FolderPairParent(parent), - mainDlg(mainDialog) - {} + FolderPairCallback(GuiPanel& basicPanel, MainDialog& mainDialog) : + FolderPairPanelBasic<GuiPanel>(basicPanel), //pass FolderPairGenerated part... + mainDlg(mainDialog) {} private: - virtual void OnAltFilterCfgRemoveConfirm(wxCommandEvent& event) + virtual void OnLocalFilterCfgRemoveConfirm(wxCommandEvent& event) { - FolderPairParent::OnAltFilterCfgRemoveConfirm(event); - mainDlg->updateFilterConfig(false); //update filter, leave activation status as it is + FolderPairPanelBasic<GuiPanel>::OnLocalFilterCfgRemoveConfirm(event); + mainDlg.updateFilterConfig(); //update filter } virtual void OnAltSyncCfgRemoveConfirm(wxCommandEvent& event) { - FolderPairParent::OnAltSyncCfgRemoveConfirm(event); - mainDlg->updateSyncConfig(); + FolderPairPanelBasic<GuiPanel>::OnAltSyncCfgRemoveConfirm(event); + mainDlg.updateSyncConfig(); } virtual wxWindow* getParentWindow() { - return mainDlg; + return &mainDlg; } virtual MainConfiguration getMainConfig() const { - return mainDlg->getCurrentConfiguration().mainCfg; + return mainDlg.getCurrentConfiguration().mainCfg; } virtual void OnAltSyncCfgChange() { - mainDlg->updateSyncConfig(); + mainDlg.updateSyncConfig(); } - virtual void OnAltFilterCfgChange(bool defaultValueSet) + virtual void OnLocalFilterCfgChange() { - if (defaultValueSet) //default - mainDlg->updateFilterConfig(false); //re-apply filter (without changing active-status) - else - mainDlg->updateFilterConfig(true); //activate(and apply) filter + mainDlg.updateFilterConfig(); //re-apply filter } - MainDialog* mainDlg; + MainDialog& mainDlg; }; -class MainFolderDragDrop : public DragDropOnMainDlg +class FolderPairPanel : + public FolderPairGenerated, //FolderPairPanel "owns" FolderPairGenerated! + public FolderPairCallback<FolderPairGenerated> { public: - MainFolderDragDrop(MainDialog* mainDlg, - wxWindow* dropWindow1, - wxWindow* dropWindow2, - wxDirPickerCtrl* dirPicker, - wxComboBox* dirName) : - - DragDropOnMainDlg(dropWindow1, dropWindow2, dirPicker, dirName), - mainDlg_(mainDlg) {} - - virtual bool AcceptDrop(const wxString& dropName) - { - const xmlAccess::XmlType fileType = xmlAccess::getXmlType(dropName); - - //test if ffs config file has been dropped - if (fileType == xmlAccess::XML_GUI_CONFIG) - { - mainDlg_->loadConfiguration(dropName); - return false; - } - //...or a ffs batch file - else if (fileType == xmlAccess::XML_BATCH_CONFIG) - { - BatchDialog* batchDlg = new BatchDialog(mainDlg_, dropName); - if (batchDlg->ShowModal() == BatchDialog::BATCH_FILE_SAVED) - mainDlg_->pushStatusInformation(_("Batch file created successfully!")); - return false; - } + FolderPairPanel(wxWindow* parent, MainDialog& mainDialog) : + FolderPairGenerated(parent), + FolderPairCallback<FolderPairGenerated>(static_cast<FolderPairGenerated&>(*this), mainDialog), //pass FolderPairGenerated part... + dragDropOnLeft( m_panelLeft, m_dirPickerLeft, m_directoryLeft), + dragDropOnRight(m_panelRight, m_dirPickerRight, m_directoryRight) {} - //disable the sync button - mainDlg_->syncPreview.enableSynchronization(false); +private: + //support for drag and drop + DragDropOnDlg dragDropOnLeft; + DragDropOnDlg dragDropOnRight; +}; - //clear grids - mainDlg_->gridDataView->clearAllRows(); - mainDlg_->updateGuiGrid(); - return true; - } +class FirstFolderPairCfg : public FolderPairCallback<MainDialogGenerated> +{ +public: + FirstFolderPairCfg(MainDialog& mainDialog) : + FolderPairCallback<MainDialogGenerated>(mainDialog, mainDialog), + + //prepare drag & drop + dragDropOnLeft(mainDialog, + mainDialog.m_panelLeft, + mainDialog.m_panelTopLeft, + mainDialog.m_dirPickerLeft, + mainDialog.m_directoryLeft), + dragDropOnRight(mainDialog, + mainDialog.m_panelRight, + mainDialog.m_panelTopRight, + mainDialog.m_dirPickerRight, + mainDialog.m_directoryRight) {} private: - MainDialog* mainDlg_; + //support for drag and drop + MainFolderDragDrop dragDropOnLeft; + MainFolderDragDrop dragDropOnRight; }; @@ -173,7 +229,10 @@ private: //################################################################################################################################## -MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, xmlAccess::XmlGlobalSettings& settings) : +MainDialog::MainDialog(wxFrame* frame, + const wxString& cfgFileName, + xmlAccess::XmlGlobalSettings& settings, + wxHelpController& helpController) : MainDialogGenerated(frame), globalSettings(settings), gridDataView(new FreeFileSync::GridView()), @@ -184,10 +243,14 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, xmlAccess::X #ifdef FFS_WIN updateFileIcons(new IconUpdater(m_gridLeft, m_gridRight)), #endif + helpController_(helpController), syncPreview(this) { wxWindowUpdateLocker dummy(this); //avoid display distortion + //init handling of first folder pair + firstFolderPair.reset(new FirstFolderPairCfg(*this)); + initViewFilterButtons(); //initialize and load configuration @@ -200,7 +263,6 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, xmlAccess::X //set icons for this dialog m_bpButton10->SetBitmapLabel(*GlobalResources::getInstance().bitmapExit); - m_bpButtonSwapSides->SetBitmapLabel(*GlobalResources::getInstance().bitmapSwap); m_buttonCompare->setBitmapFront(*GlobalResources::getInstance().bitmapCompare); m_bpButtonSyncConfig->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncCfg); m_bpButtonCmpConfig->SetBitmapLabel(*GlobalResources::getInstance().bitmapCmpCfg); @@ -246,22 +308,6 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, xmlAccess::X m_menuLanguages->Append(newItem); } - - //prepare drag & drop - dragDropOnLeft.reset(new MainFolderDragDrop( - this, - m_panelLeft, - m_panelTopLeft, - m_dirPickerLeft, - m_directoryLeft)); - - dragDropOnRight.reset(new MainFolderDragDrop( - this, - m_panelRight, - m_panelTopRight, - m_dirPickerRight, - m_directoryRight)); - //support for CTRL + C and DEL m_gridLeft->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainDialog::onGridLeftButtonEvent), NULL, this); m_gridRight->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainDialog::onGridRightButtonEvent), NULL, this); @@ -297,7 +343,7 @@ MainDialog::MainDialog(wxFrame* frame, const wxString& cfgFileName, xmlAccess::X //correct width of swap button above middle grid const wxSize source = m_gridMiddle->GetSize(); - const wxSize target = bSizerMiddle->GetSize(); + const wxSize target = m_bpButtonSwapSides->GetSize(); const int spaceToAdd = source.GetX() - target.GetX(); bSizerMiddle->Insert(1, spaceToAdd / 2, 0, 0); bSizerMiddle->Insert(0, spaceToAdd - (spaceToAdd / 2), 0, 0); @@ -345,6 +391,8 @@ void MainDialog::readGlobalSettings() posXNotMaximized != wxDefaultCoord && posYNotMaximized != wxDefaultCoord) SetSize(posXNotMaximized, posYNotMaximized, widthNotMaximized, heightNotMaximized); + else + Centre(); Maximize(globalSettings.gui.isMaximized); @@ -421,7 +469,7 @@ void MainDialog::setSyncDirManually(const std::set<unsigned int>& rowsToSetOnUiT if (fsObj) { setSyncDirectionRec(dir, *fsObj); //set new direction (recursively) - FilterProcess::setActiveStatus(true, *fsObj); //works recursively for directories + FreeFileSync::setActiveStatus(true, *fsObj); //works recursively for directories } } @@ -449,7 +497,7 @@ void MainDialog::filterRangeManually(const std::set<unsigned int>& rowsToFilterO gridDataView->getAllFileRef(rowsToFilterOnUiTable, compRef); //everything in compRef is bound for (std::vector<FileSystemObject*>::iterator i = compRef.begin(); i != compRef.end(); ++i) - FilterProcess::setActiveStatus(newSelection, **i); //works recursively for directories + FreeFileSync::setActiveStatus(newSelection, **i); //works recursively for directories refreshGridAfterFilterChange(400); //call this instead of updateGuiGrid() to add some delay if hideFiltered == true and to handle some graphical artifacts } @@ -462,12 +510,16 @@ void MainDialog::OnIdleEvent(wxEvent& event) if (stackObjects.size() > 0 ) //check if there is some work to do { wxLongLong currentTime = wxGetLocalTimeMillis(); - if (currentTime - lastStatusChange > 2000) //restore stackObject after two seconds + if (currentTime - lastStatusChange > 2500) //restore stackObject after two seconds { lastStatusChange = currentTime; m_staticTextStatusMiddle->SetLabel(stackObjects.top()); stackObjects.pop(); + + if (stackObjects.empty()) + m_staticTextStatusMiddle->SetForegroundColour(*wxBLACK); //reset color + m_panel7->Layout(); } } @@ -746,8 +798,8 @@ void MainDialog::openExternalApplication(unsigned int rowNumber, bool leftSide, else { //fallback - dir = zToWx(FreeFileSync::getFormattedDirectoryName(wxToZ(m_directoryLeft->GetValue()))); - dirCo = zToWx(FreeFileSync::getFormattedDirectoryName(wxToZ(m_directoryRight->GetValue()))); + dir = zToWx(FreeFileSync::getFormattedDirectoryName(firstFolderPair->getLeftDir())); + dirCo = zToWx(FreeFileSync::getFormattedDirectoryName(firstFolderPair->getRightDir())); if (!leftSide) std::swap(dir, dirCo); @@ -772,6 +824,7 @@ void MainDialog::pushStatusInformation(const wxString& text) lastStatusChange = wxGetLocalTimeMillis(); stackObjects.push(m_staticTextStatusMiddle->GetLabel()); m_staticTextStatusMiddle->SetLabel(text); + m_staticTextStatusMiddle->SetForegroundColour(wxColour(31, 57, 226)); //highlight color: blue m_panel7->Layout(); } @@ -781,6 +834,7 @@ void MainDialog::clearStatusBar() while (stackObjects.size() > 0) stackObjects.pop(); + m_staticTextStatusMiddle->SetForegroundColour(*wxBLACK); //reset color m_staticTextStatusLeft->SetLabel(wxEmptyString); m_staticTextStatusMiddle->SetLabel(wxEmptyString); m_staticTextStatusRight->SetLabel(wxEmptyString); @@ -910,14 +964,48 @@ void MainDialog::onGridLeftButtonEvent(wxKeyEvent& event) const int keyCode = event.GetKeyCode(); if (event.ControlDown()) - { - if (keyCode == 67 || keyCode == WXK_INSERT) //CTRL + C || CTRL + INS + switch (keyCode) + { + case 67: + case WXK_INSERT: //CTRL + C || CTRL + INS copySelectionToClipboard(m_gridLeft); - else if (keyCode == 65) //CTRL + A + break; + + case 65: //CTRL + A m_gridLeft->SelectAll(); - else if (keyCode == WXK_NUMPAD_ADD) //CTRL + '+' + break; + + case WXK_NUMPAD_ADD: //CTRL + '+' m_gridLeft->autoSizeColumns(); - } + break; + } + + else if (event.AltDown()) + switch (keyCode) + { + case WXK_LEFT: //ALT + <- + { + wxCommandEvent dummy; + OnContextSyncDirLeft(dummy); + } + break; + + case WXK_RIGHT: //ALT + -> + { + wxCommandEvent dummy; + OnContextSyncDirRight(dummy); + } + break; + + case WXK_UP: /* ALT + /|\ */ + case WXK_DOWN: /* ALT + \|/ */ + { + wxCommandEvent dummy; + OnContextSyncDirNone(dummy); + } + break; + } + else switch (keyCode) { @@ -965,14 +1053,48 @@ void MainDialog::onGridRightButtonEvent(wxKeyEvent& event) const int keyCode = event.GetKeyCode(); if (event.ControlDown()) - { - if (keyCode == 67 || keyCode == WXK_INSERT) //CTRL + C || CTRL + INS + switch (keyCode) + { + case 67: + case WXK_INSERT: //CTRL + C || CTRL + INS copySelectionToClipboard(m_gridRight); - else if (keyCode == 65) //CTRL + A + break; + + case 65: //CTRL + A m_gridRight->SelectAll(); - else if (keyCode == WXK_NUMPAD_ADD) //CTRL + '+' + break; + + case WXK_NUMPAD_ADD: //CTRL + '+' m_gridRight->autoSizeColumns(); - } + break; + } + + else if (event.AltDown()) + switch (keyCode) + { + case WXK_LEFT: //ALT + <- + { + wxCommandEvent dummy; + OnContextSyncDirLeft(dummy); + } + break; + + case WXK_RIGHT: //ALT + -> + { + wxCommandEvent dummy; + OnContextSyncDirRight(dummy); + } + break; + + case WXK_UP: /* ALT + /|\ */ + case WXK_DOWN: /* ALT + \|/ */ + { + wxCommandEvent dummy; + OnContextSyncDirNone(dummy); + } + break; + } + else switch (keyCode) { @@ -1073,17 +1195,17 @@ void MainDialog::OnContextRim(wxGridEvent& event) if (fsObj && (selectionLeft.size() + selectionRight.size() > 0)) { //CONTEXT_SYNC_DIR_LEFT - wxMenuItem* menuItemSyncDirLeft = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_LEFT, _("Change direction")); + wxMenuItem* menuItemSyncDirLeft = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_LEFT, wxString(_("Change direction")) + wxT("\tALT + LEFT")); menuItemSyncDirLeft->SetBitmap(getSyncOpImage(fsObj->testSyncOperation(true, SYNC_DIR_LEFT))); contextMenu->Append(menuItemSyncDirLeft); //CONTEXT_SYNC_DIR_NONE - wxMenuItem* menuItemSyncDirNone = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_NONE, _("Change direction")); + wxMenuItem* menuItemSyncDirNone = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_NONE, wxString(_("Change direction")) + wxT("\tALT + UP")); menuItemSyncDirNone->SetBitmap(getSyncOpImage(fsObj->testSyncOperation(true, SYNC_DIR_NONE))); contextMenu->Append(menuItemSyncDirNone); //CONTEXT_SYNC_DIR_RIGHT - wxMenuItem* menuItemSyncDirRight = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_RIGHT, _("Change direction")); + wxMenuItem* menuItemSyncDirRight = new wxMenuItem(contextMenu.get(), CONTEXT_SYNC_DIR_RIGHT, wxString(_("Change direction")) + wxT("\tALT + RIGHT")); menuItemSyncDirRight->SetBitmap(getSyncOpImage(fsObj->testSyncOperation(true, SYNC_DIR_RIGHT))); contextMenu->Append(menuItemSyncDirRight); @@ -1259,8 +1381,8 @@ void MainDialog::OnContextExcludeExtension(wxCommandEvent& event) currentCfg.mainCfg.excludeFilter += Zstring(DefaultStr("*.")) + selExtension->extension + DefaultStr(";"); //';' is appended to 'mark' that next exclude extension entry won't write to new line - currentCfg.mainCfg.filterIsActive = true; - updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive); + m_checkBoxActivateFilter->SetValue(true); + updateFilterButtons(); applyFiltering(getCurrentConfiguration().mainCfg, gridDataView->getDataTentative()); updateGuiGrid(); @@ -1293,8 +1415,8 @@ void MainDialog::OnContextExcludeObject(wxCommandEvent& event) currentCfg.mainCfg.excludeFilter += Zstring() + globalFunctions::FILE_NAME_SEPARATOR + i->relativeName + globalFunctions::FILE_NAME_SEPARATOR + DefaultStr("*"); } - currentCfg.mainCfg.filterIsActive = true; - updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive); + m_checkBoxActivateFilter->SetValue(true); + updateFilterButtons(); applyFiltering(getCurrentConfiguration().mainCfg, gridDataView->getDataTentative()); updateGuiGrid(); @@ -1457,8 +1579,8 @@ void MainDialog::OnContextMiddle(wxGridEvent& event) { contextMenu.reset(new wxMenu); //re-create context menu - contextMenu->Append(CONTEXT_CHECK_ALL, _("Check all")); - contextMenu->Append(CONTEXT_UNCHECK_ALL, _("Uncheck all")); + contextMenu->Append(CONTEXT_CHECK_ALL, _("Include all rows")); + contextMenu->Append(CONTEXT_UNCHECK_ALL, _("Exclude all rows")); if (gridDataView->rowsTotal() == 0) { @@ -1497,14 +1619,14 @@ void MainDialog::OnContextMiddleLabel(wxGridEvent& event) void MainDialog::OnContextIncludeAll(wxCommandEvent& event) { - FilterProcess::setActiveStatus(true, gridDataView->getDataTentative()); + FreeFileSync::setActiveStatus(true, gridDataView->getDataTentative()); refreshGridAfterFilterChange(0); //call this instead of updateGuiGrid() to add some delay if hideFiltered == true and to handle some graphical artifacts break; } void MainDialog::OnContextExcludeAll(wxCommandEvent& event) { - FilterProcess::setActiveStatus(false, gridDataView->getDataTentative()); + FreeFileSync::setActiveStatus(false, gridDataView->getDataTentative()); refreshGridAfterFilterChange(400); //call this instead of updateGuiGrid() to add some delay if hideFiltered == true and to handle some graphical artifacts } @@ -1621,48 +1743,15 @@ void MainDialog::addFileToCfgHistory(const wxString& filename) } -int findTextPos(const wxArrayString& array, const wxString& text) -{ - for (unsigned int i = 0; i < array.GetCount(); ++i) -#ifdef FFS_WIN //don't respect case in windows build - if (array[i].CmpNoCase(text) == 0) -#elif defined FFS_LINUX - if (array[i] == text) -#endif - return i; - - return -1; -} - - -void addPairToFolderHistory(wxComboBox* comboBox, const wxString& newFolder, unsigned int maxHistSize) -{ - const wxString oldVal = comboBox->GetValue(); - - const int pos = findTextPos(comboBox->GetStrings(), newFolder); - if (pos >= 0) - comboBox->Delete(pos); - - comboBox->Insert(newFolder, 0); - - //keep maximal size of history list - if (comboBox->GetCount() > maxHistSize) - comboBox->Delete(maxHistSize); - - comboBox->SetSelection(wxNOT_FOUND); //don't select anything - comboBox->SetValue(oldVal); //but preserve main text! -} - - void MainDialog::addLeftFolderToHistory(const wxString& leftFolder) { - addPairToFolderHistory(m_directoryLeft, leftFolder, globalSettings.gui.folderHistLeftMax); + m_directoryLeft->addPairToFolderHistory(leftFolder, globalSettings.gui.folderHistLeftMax); } void MainDialog::addRightFolderToHistory(const wxString& rightFolder) { - addPairToFolderHistory(m_directoryRight, rightFolder, globalSettings.gui.folderHistRightMax); + m_directoryRight->addPairToFolderHistory(rightFolder, globalSettings.gui.folderHistRightMax); } @@ -1800,44 +1889,6 @@ void MainDialog::OnCfgHistoryKeyEvent(wxKeyEvent& event) } -void removeSelectedElement(wxComboBox* control, wxEvent& event) -{ - const int selectedItem = control->GetCurrentSelection(); - if (0 <= selectedItem && selectedItem < int(control->GetCount())) - { - const wxString oldVal = control->GetValue(); - control->Delete(selectedItem); - control->SetSelection(wxNOT_FOUND); - control->SetValue(oldVal); - } - else - event.Skip(); -} - - -void MainDialog::OnFolderHistoryKeyEvent(wxKeyEvent& event) -{ - - /* - const int keyCode = event.GetKeyCode(); - if (keyCode == WXK_DELETE || keyCode == WXK_NUMPAD_DELETE) - { - wxObject* eventObj = event.GetEventObject(); - if (eventObj == (wxObject*)m_comboBoxDirLeft) - { - removeSelectedElement(m_comboBoxDirLeft, event); - return; //no event.Skip() here! - } - else if (eventObj == (wxObject*)m_comboBoxDirRight) - { - removeSelectedElement(m_comboBoxDirRight, event); - return; - } - }*/ - event.Skip(); -} - - void MainDialog::OnClose(wxCloseEvent &event) { if (!saveOldConfig()) //notify user about changed settings @@ -1886,7 +1937,7 @@ void MainDialog::OnSetSyncDirection(FFSSyncDirectionEvent& event) if (fsObj) { setSyncDirectionRec(event.direction, *fsObj); //set new direction (recursively) - FilterProcess::setActiveStatus(true, *fsObj); //works recursively for directories + FreeFileSync::setActiveStatus(true, *fsObj); //works recursively for directories } } @@ -1997,17 +2048,17 @@ void MainDialog::setCurrentConfiguration(const xmlAccess::XmlGuiConfig& newGuiCf //(re-)set view filter buttons initViewFilterButtons(); - updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive); - + m_checkBoxActivateFilter->SetValue(currentCfg.mainCfg.filterIsActive); + updateFilterButtons(); - //read main folder pair - const wxString mainFolderLeft = zToWx(currentCfg.mainCfg.mainFolderPair.leftDirectory); - const wxString mainFolderRight = zToWx(currentCfg.mainCfg.mainFolderPair.rightDirectory); - FreeFileSync::setDirectoryName(mainFolderLeft, m_directoryLeft, m_dirPickerLeft); - FreeFileSync::setDirectoryName(mainFolderRight, m_directoryRight, m_dirPickerRight); + //set first folder pair + firstFolderPair->setValues(currentCfg.mainCfg.firstPair.leftDirectory, + currentCfg.mainCfg.firstPair.rightDirectory, + currentCfg.mainCfg.firstPair.altSyncConfig, + currentCfg.mainCfg.firstPair.localFilter); - addLeftFolderToHistory( mainFolderLeft); //another hack: wxCombobox::Insert() asynchronously sends message - addRightFolderToHistory(mainFolderRight); //overwriting a later wxCombobox::SetValue()!!! :( + addLeftFolderToHistory( zToWx(currentCfg.mainCfg.firstPair.leftDirectory)); //another hack: wxCombobox::Insert() asynchronously sends message + addRightFolderToHistory(zToWx(currentCfg.mainCfg.firstPair.rightDirectory)); //overwriting a later wxCombobox::SetValue()!!! :( //clear existing additional folder pairs clearAddFolderPairs(); @@ -2034,8 +2085,8 @@ void MainDialog::setCurrentConfiguration(const xmlAccess::XmlGuiConfig& newGuiCf inline FolderPairEnh getEnahncedPair(const FolderPairPanel* panel) { - return FolderPairEnh(wxToZ(panel->m_directoryLeft->GetValue()), - wxToZ(panel->m_directoryRight->GetValue()), + return FolderPairEnh(panel->getLeftDir(), + panel->getRightDir(), panel->getAltSyncConfig(), panel->getAltFilterConfig()); } @@ -2047,15 +2098,19 @@ xmlAccess::XmlGuiConfig MainDialog::getCurrentConfiguration() const //load settings whose ownership lies not in currentCfg: - //main folder pair - guiCfg.mainCfg.mainFolderPair.leftDirectory = wxToZ(m_directoryLeft->GetValue()); - guiCfg.mainCfg.mainFolderPair.rightDirectory = wxToZ(m_directoryRight->GetValue()); + //first folder pair + guiCfg.mainCfg.firstPair = FolderPairEnh(firstFolderPair->getLeftDir(), + firstFolderPair->getRightDir(), + firstFolderPair->getAltSyncConfig(), + firstFolderPair->getAltFilterConfig()); //add additional pairs guiCfg.mainCfg.additionalPairs.clear(); std::transform(additionalFolderPairs.begin(), additionalFolderPairs.end(), std::back_inserter(guiCfg.mainCfg.additionalPairs), getEnahncedPair); + //filter active status + guiCfg.mainCfg.filterIsActive = m_checkBoxActivateFilter->GetValue(); //sync preview guiCfg.syncPreviewEnabled = syncPreview.previewIsEnabled(); @@ -2096,12 +2151,10 @@ void MainDialog::refreshGridAfterFilterChange(const int delay) void MainDialog::OnFilterButton(wxCommandEvent &event) { - //toggle filter on/off - currentCfg.mainCfg.filterIsActive = !currentCfg.mainCfg.filterIsActive; - //make sure, button-appearance and "filterIsActive" are in sync. - updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive); + //make sure, button-appearance and "m_checkBoxActivateFilter" are in sync. + updateFilterButtons(); - updateFilterConfig(false); //refresh filtering (without changing active-status) + updateFilterConfig(); //refresh filtering } @@ -2120,19 +2173,20 @@ void MainDialog::OnHideFilteredButton(wxCommandEvent &event) } -void MainDialog::OnConfigureFilter(wxHyperlinkEvent &event) +void MainDialog::OnConfigureFilter(wxCommandEvent &event) { - FilterDlg* filterDlg = new FilterDlg(this, currentCfg.mainCfg.includeFilter, currentCfg.mainCfg.excludeFilter); + FilterDlg* filterDlg = new FilterDlg(this, + true, //is main filter dialog + currentCfg.mainCfg.includeFilter, + currentCfg.mainCfg.excludeFilter, + m_checkBoxActivateFilter->GetValue()); if (filterDlg->ShowModal() == FilterDlg::BUTTON_APPLY) { - if (currentCfg.mainCfg.includeFilter == defaultIncludeFilter() && - currentCfg.mainCfg.excludeFilter == defaultExcludeFilter()) //default - updateFilterConfig(false); //re-apply filter (without changing active-status) - else - updateFilterConfig(true); //activate(and apply) filter + updateFilterButtons(); //refresh global filter icon + updateFilterConfig(); //re-apply filter } - //no event.Skip() here, to not start browser + //event.Skip() } @@ -2328,30 +2382,56 @@ void MainDialog::initViewFilterButtons() } -void MainDialog::updateFilterButton(wxBitmapButton* filterButton, bool isActive) +void MainDialog::updateFilterButtons() { - if (isActive) + //prepare filter icon + if (m_notebookBottomLeft->GetImageList() == NULL) { - filterButton->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterOn); - filterButton->SetToolTip(_("Filter active: Press again to deactivate")); + wxImageList* panelIcons = new wxImageList(16, 16); + panelIcons->Add(wxBitmap(*GlobalResources::getInstance().bitmapFilterSmall)); + panelIcons->Add(wxBitmap(*GlobalResources::getInstance().bitmapFilterSmallGrey)); + m_notebookBottomLeft->AssignImageList(panelIcons); //pass ownership + } - //show filter icon - if (m_notebookBottomLeft->GetImageList() == NULL) + //global filter + if (m_checkBoxActivateFilter->GetValue()) //filter active? + { + //test for Null-filter + const bool isNullFilter = NameFilter(currentCfg.mainCfg.includeFilter, currentCfg.mainCfg.excludeFilter).isNull(); + if (isNullFilter) { - wxImageList* panelIcons = new wxImageList(16, 16); - panelIcons->Add(wxBitmap(*GlobalResources::getInstance().bitmapFilterSmall)); - m_notebookBottomLeft->AssignImageList(panelIcons); //pass ownership + m_bpButtonFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterOff); + m_bpButtonFilter->SetToolTip(_("No filter selected")); + + //additional filter icon + m_notebookBottomLeft->SetPageImage(1, 1); } - m_notebookBottomLeft->SetPageImage(1, 0); + else + { + m_bpButtonFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterOn); + m_bpButtonFilter->SetToolTip(_("Filter has been selected")); + //show filter icon + m_notebookBottomLeft->SetPageImage(1, 0); + } } else { - filterButton->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterOff); - filterButton->SetToolTip(_("Press button to activate filter")); + m_bpButtonFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterOff); + m_bpButtonFilter->SetToolTip(_("Filtering is deactivated")); - //hide filter icon - m_notebookBottomLeft->SetPageImage(1, -1); + //additional filter icon + m_notebookBottomLeft->SetPageImage(1, 1); + } + + //update main local filter + firstFolderPair->refreshButtons(); + + //update folder pairs + for (std::vector<FolderPairPanel*>::const_iterator i = additionalFolderPairs.begin(); i != additionalFolderPairs.end(); ++i) + { + FolderPairPanel* dirPair = *i; + dirPair->refreshButtons(); } } @@ -2400,6 +2480,7 @@ void MainDialog::OnCompare(wxCommandEvent &event) //disable the sync button syncPreview.enableSynchronization(false); m_buttonCompare->SetFocus(); + updateGuiGrid(); //refresh grid in ANY case! (also on abort) } else { @@ -2421,12 +2502,15 @@ void MainDialog::OnCompare(wxCommandEvent &event) m_gridRight-> ClearSelection(); //add to folder history after successful comparison only - addLeftFolderToHistory(m_directoryLeft->GetValue()); + addLeftFolderToHistory( m_directoryLeft->GetValue()); addRightFolderToHistory(m_directoryRight->GetValue()); - } - //refresh grid in ANY case! (also on abort) - updateGuiGrid(); + //refresh grid in ANY case! (also on abort) + updateGuiGrid(); + + if (allElementsEqual(gridDataView->getDataTentative())) + pushStatusInformation(_("All directories in sync!")); + } } @@ -2545,73 +2629,82 @@ void MainDialog::OnCmpSettings(wxCommandEvent& event) void MainDialog::OnStartSync(wxCommandEvent& event) { - if (syncPreview.synchronizationIsEnabled()) + if (!syncPreview.synchronizationIsEnabled()) { - //show sync preview screen - if (globalSettings.optDialogs.showSummaryBeforeSync) - { - bool dontShowAgain = false; + pushStatusInformation(_("Please run a Compare first before synchronizing!")); + return; + } - SyncPreviewDlg* preview = new SyncPreviewDlg( - this, - getCurrentConfiguration().mainCfg.getSyncVariantName(), - FreeFileSync::SyncStatistics(gridDataView->getDataTentative()), - dontShowAgain); + //show sync preview screen + if (globalSettings.optDialogs.showSummaryBeforeSync) + { + bool dontShowAgain = false; - if (preview->ShowModal() != SyncPreviewDlg::BUTTON_START) - return; + SyncPreviewDlg* preview = new SyncPreviewDlg( + this, + getCurrentConfiguration().mainCfg.getSyncVariantName(), + FreeFileSync::SyncStatistics(gridDataView->getDataTentative()), + dontShowAgain); - globalSettings.optDialogs.showSummaryBeforeSync = !dontShowAgain; - } - - //check if there are files/folders to be sync'ed at all - if (!synchronizationNeeded(gridDataView->getDataTentative())) - { - wxMessageBox(_("Nothing to synchronize according to configuration!"), _("Information"), wxICON_WARNING); + if (preview->ShowModal() != SyncPreviewDlg::BUTTON_START) return; - } - wxBusyCursor dummy; //show hourglass cursor + globalSettings.optDialogs.showSummaryBeforeSync = !dontShowAgain; + } - clearStatusBar(); - try - { - //PERF_START; + //check if there are files/folders to be sync'ed at all + if (!synchronizationNeeded(gridDataView->getDataTentative())) + { + wxMessageBox(_("Nothing to synchronize according to configuration!"), _("Information"), wxICON_WARNING); + return; + } - //class handling status updates and error messages - SyncStatusHandler statusHandler(this, currentCfg.ignoreErrors); + wxBusyCursor dummy; //show hourglass cursor - //start synchronization and mark all elements processed - FreeFileSync::SyncProcess synchronization( - currentCfg.mainCfg.hidden.copyFileSymlinks, - currentCfg.mainCfg.hidden.traverseDirectorySymlinks, - globalSettings.optDialogs, - currentCfg.mainCfg.hidden.verifyFileCopy, - statusHandler); + clearStatusBar(); + try + { + //PERF_START; - const std::vector<FreeFileSync::FolderPairSyncCfg> syncProcessCfg = FreeFileSync::extractSyncCfg(getCurrentConfiguration().mainCfg); - FolderComparison& dataToSync = gridDataView->getDataTentative(); + //class handling status updates and error messages + SyncStatusHandler statusHandler(this, currentCfg.ignoreErrors); - //make sure syncProcessCfg and dataToSync have same size and correspond! - if (syncProcessCfg.size() != dataToSync.size()) - throw std::logic_error("Programming Error: Contract violation!"); //should never happen: sync button is deactivated if they are not in sync + //start synchronization and mark all elements processed + FreeFileSync::SyncProcess synchronization( + currentCfg.mainCfg.hidden.copyFileSymlinks, + currentCfg.mainCfg.hidden.traverseDirectorySymlinks, + globalSettings.optDialogs, + currentCfg.mainCfg.hidden.verifyFileCopy, + globalSettings.copyLockedFiles, + statusHandler); - synchronization.startSynchronizationProcess(syncProcessCfg, dataToSync); - } - catch (AbortThisProcess&) - { - //do NOT disable the sync button: user might want to try to sync the REMAINING rows - } //enableSynchronization(false); + const std::vector<FreeFileSync::FolderPairSyncCfg> syncProcessCfg = FreeFileSync::extractSyncCfg(getCurrentConfiguration().mainCfg); + FolderComparison& dataToSync = gridDataView->getDataTentative(); - //remove rows that empty: just a beautification, invalid rows shouldn't cause issues - gridDataView->removeInvalidRows(); + //make sure syncProcessCfg and dataToSync have same size and correspond! + if (syncProcessCfg.size() != dataToSync.size()) + throw std::logic_error("Programming Error: Contract violation!"); //should never happen: sync button is deactivated if they are not in sync - updateGuiGrid(); + synchronization.startSynchronizationProcess(syncProcessCfg, dataToSync); - m_gridLeft-> ClearSelection(); - m_gridMiddle->ClearSelection(); - m_gridRight-> ClearSelection(); + //play (optional) sound notification after sync has completed (GUI and batch mode) + const wxString soundFile = FreeFileSync::getInstallationDir() + wxT("Sync_Complete.wav"); + if (fileExists(wxToZ(soundFile))) + wxSound::Play(soundFile, wxSOUND_ASYNC); } + catch (AbortThisProcess&) + { + //do NOT disable the sync button: user might want to try to sync the REMAINING rows + } //enableSynchronization(false); + + //remove rows that empty: just a beautification, invalid rows shouldn't cause issues + gridDataView->removeInvalidRows(); + + updateGuiGrid(); + + m_gridLeft-> ClearSelection(); + m_gridMiddle->ClearSelection(); + m_gridRight-> ClearSelection(); } @@ -2651,7 +2744,7 @@ void MainDialog::OnSortLeftGrid(wxGridEvent& event) switch (columnType) { case xmlAccess::FULL_PATH: - gridDataView->sortView(GridView::SORT_BY_DIRECTORY, true, sortAscending); + gridDataView->sortView(GridView::SORT_BY_REL_NAME, true, sortAscending); break; case xmlAccess::FILENAME: gridDataView->sortView(GridView::SORT_BY_FILENAME, true, sortAscending); @@ -2726,7 +2819,7 @@ void MainDialog::OnSortRightGrid(wxGridEvent& event) switch (columnType) { case xmlAccess::FULL_PATH: - gridDataView->sortView(GridView::SORT_BY_DIRECTORY, false, sortAscending); + gridDataView->sortView(GridView::SORT_BY_REL_NAME, false, sortAscending); break; case xmlAccess::FILENAME: gridDataView->sortView(GridView::SORT_BY_FILENAME, false, sortAscending); @@ -2757,22 +2850,20 @@ void MainDialog::OnSortRightGrid(wxGridEvent& event) void MainDialog::OnSwapSides(wxCommandEvent& event) { - //swap directory names: main pair - const wxString leftDir = m_directoryLeft->GetValue(); - const wxString rightDir = m_directoryRight->GetValue(); - m_directoryLeft->SetSelection(wxNOT_FOUND); - m_directoryRight->SetSelection(wxNOT_FOUND); - - m_directoryLeft->SetValue(rightDir); - m_directoryRight->SetValue(leftDir); + //swap directory names: first pair + firstFolderPair->setValues(firstFolderPair->getRightDir(), // swap directories + firstFolderPair->getLeftDir(), // + firstFolderPair->getAltSyncConfig(), + firstFolderPair->getAltFilterConfig()); //additional pairs for (std::vector<FolderPairPanel*>::const_iterator i = additionalFolderPairs.begin(); i != additionalFolderPairs.end(); ++i) { FolderPairPanel* dirPair = *i; - wxString tmp = dirPair->m_directoryLeft->GetValue(); - dirPair->m_directoryLeft->SetValue(dirPair->m_directoryRight->GetValue()); - dirPair->m_directoryRight->SetValue(tmp); + dirPair->setValues(dirPair->getRightDir(), // swap directories + dirPair->getLeftDir(), // + dirPair->getAltSyncConfig(), + dirPair->getAltFilterConfig()); } //swap view filter @@ -2800,7 +2891,6 @@ void MainDialog::OnSwapSides(wxCommandEvent& event) //swap grid information FreeFileSync::swapGrids(getCurrentConfiguration().mainCfg, gridDataView->getDataTentative()); updateGuiGrid(); - event.Skip(); } @@ -2923,10 +3013,9 @@ void MainDialog::updateGridViewData() bSizer3->Layout(); - //update status information - while (stackObjects.size() > 0) - stackObjects.pop(); + clearStatusBar(); + wxString statusLeftNew; wxString statusMiddleNew; @@ -2969,7 +3058,8 @@ void MainDialog::updateGridViewData() statusLeftNew += FreeFileSync::formatFilesizeToShortString(filesizeLeftView); } - const wxString objectsView = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(gridDataView->rowsOnView())); + const wxString objectsView = FreeFileSync::includeNumberSeparator( + globalFunctions::numberToWxString(static_cast<unsigned int>(gridDataView->rowsOnView()))); if (gridDataView->rowsTotal() == 1) { wxString outputString = _("%x of 1 row in view"); @@ -2978,7 +3068,8 @@ void MainDialog::updateGridViewData() } else { - const wxString objectsTotal = FreeFileSync::includeNumberSeparator(globalFunctions::numberToWxString(gridDataView->rowsTotal())); + const wxString objectsTotal = FreeFileSync::includeNumberSeparator( + globalFunctions::numberToWxString(static_cast<unsigned int>(gridDataView->rowsTotal()))); wxString outputString = _("%x of %y rows in view"); outputString.Replace(wxT("%x"), objectsView, false); @@ -3038,45 +3129,36 @@ void MainDialog::OnAddFolderPair(wxCommandEvent& event) wxWindowUpdateLocker dummy(this); //avoid display distortion std::vector<FolderPairEnh> newPairs; - newPairs.push_back( - FolderPairEnh(Zstring(), - Zstring(), - boost::shared_ptr<AlternateSyncConfig>(), - boost::shared_ptr<AlternateFilter>())); + newPairs.push_back(getCurrentConfiguration().mainCfg.firstPair); - addFolderPair(newPairs, false); //add pair at the end of additional pairs + addFolderPair(newPairs, true); //add pair in front of additonal pairs - FreeFileSync::scrollToBottom(m_scrolledWindowFolderPairs); + //clear first pair + const FolderPairEnh cfgEmpty; + firstFolderPair->setValues(cfgEmpty.leftDirectory, + cfgEmpty.rightDirectory, + cfgEmpty.altSyncConfig, + cfgEmpty.localFilter); //disable the sync button syncPreview.enableSynchronization(false); //clear grids gridDataView->clearAllRows(); - updateGuiGrid(); + updateSyncConfig(); //mainly to update sync dir description text } -void MainDialog::updateFilterConfig(bool activateFilter) //true: activate filter false: stay as it is +void MainDialog::updateFilterConfig() { - if (activateFilter) - { - //activate filter (if not yet active) - if (!currentCfg.mainCfg.filterIsActive) - { - currentCfg.mainCfg.filterIsActive = true; - updateFilterButton(m_bpButtonFilter, currentCfg.mainCfg.filterIsActive); - } - } - - if (currentCfg.mainCfg.filterIsActive) + if (m_checkBoxActivateFilter->GetValue()) { applyFiltering(getCurrentConfiguration().mainCfg, gridDataView->getDataTentative()); refreshGridAfterFilterChange(400); } else { - FilterProcess::setActiveStatus(true, gridDataView->getDataTentative()); + FreeFileSync::setActiveStatus(true, gridDataView->getDataTentative()); refreshGridAfterFilterChange(0); } } @@ -3119,21 +3201,47 @@ void MainDialog::updateSyncConfig() } +void MainDialog::OnRemoveTopFolderPair(wxCommandEvent& event) +{ + if (additionalFolderPairs.size() > 0) + { + //get settings from second folder pair + const FolderPairEnh cfgSecond = getEnahncedPair(additionalFolderPairs[0]); + + //reset first pair + firstFolderPair->setValues(cfgSecond.leftDirectory, + cfgSecond.rightDirectory, + cfgSecond.altSyncConfig, + cfgSecond.localFilter); + + removeAddFolderPair(0); //remove second folder pair (first of additional folder pairs) + +//------------------------------------------------------------------ + //disable the sync button + syncPreview.enableSynchronization(false); + + //clear grids + gridDataView->clearAllRows(); + updateSyncConfig(); //mainly to update sync dir description text + } +} + + void MainDialog::OnRemoveFolderPair(wxCommandEvent& event) { const wxObject* const eventObj = event.GetEventObject(); //find folder pair originating the event for (std::vector<FolderPairPanel*>::const_iterator i = additionalFolderPairs.begin(); i != additionalFolderPairs.end(); ++i) - if (eventObj == static_cast<wxObject*>((*i)->m_bpButtonRemovePair)) + if (eventObj == (*i)->m_bpButtonRemovePair) { removeAddFolderPair(i - additionalFolderPairs.begin()); +//------------------------------------------------------------------ //disable the sync button syncPreview.enableSynchronization(false); //clear grids gridDataView->clearAllRows(); - - updateSyncConfig(); + updateSyncConfig(); //mainly to update sync dir description text return; } } @@ -3142,63 +3250,94 @@ void MainDialog::OnRemoveFolderPair(wxCommandEvent& event) const size_t MAX_ADD_FOLDER_PAIRS = 5; -void MainDialog::addFolderPair(const std::vector<FolderPairEnh>& newPairs, bool addFront) +void MainDialog::updateGuiForFolderPair() { - if (newPairs.size() == 0) - return; + //adapt delete top folder pair button + if (additionalFolderPairs.size() == 0) + m_bpButtonRemovePair->Hide(); + else + m_bpButtonRemovePair->Show(); - wxWindowUpdateLocker dummy(this); //avoid display distortion + m_panelTopRight->Layout(); - int pairHeight = 0; - for (std::vector<FolderPairEnh>::const_iterator i = newPairs.begin(); i != newPairs.end(); ++i) + //adapt local filter and sync cfg for first folder pair + if ( additionalFolderPairs.size() == 0 && + firstFolderPair->getAltSyncConfig().get() == NULL && + NameFilter(firstFolderPair->getAltFilterConfig().includeFilter, + firstFolderPair->getAltFilterConfig().excludeFilter).isNull()) { - //add new folder pair - FolderPairPanel* newPair = new FolderPairPanel(m_scrolledWindowFolderPairs, this); + m_bpButtonLocalFilter->Hide(); + m_bpButtonAltSyncCfg->Hide(); - //correct width of middle block - newPair->m_panel21->SetMinSize(wxSize(m_gridMiddle->GetSize().GetWidth(), -1)); + m_bpButtonSwapSides->SetBitmapLabel(*GlobalResources::getInstance().bitmapSwap); + } + else + { + m_bpButtonLocalFilter->Show(); + m_bpButtonAltSyncCfg->Show(); - //set width of left folder panel - const int width = m_panelTopLeft->GetSize().GetWidth(); - newPair->m_panelLeft->SetMinSize(wxSize(width, -1)); + m_bpButtonSwapSides->SetBitmapLabel(*GlobalResources::getInstance().bitmapSwapSlim); + } + m_panelTopMiddle->Layout(); +} - if (addFront) - { - bSizerAddFolderPairs->Insert(0, newPair, 0, wxEXPAND, 5); - additionalFolderPairs.insert(additionalFolderPairs.begin(), newPair); - } - else + +void MainDialog::addFolderPair(const std::vector<FolderPairEnh>& newPairs, bool addFront) +{ + wxWindowUpdateLocker dummy(this); //avoid display distortion + + if (!newPairs.empty()) + { + int pairHeight = 0; + for (std::vector<FolderPairEnh>::const_iterator i = newPairs.begin(); i != newPairs.end(); ++i) { - bSizerAddFolderPairs->Add(newPair, 0, wxEXPAND, 5); - additionalFolderPairs.push_back(newPair); - } + //add new folder pair + FolderPairPanel* newPair = new FolderPairPanel(m_scrolledWindowFolderPairs, *this); - //get size of scrolled window - pairHeight = newPair->GetSize().GetHeight(); + //correct width of middle block + newPair->m_panel21->SetMinSize(wxSize(m_gridMiddle->GetSize().GetWidth(), -1)); - //register events - newPair->m_bpButtonRemovePair->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainDialog::OnRemoveFolderPair), NULL, this); + //set width of left folder panel + const int width = m_panelTopLeft->GetSize().GetWidth(); + newPair->m_panelLeft->SetMinSize(wxSize(width, -1)); - //insert directory names - FreeFileSync::setDirectoryName(zToWx(i->leftDirectory), newPair->m_directoryLeft, newPair->m_dirPickerLeft); - FreeFileSync::setDirectoryName(zToWx(i->rightDirectory), newPair->m_directoryRight, newPair->m_dirPickerRight); - //set alternate configuration - newPair->setValues(i->altSyncConfig, i->altFilter); - } + if (addFront) + { + bSizerAddFolderPairs->Insert(0, newPair, 0, wxEXPAND, 5); + additionalFolderPairs.insert(additionalFolderPairs.begin(), newPair); + } + else + { + bSizerAddFolderPairs->Add(newPair, 0, wxEXPAND, 5); + additionalFolderPairs.push_back(newPair); + } - //set size of scrolled window - const int visiblePairs = std::min(additionalFolderPairs.size(), MAX_ADD_FOLDER_PAIRS); //up to MAX_ADD_FOLDER_PAIRS additional pairs shall be shown - m_scrolledWindowFolderPairs->SetMinSize(wxSize( -1, pairHeight * visiblePairs)); + //get size of scrolled window + pairHeight = newPair->GetSize().GetHeight(); - //update controls - m_scrolledWindowFolderPairs->Fit(); //adjust scrolled window size - m_scrolledWindowFolderPairs->Layout(); //adjust stuff inside scrolled window - bSizer1->Layout(); + //register events + newPair->m_bpButtonRemovePair->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MainDialog::OnRemoveFolderPair), NULL, this); + + //set alternate configuration + newPair->setValues(i->leftDirectory, + i->rightDirectory, + i->altSyncConfig, + i->localFilter); + } - //scroll to the bottom of wxScrolledWindow - //scrollToBottom(m_scrolledWindowFolderPairs); + //set size of scrolled window + const int visiblePairs = std::min(additionalFolderPairs.size(), MAX_ADD_FOLDER_PAIRS); //up to MAX_ADD_FOLDER_PAIRS additional pairs shall be shown + m_scrolledWindowFolderPairs->SetMinSize(wxSize( -1, pairHeight * visiblePairs)); + + //update controls + m_scrolledWindowFolderPairs->Fit(); //adjust scrolled window size + m_scrolledWindowFolderPairs->Layout(); //adjust stuff inside scrolled window + bSizer1->Layout(); + } + + updateGuiForFolderPair(); } @@ -3226,6 +3365,8 @@ void MainDialog::removeAddFolderPair(const unsigned int pos) m_scrolledWindowFolderPairs->Layout(); //adjust stuff inside scrolled window bSizer1->Layout(); } + + updateGuiForFolderPair(); } @@ -3416,6 +3557,13 @@ void MainDialog::OnMenuAbout(wxCommandEvent& event) } + +void MainDialog::OnShowHelp(wxCommandEvent& event) +{ + helpController_.DisplayContents(); +} + + void MainDialog::OnMenuQuit(wxCommandEvent& event) { if (!saveOldConfig()) //notify user about changed settings @@ -3435,7 +3583,7 @@ void MainDialog::switchProgramLanguage(const int langID) cleanUp(); //destructor's code: includes writing settings to HD //create new dialog with respect to new language - MainDialog* frame = new MainDialog(NULL, wxEmptyString, globalSettings); + MainDialog* frame = new MainDialog(NULL, wxEmptyString, globalSettings, helpController_); frame->SetIcon(*GlobalResources::getInstance().programIcon); //set application icon frame->Show(); @@ -3511,3 +3659,7 @@ bool MainDialog::SyncPreview::synchronizationIsEnabled() const { return synchronizationEnabled; } + + + + diff --git a/ui/MainDialog.h b/ui/MainDialog.h index 30f018ad..61f1537f 100644 --- a/ui/MainDialog.h +++ b/ui/MainDialog.h @@ -14,6 +14,7 @@ #include <memory> #include <map> #include <set> +#include <wx/help.h> class CompareStatusHandler; class CompareStatus; @@ -24,6 +25,7 @@ class FFSSyncDirectionEvent; class IconUpdater; class ManualDeletionHandler; class FolderPairPanel; +class FirstFolderPairCfg; namespace FreeFileSync @@ -38,7 +40,8 @@ class MainDialog : public MainDialogGenerated friend class CompareStatusHandler; friend class ManualDeletionHandler; friend class MainFolderDragDrop; - friend class FolderPairPanel; + template <class GuiPanel> + friend class FolderPairCallback; //IDs for context menu items enum ContextIDRim //context menu for left and right grids @@ -78,7 +81,8 @@ class MainDialog : public MainDialogGenerated public: MainDialog(wxFrame* frame, const wxString& cfgFileName, - xmlAccess::XmlGlobalSettings& settings); + xmlAccess::XmlGlobalSettings& settings, + wxHelpController& helpController); ~MainDialog(); @@ -102,7 +106,7 @@ private: void writeGlobalSettings(); void initViewFilterButtons(); - void updateFilterButton(wxBitmapButton* filterButton, bool isActive); + void updateFilterButtons(); void addFileToCfgHistory(const wxString& filename); void addLeftFolderToHistory(const wxString& leftFolder); @@ -112,6 +116,8 @@ private: void removeAddFolderPair(const unsigned int pos); void clearAddFolderPairs(); +void updateGuiForFolderPair(); //helper method: add usability by showing/hiding buttons related to folder pairs + //main method for putting gridDataView on UI: updates data respecting current view settings void updateGuiGrid(); void updateGridViewData(); @@ -203,7 +209,6 @@ private: void loadConfiguration(const wxString& filename); void OnCfgHistoryKeyEvent( wxKeyEvent& event); - void OnFolderHistoryKeyEvent(wxKeyEvent& event); void OnRegularUpdateCheck( wxIdleEvent& event); void OnLayoutWindowAsync( wxIdleEvent& event); @@ -213,7 +218,7 @@ private: void OnResizeFolderPairs( wxSizeEvent& event); void OnFilterButton( wxCommandEvent& event); void OnHideFilteredButton( wxCommandEvent& event); - void OnConfigureFilter( wxHyperlinkEvent& event); + void OnConfigureFilter( wxCommandEvent& event); void OnSwapSides( wxCommandEvent& event); void OnCompare( wxCommandEvent& event); void OnSwitchView( wxCommandEvent& event); @@ -227,8 +232,9 @@ private: void OnAddFolderPair( wxCommandEvent& event); void OnRemoveFolderPair( wxCommandEvent& event); + void OnRemoveTopFolderPair( wxCommandEvent& event); - void updateFilterConfig(bool activateFilter); + void updateFilterConfig(); void updateSyncConfig(); //menu events @@ -237,6 +243,7 @@ private: void OnMenuBatchJob( wxCommandEvent& event); void OnMenuCheckVersion( wxCommandEvent& event); void OnMenuAbout( wxCommandEvent& event); + void OnShowHelp( wxCommandEvent& event); void OnMenuQuit( wxCommandEvent& event); void OnMenuLanguageSwitch( wxCommandEvent& event); @@ -260,8 +267,8 @@ private: xmlAccess::XmlGuiConfig currentCfg; //folder pairs: - //m_directoryLeft, m_directoryRight - std::vector<FolderPairPanel*> additionalFolderPairs; //additional pairs to the standard pair + std::auto_ptr<FirstFolderPairCfg> firstFolderPair; //always bound!!! + std::vector<FolderPairPanel*> additionalFolderPairs; //additional pairs to the first pair //gui settings int widthNotMaximized; @@ -291,15 +298,14 @@ private: int lastSortColumn; const wxGrid* lastSortGrid; - //support for drag and drop - std::auto_ptr<MainFolderDragDrop> dragDropOnLeft; - std::auto_ptr<MainFolderDragDrop> dragDropOnRight; - #ifdef FFS_WIN //update icons periodically: one updater instance for both left and right grids std::auto_ptr<IconUpdater> updateFileIcons; #endif + //global help controller + wxHelpController& helpController_; + //encapsulation of handling of sync preview class SyncPreview //encapsulates MainDialog functionality for synchronization preview (friend class) { diff --git a/ui/SmallDialogs.cpp b/ui/SmallDialogs.cpp index 4999a0e7..74678244 100644 --- a/ui/SmallDialogs.cpp +++ b/ui/SmallDialogs.cpp @@ -114,9 +114,6 @@ HelpDlg::HelpDlg(wxWindow* window) : HelpDlgGenerated(window) } -HelpDlg::~HelpDlg() {} - - void HelpDlg::OnClose(wxCloseEvent& event) { Destroy(); @@ -127,17 +124,22 @@ void HelpDlg::OnOK(wxCommandEvent& event) { Destroy(); } -//######################################################################################## -FilterDlg::FilterDlg(wxWindow* window, Zstring& filterIncl, Zstring& filterExcl) : +//######################################################################################## +FilterDlg::FilterDlg(wxWindow* window, + bool isGlobalFilter, //global or local filter dialog? + Zstring& filterIncl, + Zstring& filterExcl, + bool filterActive) : FilterDlgGenerated(window), + isGlobalFilter_(isGlobalFilter), includeFilter(filterIncl), excludeFilter(filterExcl) { m_bitmap8->SetBitmap(*GlobalResources::getInstance().bitmapInclude); m_bitmap9->SetBitmap(*GlobalResources::getInstance().bitmapExclude); - m_bitmap26->SetBitmap(*GlobalResources::getInstance().bitmapFilter); + m_bitmap26->SetBitmap(*GlobalResources::getInstance().bitmapFilterOn); m_bpButtonHelp->SetBitmapLabel(*GlobalResources::getInstance().bitmapHelp); m_textCtrlInclude->SetValue(zToWx(includeFilter)); @@ -146,6 +148,15 @@ FilterDlg::FilterDlg(wxWindow* window, Zstring& filterIncl, Zstring& filterExcl) m_panel13->Hide(); m_button10->SetFocus(); + if (filterActive) + m_staticTextFilteringInactive->Hide(); + + //adapt header for global/local dialog + if (isGlobalFilter_) + m_staticTexHeader->SetLabel(_("Global filter")); + else + m_staticTexHeader->SetLabel(_("Local filter")); + Fit(); } @@ -163,8 +174,19 @@ void FilterDlg::OnHelp(wxCommandEvent& event) void FilterDlg::OnDefault(wxCommandEvent& event) { - m_textCtrlInclude->SetValue(zToWx(defaultIncludeFilter())); - m_textCtrlExclude->SetValue(zToWx(defaultExcludeFilter())); + const FilterConfig nullFilter; + + if (isGlobalFilter_) + { + m_textCtrlInclude->SetValue(zToWx(nullFilter.includeFilter)); + //exclude various recycle bin directories with global filter + m_textCtrlExclude->SetValue(zToWx(standardExcludeFilter())); + } + else + { + m_textCtrlInclude->SetValue(zToWx(nullFilter.includeFilter)); + m_textCtrlExclude->SetValue(zToWx(nullFilter.excludeFilter)); + } //changes to mainDialog are only committed when the OK button is pressed Fit(); @@ -636,6 +658,8 @@ CompareCfgDialog::CompareCfgDialog(wxWindow* parentWindow, const wxPoint& positi Move(wxPoint(position.x, std::max(0, position.y - (m_buttonTimeSize->GetScreenPosition() - GetScreenPosition()).y))); m_bpButtonHelp->SetBitmapLabel(*GlobalResources::getInstance().bitmapHelp); + m_bitmapByTime->SetBitmap(*GlobalResources::getInstance().bitmapCmpByTime); + m_bitmapByContent->SetBitmap(*GlobalResources::getInstance().bitmapCmpByContent); switch (cmpVar) { @@ -648,6 +672,7 @@ CompareCfgDialog::CompareCfgDialog(wxWindow* parentWindow, const wxPoint& positi m_buttonTimeSize->SetFocus(); //set focus on the other button break; } + Fit(); } @@ -695,12 +720,18 @@ GlobalSettingsDlg::GlobalSettingsDlg(wxWindow* window, xmlAccess::XmlGlobalSetti m_bpButtonRemoveRow->SetBitmapLabel(*GlobalResources::getInstance().bitmapRemoveFolderPair); m_checkBoxIgnoreOneHour->SetValue(globalSettings.ignoreOneHourDiff); + m_checkBoxCopyLocked->SetValue(globalSettings.copyLockedFiles); + +#ifndef FFS_WIN +m_staticTextCopyLocked->Hide(); +m_checkBoxCopyLocked->Hide(); +#endif set(globalSettings.gui.externelApplications); const wxString toolTip = wxString(_("Integrate external applications into context menu. The following macros are available:")) + wxT("\n\n") + wxT("%name \t") + _("- full file or directory name") + wxT("\n") + - wxT("%dir \t") + _("- directory part only") + wxT("\n") + + wxT("%dir \t") + _("- directory part only") + wxT("\n") + wxT("%nameCo \t") + _("- Other side's counterpart to %name") + wxT("\n") + wxT("%dirCo \t") + _("- Other side's counterpart to %dir"); @@ -717,6 +748,7 @@ void GlobalSettingsDlg::OnOkay(wxCommandEvent& event) { //write global settings only when okay-button is pressed! settings.ignoreOneHourDiff = m_checkBoxIgnoreOneHour->GetValue(); + settings.copyLockedFiles = m_checkBoxCopyLocked->GetValue(); settings.gui.externelApplications = getExtApp(); @@ -740,6 +772,7 @@ void GlobalSettingsDlg::OnDefault(wxCommandEvent& event) xmlAccess::XmlGlobalSettings defaultCfg; m_checkBoxIgnoreOneHour->SetValue(defaultCfg.ignoreOneHourDiff); + m_checkBoxCopyLocked->SetValue(defaultCfg.copyLockedFiles); set(defaultCfg.gui.externelApplications); } @@ -762,7 +795,7 @@ void GlobalSettingsDlg::set(const xmlAccess::ExternalApps& extApp) if (rowCount > 0) m_gridCustomCommand->DeleteRows(0, rowCount); - m_gridCustomCommand->AppendRows(extApp.size()); + m_gridCustomCommand->AppendRows(static_cast<int>(extApp.size())); for (xmlAccess::ExternalApps::const_iterator i = extApp.begin(); i != extApp.end(); ++i) { const int row = i - extApp.begin(); @@ -919,10 +952,10 @@ void CompareStatus::updateStatusPanelNow() if (*i == wxChar('\n')) *i = wxChar(' '); - //status texts + //status texts if (m_textCtrlStatus->GetValue() != formattedStatusText && (screenChanged = true)) //avoid screen flicker m_textCtrlStatus->SetValue(formattedStatusText); - + //nr of scanned objects const wxString scannedObjTmp = globalFunctions::numberToWxString(scannedObjects); if (m_staticTextScanned->GetLabel() != scannedObjTmp && (screenChanged = true)) //avoid screen flicker @@ -942,7 +975,7 @@ void CompareStatus::updateStatusPanelNow() m_staticTextDataRemaining->SetLabel(remainingBytesTmp); if (statistics.get()) - { + { if (timeElapsed.Time() - lastStatCallSpeed >= 500) //call method every 500 ms { lastStatCallSpeed = timeElapsed.Time(); @@ -1014,8 +1047,14 @@ SyncStatus::SyncStatus(StatusHandler* updater, wxWindow* parentWindow) : if (mainDialog) //disable (main) window while this status dialog is shown mainDialog->Disable(); - SetIcon(*GlobalResources::getInstance().programIcon); //set application icon timeElapsed.Start(); //measure total time + + + SetIcon(*GlobalResources::getInstance().programIcon); //set application icon + + //register key event + Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(SyncStatus::OnKeyPressed), NULL, this); + } @@ -1033,6 +1072,16 @@ SyncStatus::~SyncStatus() } +void SyncStatus::OnKeyPressed(wxKeyEvent& event) +{ + const int keyCode = event.GetKeyCode(); + if (keyCode == WXK_ESCAPE) + Close(); //generate close event: do NOT destroy window unconditionally! + + event.Skip(); +} + + void SyncStatus::resetGauge(int totalObjectsToProcess, wxLongLong totalDataToProcess) { currentData = 0; diff --git a/ui/SmallDialogs.h b/ui/SmallDialogs.h index ca22afa9..22a271c9 100644 --- a/ui/SmallDialogs.h +++ b/ui/SmallDialogs.h @@ -33,7 +33,6 @@ class HelpDlg : public HelpDlgGenerated { public: HelpDlg(wxWindow* window); - ~HelpDlg(); private: void OnClose(wxCloseEvent& event); @@ -44,7 +43,11 @@ private: class FilterDlg : public FilterDlgGenerated { public: - FilterDlg(wxWindow* window, Zstring& filterIncl, Zstring& filterExcl); + FilterDlg(wxWindow* window, + bool isGlobalFilter, + Zstring& filterIncl, + Zstring& filterExcl, + bool filterActive); ~FilterDlg() {} enum @@ -59,6 +62,7 @@ private: void OnCancel(wxCommandEvent& event); void OnClose(wxCloseEvent& event); + const bool isGlobalFilter_; Zstring& includeFilter; Zstring& excludeFilter; }; @@ -324,6 +328,7 @@ public: void minimizeToTray(); private: + void OnKeyPressed(wxKeyEvent& event); virtual void OnOkay(wxCommandEvent& event); virtual void OnPause(wxCommandEvent& event); virtual void OnAbort(wxCommandEvent& event); diff --git a/ui/folderPair.h b/ui/folderPair.h index e495995e..557f3cc6 100644 --- a/ui/folderPair.h +++ b/ui/folderPair.h @@ -6,99 +6,127 @@ #include "../library/resources.h" #include "smallDialogs.h" #include "settingsDialog.h" +#include <wx/event.h> namespace FreeFileSync { -//basic functionality for changing alternate folder pair configuration: adaptable to generated gui class +//basic functionality for handling alternate folder pair configuration: change sync-cfg/filter cfg, right-click context menu, button icons... template <class GuiPanel> -class FolderPairPanelBasic : public GuiPanel +class FolderPairPanelBasic : private wxEvtHandler { - using GuiPanel::m_bpButtonAltSyncCfg; - using GuiPanel::m_bpButtonAltFilter; - public: - FolderPairPanelBasic(wxWindow* parent) : - GuiPanel(parent), - dragDropOnLeft(new DragDropOnDlg( GuiPanel::m_panelLeft, GuiPanel::m_dirPickerLeft, GuiPanel::m_directoryLeft)), - dragDropOnRight(new DragDropOnDlg(GuiPanel::m_panelRight, GuiPanel::m_dirPickerRight, GuiPanel::m_directoryRight)) - { - //register events for removal of alternate configuration - m_bpButtonAltFilter->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(FolderPairPanelBasic::OnAltFilterCfgRemove), NULL, this); - m_bpButtonAltSyncCfg->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(FolderPairPanelBasic::OnAltSyncCfgRemove), NULL, this); + typedef boost::shared_ptr<const FreeFileSync::AlternateSyncConfig> AltSyncCfgPtr; - m_bpButtonAltSyncCfg->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FolderPairPanelBasic::OnAltSyncCfg), NULL, this); - m_bpButtonAltFilter-> Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FolderPairPanelBasic::OnAltFilterCfg), NULL, this); - GuiPanel::m_bpButtonRemovePair->SetBitmapLabel(*GlobalResources::getInstance().bitmapRemoveFolderPair); + Zstring getLeftDir() const + { + return wxToZ(basicPanel_.m_directoryLeft->GetValue()); } - typedef boost::shared_ptr<const FreeFileSync::AlternateSyncConfig> AltSyncCfgPtr; - typedef boost::shared_ptr<const FreeFileSync::AlternateFilter> AltFilterPtr; + Zstring getRightDir() const + { + return wxToZ(basicPanel_.m_directoryRight->GetValue()); + } AltSyncCfgPtr getAltSyncConfig() const { return altSyncConfig; } - AltFilterPtr getAltFilterConfig() const + FilterConfig getAltFilterConfig() const { - return altFilter; + return localFilter; } - void setValues(AltSyncCfgPtr syncCfg, AltFilterPtr filter) + void setValues(const Zstring& leftDir, + const Zstring& rightDir, + AltSyncCfgPtr syncCfg, + const FilterConfig& filter) { altSyncConfig = syncCfg; - altFilter = filter; + localFilter = filter; + + //insert directory names + FreeFileSync::setDirectoryName(zToWx(leftDir), basicPanel_.m_directoryLeft, basicPanel_.m_dirPickerLeft); + FreeFileSync::setDirectoryName(zToWx(rightDir), basicPanel_.m_directoryRight, basicPanel_.m_dirPickerRight); - updateAltButtonColor(); + refreshButtons(); } + void refreshButtons() + { + if (altSyncConfig.get()) + { + basicPanel_.m_bpButtonAltSyncCfg->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncCfgSmall); + basicPanel_.m_bpButtonAltSyncCfg->SetToolTip(wxString(_("Select alternate synchronization settings")) + wxT(" ") + globalFunctions::LINE_BREAK + + wxT("(") + altSyncConfig->syncConfiguration.getVariantName() + wxT(")")); + } + else + { + basicPanel_.m_bpButtonAltSyncCfg->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncCfgSmallGrey); + basicPanel_.m_bpButtonAltSyncCfg->SetToolTip(_("Select alternate synchronization settings")); + } + + + if (getMainConfig().filterIsActive) + { + //test for Null-filter + const bool isNullFilter = NameFilter(localFilter.includeFilter, localFilter.excludeFilter).isNull(); + if (isNullFilter) + { + basicPanel_.m_bpButtonLocalFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterSmallGrey); + basicPanel_.m_bpButtonLocalFilter->SetToolTip(_("No filter selected")); + } + else + { + basicPanel_.m_bpButtonLocalFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterSmall); + basicPanel_.m_bpButtonLocalFilter->SetToolTip(_("Filter has been selected")); + } + } + else + { + basicPanel_.m_bpButtonLocalFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterSmallGrey); + basicPanel_.m_bpButtonLocalFilter->SetToolTip(_("Filtering is deactivated")); + } + } + protected: - virtual void OnAltFilterCfgRemoveConfirm(wxCommandEvent& event) + FolderPairPanelBasic(GuiPanel& basicPanel) : //takes reference on basic panel to be enhanced + basicPanel_(basicPanel) + { + //register events for removal of alternate configuration + basicPanel_.m_bpButtonAltSyncCfg->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(FolderPairPanelBasic::OnAltSyncCfgRemove), NULL, this); + basicPanel_.m_bpButtonLocalFilter->Connect(wxEVT_RIGHT_DOWN, wxCommandEventHandler(FolderPairPanelBasic::OnLocalFilterCfgRemove), NULL, this); + + basicPanel_.m_bpButtonAltSyncCfg-> Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FolderPairPanelBasic::OnAltSyncCfg), NULL, this); + basicPanel_.m_bpButtonLocalFilter->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FolderPairPanelBasic::OnLocalFilterCfg), NULL, this); + + basicPanel_.m_bpButtonRemovePair->SetBitmapLabel(*GlobalResources::getInstance().bitmapRemoveFolderPair); + } + + virtual void OnLocalFilterCfgRemoveConfirm(wxCommandEvent& event) { - altFilter.reset(); - updateAltButtonColor(); + localFilter = FilterConfig(); + refreshButtons(); } virtual void OnAltSyncCfgRemoveConfirm(wxCommandEvent& event) { altSyncConfig.reset(); - updateAltButtonColor(); + refreshButtons(); } private: - void updateAltButtonColor() - { - if (altSyncConfig.get()) - m_bpButtonAltSyncCfg->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncCfgSmall); - else - m_bpButtonAltSyncCfg->SetBitmapLabel(*GlobalResources::getInstance().bitmapSyncCfgSmallGrey); - - if (altFilter.get()) - m_bpButtonAltFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterSmall); - else - m_bpButtonAltFilter->SetBitmapLabel(*GlobalResources::getInstance().bitmapFilterSmallGrey); - - //set tooltips - if (altSyncConfig.get()) - m_bpButtonAltSyncCfg->SetToolTip(wxString(_("Select alternate synchronization settings")) + wxT(" \n") + - wxT("(") + altSyncConfig->syncConfiguration.getVariantName() + wxT(")")); - else - m_bpButtonAltSyncCfg->SetToolTip(_("Select alternate synchronization settings")); - - m_bpButtonAltFilter->SetToolTip(_("Select alternate filter settings")); - } - - void OnAltFilterCfgRemove(wxCommandEvent& event) + void OnLocalFilterCfgRemove(wxCommandEvent& event) { contextMenu.reset(new wxMenu); //re-create context menu - contextMenu->Append(wxID_ANY, _("Remove alternate settings")); - contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(FolderPairPanelBasic::OnAltFilterCfgRemoveConfirm), NULL, this); - GuiPanel::PopupMenu(contextMenu.get()); //show context menu + contextMenu->Append(wxID_ANY, _("Remove local filter settings")); + contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(FolderPairPanelBasic::OnLocalFilterCfgRemoveConfirm), NULL, this); + basicPanel_.PopupMenu(contextMenu.get()); //show context menu } void OnAltSyncCfgRemove(wxCommandEvent& event) @@ -106,7 +134,7 @@ private: contextMenu.reset(new wxMenu); //re-create context menu contextMenu->Append(wxID_ANY, _("Remove alternate settings")); contextMenu->Connect(wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(FolderPairPanelBasic::OnAltSyncCfgRemoveConfirm), NULL, this); - GuiPanel::PopupMenu(contextMenu.get()); //show context menu + basicPanel_.PopupMenu(contextMenu.get()); //show context menu } virtual MainConfiguration getMainConfig() const = 0; @@ -131,46 +159,42 @@ private: if (syncDlg->ShowModal() == SyncCfgDialog::BUTTON_APPLY) { altSyncConfig.reset(new AlternateSyncConfig(altSyncCfg)); - updateAltButtonColor(); + refreshButtons(); OnAltSyncCfgChange(); } } - virtual void OnAltFilterCfgChange(bool defaultValueSet) {}; + virtual void OnLocalFilterCfgChange() {}; - void OnAltFilterCfg(wxCommandEvent& event) + void OnLocalFilterCfg(wxCommandEvent& event) { - const MainConfiguration mainCfg = getMainConfig(); - const AlternateFilter filterMain(mainCfg.includeFilter, mainCfg.excludeFilter); - - AlternateFilter altFilt = altFilter.get() ? *altFilter : filterMain; - FilterDlg* filterDlg = new FilterDlg(getParentWindow(), altFilt.includeFilter, altFilt.excludeFilter); + FilterConfig localFiltTmp = localFilter; + FilterDlg* filterDlg = new FilterDlg(getParentWindow(), + false, //is local filter dialog + localFiltTmp.includeFilter, + localFiltTmp.excludeFilter, + getMainConfig().filterIsActive); if (filterDlg->ShowModal() == FilterDlg::BUTTON_APPLY) { - altFilter.reset(new AlternateFilter(altFilt)); - updateAltButtonColor(); + localFilter = localFiltTmp; + refreshButtons(); - if ( altFilt.includeFilter == defaultIncludeFilter() && - altFilt.excludeFilter == defaultExcludeFilter()) //default - OnAltFilterCfgChange(true); - else - OnAltFilterCfgChange(false); + OnLocalFilterCfgChange(); } } + GuiPanel& basicPanel_; //panel to be enhanced by this template + //alternate configuration attached to it - AltSyncCfgPtr altSyncConfig; //optional - AltFilterPtr altFilter; //optional + AltSyncCfgPtr altSyncConfig; //optional: present if non-NULL + FilterConfig localFilter; std::auto_ptr<wxMenu> contextMenu; - - //support for drag and drop - std::auto_ptr<DragDropOnDlg> dragDropOnLeft; - std::auto_ptr<DragDropOnDlg> dragDropOnRight; }; } #endif // FOLDERPAIR_H_INCLUDED + diff --git a/ui/guiGenerated.cpp b/ui/guiGenerated.cpp index fdc4f72d..9670c775 100644 --- a/ui/guiGenerated.cpp +++ b/ui/guiGenerated.cpp @@ -7,6 +7,7 @@ #include "../library/customGrid.h" #include "../shared/customButton.h" +#include "../shared/customComboBox.h" #include "../shared/toggleButton.h" #include "guiGenerated.h" @@ -68,13 +69,17 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_menubar1->Append( m_menuAdvanced, _("&Advanced") ); m_menuHelp = new wxMenu(); + wxMenuItem* m_menuItemReadme; + m_menuItemReadme = new wxMenuItem( m_menuHelp, wxID_ANY, wxString( _("&Content") ) + wxT('\t') + wxT("F1"), wxEmptyString, wxITEM_NORMAL ); + m_menuHelp->Append( m_menuItemReadme ); + wxMenuItem* m_menuItemCheckVer; m_menuItemCheckVer = new wxMenuItem( m_menuHelp, wxID_ANY, wxString( _("&Check for new version") ) , wxEmptyString, wxITEM_NORMAL ); m_menuHelp->Append( m_menuItemCheckVer ); m_menuHelp->AppendSeparator(); - m_menuItemAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( _("&About...") ) + wxT('\t') + wxT("F1"), wxEmptyString, wxITEM_NORMAL ); + m_menuItemAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( _("&About...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuHelp->Append( m_menuItemAbout ); m_menubar1->Append( m_menuHelp, _("&Help") ); @@ -182,7 +187,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const sbSizer2 = new wxStaticBoxSizer( new wxStaticBox( m_panelTopLeft, wxID_ANY, _("Drag && drop") ), wxHORIZONTAL ); - m_directoryLeft = new wxComboBox( m_panelTopLeft, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); + m_directoryLeft = new CustomComboBox( m_panelTopLeft, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); sbSizer2->Add( m_directoryLeft, 1, wxALIGN_CENTER_VERTICAL, 5 ); m_dirPickerLeft = new wxDirPickerCtrl( m_panelTopLeft, wxID_ANY, wxEmptyString, _("Select a folder"), wxDefaultPosition, wxDefaultSize, 0 ); @@ -195,7 +200,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_panelTopLeft->SetSizer( bSizer92 ); m_panelTopLeft->Layout(); bSizer92->Fit( m_panelTopLeft ); - bSizer91->Add( m_panelTopLeft, 1, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer91->Add( m_panelTopLeft, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_panelTopMiddle = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bSizer93; @@ -206,7 +211,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizerMiddle = new wxBoxSizer( wxHORIZONTAL ); - m_bpButtonSwapSides = new wxBitmapButton( m_panelTopMiddle, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 42,42 ), wxBU_AUTODRAW ); + m_bpButtonSwapSides = new wxBitmapButton( m_panelTopMiddle, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW ); m_bpButtonSwapSides->SetToolTip( _("Swap sides") ); m_bpButtonSwapSides->SetToolTip( _("Swap sides") ); @@ -215,6 +220,26 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizer93->Add( bSizerMiddle, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); + wxBoxSizer* bSizer160; + bSizer160 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer160->Add( 0, 0, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_bpButtonLocalFilter = new wxBitmapButton( m_panelTopMiddle, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); + bSizer160->Add( m_bpButtonLocalFilter, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer160->Add( 5, 0, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + m_bpButtonAltSyncCfg = new wxBitmapButton( m_panelTopMiddle, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); + bSizer160->Add( m_bpButtonAltSyncCfg, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer160->Add( 0, 0, 1, wxEXPAND, 5 ); + + bSizer93->Add( bSizer160, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + m_panelTopMiddle->SetSizer( bSizer93 ); m_panelTopMiddle->Layout(); bSizer93->Fit( m_panelTopMiddle ); @@ -237,7 +262,14 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const sbSizer3->Add( m_bpButtonAddPair, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 3 ); - m_directoryRight = new wxComboBox( m_panelTopRight, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); + m_bpButtonRemovePair = new wxBitmapButton( m_panelTopRight, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 19,21 ), wxBU_AUTODRAW ); + m_bpButtonRemovePair->SetToolTip( _("Remove folder pair") ); + + m_bpButtonRemovePair->SetToolTip( _("Remove folder pair") ); + + sbSizer3->Add( m_bpButtonRemovePair, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + m_directoryRight = new CustomComboBox( m_panelTopRight, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); sbSizer3->Add( m_directoryRight, 1, wxALIGN_CENTER_VERTICAL, 5 ); m_dirPickerRight = new wxDirPickerCtrl( m_panelTopRight, wxID_ANY, wxEmptyString, _("Select a folder"), wxDefaultPosition, wxDefaultSize, 0 ); @@ -252,7 +284,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_panelTopRight->SetSizer( bSizer94 ); m_panelTopRight->Layout(); bSizer94->Fit( m_panelTopRight ); - bSizer91->Add( m_panelTopRight, 1, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer91->Add( m_panelTopRight, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer1->Add( bSizer91, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 ); @@ -333,7 +365,7 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const // Label Appearance // Cell Defaults - m_gridMiddle->SetDefaultCellFont( wxFont( 12, 74, 90, 92, false, wxT("Arial") ) ); + m_gridMiddle->SetDefaultCellFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxT("Arial") ) ); m_gridMiddle->SetDefaultCellAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); bSizer18->Add( m_gridMiddle, 1, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP|wxBOTTOM, 5 ); @@ -426,19 +458,19 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const wxBoxSizer* bSizer23; bSizer23 = new wxBoxSizer( wxVERTICAL ); - m_hyperlinkCfgFilter = new wxHyperlinkCtrl( m_panelFilter, wxID_ANY, _("Configure filter..."), wxEmptyString, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_checkBoxActivateFilter = new wxCheckBox( m_panelFilter, wxID_ANY, _("Activate filter"), wxDefaultPosition, wxDefaultSize, 0 ); - m_hyperlinkCfgFilter->SetNormalColour( wxColour( 0, 0, 255 ) ); - m_hyperlinkCfgFilter->SetVisitedColour( wxColour( 0, 0, 255 ) ); - bSizer23->Add( m_hyperlinkCfgFilter, 0, wxALL, 5 ); + m_checkBoxActivateFilter->SetToolTip( _("Enable filter to exclude files from synchronization") ); - m_checkBoxHideFilt = new wxCheckBox( m_panelFilter, wxID_ANY, _("Hide filtered items"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer23->Add( m_checkBoxActivateFilter, 0, wxBOTTOM, 5 ); - m_checkBoxHideFilt->SetToolTip( _("Choose to hide filtered files/directories from list") ); + m_checkBoxHideFilt = new wxCheckBox( m_panelFilter, wxID_ANY, _("Hide excluded items"), wxDefaultPosition, wxDefaultSize, 0 ); + + m_checkBoxHideFilt->SetToolTip( _("Hide filtered or temporarily excluded files") ); bSizer23->Add( m_checkBoxHideFilt, 0, 0, 5 ); - bSizer140->Add( bSizer23, 0, 0, 5 ); + bSizer140->Add( bSizer23, 0, wxALIGN_CENTER_VERTICAL, 5 ); m_panelFilter->SetSizer( bSizer140 ); m_panelFilter->Layout(); @@ -594,8 +626,10 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const bSizerBottomRight->Add( m_panelSyncPreview, 0, wxALIGN_CENTER_VERTICAL, 5 ); m_bpButton10 = new wxBitmapButton( m_panelBottom, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 50,50 ), wxBU_AUTODRAW ); + m_bpButton10->Hide(); m_bpButton10->SetToolTip( _("Quit") ); + m_bpButton10->Hide(); m_bpButton10->SetToolTip( _("Quit") ); bSizerBottomRight->Add( m_bpButton10, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT, 5 ); @@ -692,17 +726,17 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const this->Connect( m_menuItemGlobSett->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuGlobalSettings ) ); this->Connect( m_menuItem7->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuBatchJob ) ); this->Connect( m_menuItem5->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuExportFileList ) ); + this->Connect( m_menuItemReadme->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnShowHelp ) ); this->Connect( m_menuItemCheckVer->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuCheckVersion ) ); this->Connect( m_menuItemAbout->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuAbout ) ); m_buttonCompare->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnCompare ), NULL, this ); m_bpButtonCmpConfig->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnCmpSettings ), NULL, this ); m_bpButtonSyncConfig->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncSettings ), NULL, this ); m_buttonStartSync->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnStartSync ), NULL, this ); - m_directoryLeft->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( MainDialogGenerated::OnFolderHistoryKeyEvent ), NULL, this ); m_dirPickerLeft->Connect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( MainDialogGenerated::OnDirSelected ), NULL, this ); m_bpButtonSwapSides->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSwapSides ), NULL, this ); m_bpButtonAddPair->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnAddFolderPair ), NULL, this ); - m_directoryRight->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( MainDialogGenerated::OnFolderHistoryKeyEvent ), NULL, this ); + m_bpButtonRemovePair->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnRemoveTopFolderPair ), NULL, this ); m_dirPickerRight->Connect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( MainDialogGenerated::OnDirSelected ), NULL, this ); m_gridLeft->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( MainDialogGenerated::OnLeftGridDoubleClick ), NULL, this ); m_gridLeft->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( MainDialogGenerated::OnContextRim ), NULL, this ); @@ -719,8 +753,8 @@ MainDialogGenerated::MainDialogGenerated( wxWindow* parent, wxWindowID id, const m_bpButtonLoad->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnLoadConfig ), NULL, this ); m_choiceHistory->Connect( wxEVT_CHAR, wxKeyEventHandler( MainDialogGenerated::OnCfgHistoryKeyEvent ), NULL, this ); m_choiceHistory->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnLoadFromHistory ), NULL, this ); - m_bpButtonFilter->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnFilterButton ), NULL, this ); - m_hyperlinkCfgFilter->Connect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( MainDialogGenerated::OnConfigureFilter ), NULL, this ); + m_bpButtonFilter->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnConfigureFilter ), NULL, this ); + m_checkBoxActivateFilter->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnFilterButton ), NULL, this ); m_checkBoxHideFilt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnHideFilteredButton ), NULL, this ); m_bpButtonLeftOnly->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnLeftOnlyFiles ), NULL, this ); m_bpButtonLeftNewer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnLeftNewerFiles ), NULL, this ); @@ -753,17 +787,17 @@ MainDialogGenerated::~MainDialogGenerated() this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuGlobalSettings ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuBatchJob ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuExportFileList ) ); + this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnShowHelp ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuCheckVersion ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnMenuAbout ) ); m_buttonCompare->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnCompare ), NULL, this ); m_bpButtonCmpConfig->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnCmpSettings ), NULL, this ); m_bpButtonSyncConfig->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSyncSettings ), NULL, this ); m_buttonStartSync->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnStartSync ), NULL, this ); - m_directoryLeft->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( MainDialogGenerated::OnFolderHistoryKeyEvent ), NULL, this ); m_dirPickerLeft->Disconnect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( MainDialogGenerated::OnDirSelected ), NULL, this ); m_bpButtonSwapSides->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnSwapSides ), NULL, this ); m_bpButtonAddPair->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnAddFolderPair ), NULL, this ); - m_directoryRight->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( MainDialogGenerated::OnFolderHistoryKeyEvent ), NULL, this ); + m_bpButtonRemovePair->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnRemoveTopFolderPair ), NULL, this ); m_dirPickerRight->Disconnect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( MainDialogGenerated::OnDirSelected ), NULL, this ); m_gridLeft->Disconnect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( MainDialogGenerated::OnLeftGridDoubleClick ), NULL, this ); m_gridLeft->Disconnect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( MainDialogGenerated::OnContextRim ), NULL, this ); @@ -780,8 +814,8 @@ MainDialogGenerated::~MainDialogGenerated() m_bpButtonLoad->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnLoadConfig ), NULL, this ); m_choiceHistory->Disconnect( wxEVT_CHAR, wxKeyEventHandler( MainDialogGenerated::OnCfgHistoryKeyEvent ), NULL, this ); m_choiceHistory->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( MainDialogGenerated::OnLoadFromHistory ), NULL, this ); - m_bpButtonFilter->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnFilterButton ), NULL, this ); - m_hyperlinkCfgFilter->Disconnect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( MainDialogGenerated::OnConfigureFilter ), NULL, this ); + m_bpButtonFilter->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnConfigureFilter ), NULL, this ); + m_checkBoxActivateFilter->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnFilterButton ), NULL, this ); m_checkBoxHideFilt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnHideFilteredButton ), NULL, this ); m_bpButtonLeftOnly->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnLeftOnlyFiles ), NULL, this ); m_bpButtonLeftNewer->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainDialogGenerated::OnLeftNewerFiles ), NULL, this ); @@ -829,7 +863,7 @@ FolderPairGenerated::FolderPairGenerated( wxWindow* parent, wxWindowID id, const bSizer95 = new wxBoxSizer( wxHORIZONTAL ); m_panel21 = new wxPanel( m_panel20, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - m_panel21->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); + m_panel21->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) ); wxBoxSizer* bSizer96; bSizer96 = new wxBoxSizer( wxHORIZONTAL ); @@ -837,8 +871,11 @@ FolderPairGenerated::FolderPairGenerated( wxWindow* parent, wxWindowID id, const bSizer96->Add( 0, 0, 1, wxEXPAND, 5 ); - m_bpButtonAltFilter = new wxBitmapButton( m_panel21, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); - bSizer96->Add( m_bpButtonAltFilter, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 ); + m_bpButtonLocalFilter = new wxBitmapButton( m_panel21, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); + bSizer96->Add( m_bpButtonLocalFilter, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer96->Add( 5, 0, 0, wxALIGN_CENTER_VERTICAL, 5 ); m_bpButtonAltSyncCfg = new wxBitmapButton( m_panel21, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); bSizer96->Add( m_bpButtonAltSyncCfg, 0, wxALIGN_CENTER_VERTICAL, 5 ); @@ -960,8 +997,8 @@ BatchFolderPairGenerated::BatchFolderPairGenerated( wxWindow* parent, wxWindowID bSizer114->Add( m_dirPickerLeft, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_bpButtonAltFilter = new wxBitmapButton( m_panelLeft, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); - bSizer114->Add( m_bpButtonAltFilter, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_bpButtonLocalFilter = new wxBitmapButton( m_panelLeft, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); + bSizer114->Add( m_bpButtonLocalFilter, 0, wxALIGN_CENTER_VERTICAL, 5 ); m_panelLeft->SetSizer( bSizer114 ); m_panelLeft->Layout(); @@ -1085,7 +1122,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer147 = new wxBoxSizer( wxHORIZONTAL ); wxBoxSizer* bSizer1361; - bSizer1361 = new wxBoxSizer( wxVERTICAL ); + bSizer1361 = new wxBoxSizer( wxHORIZONTAL ); m_bpButtonAddPair = new wxBitmapButton( m_panelMainPair, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 19,21 ), wxBU_AUTODRAW ); m_bpButtonAddPair->SetToolTip( _("Add folder pair") ); @@ -1094,6 +1131,13 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer1361->Add( m_bpButtonAddPair, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 3 ); + m_bpButtonRemovePair = new wxBitmapButton( m_panelMainPair, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 19,21 ), wxBU_AUTODRAW ); + m_bpButtonRemovePair->SetToolTip( _("Remove folder pair") ); + + m_bpButtonRemovePair->SetToolTip( _("Remove folder pair") ); + + bSizer1361->Add( m_bpButtonRemovePair, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + bSizer147->Add( bSizer1361, 0, wxALIGN_CENTER_VERTICAL, 5 ); wxBoxSizer* bSizer143; @@ -1143,6 +1187,9 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer1141->Add( m_dirPickerLeft, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_bpButtonLocalFilter = new wxBitmapButton( m_panelLeft, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); + bSizer1141->Add( m_bpButtonLocalFilter, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_panelLeft->SetSizer( bSizer1141 ); m_panelLeft->Layout(); bSizer1141->Fit( m_panelLeft ); @@ -1160,6 +1207,9 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS bSizer115->Add( m_dirPickerRight, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_bpButtonAltSyncCfg = new wxBitmapButton( m_panelRight, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 20,20 ), wxBU_AUTODRAW ); + bSizer115->Add( m_bpButtonAltSyncCfg, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_panelRight->SetSizer( bSizer115 ); m_panelRight->Layout(); bSizer115->Fit( m_panelRight ); @@ -1220,7 +1270,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS sbSizer24->Add( m_checkBoxAutomatic, 0, wxALL, 5 ); - m_checkBoxFilter = new wxCheckBox( m_panelOverview, wxID_ANY, _("Filter files"), wxDefaultPosition, wxDefaultSize, 0 ); + m_checkBoxFilter = new wxCheckBox( m_panelOverview, wxID_ANY, _("Activate filter"), wxDefaultPosition, wxDefaultSize, 0 ); m_checkBoxFilter->SetToolTip( _("Enable filter to exclude files from synchronization") ); @@ -1228,7 +1278,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS m_checkBoxSilent = new wxCheckBox( m_panelOverview, wxID_ANY, _("Silent mode"), wxDefaultPosition, wxDefaultSize, 0 ); - m_checkBoxSilent->SetToolTip( _("Do not display visual status information but write to a logfile instead") ); + m_checkBoxSilent->SetToolTip( _("Run minimized and write status information to a logfile") ); sbSizer24->Add( m_checkBoxSilent, 0, wxALL, 5 ); @@ -1542,6 +1592,7 @@ BatchDlgGenerated::BatchDlgGenerated( wxWindow* parent, wxWindowID id, const wxS // Connect Events this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( BatchDlgGenerated::OnClose ) ); m_bpButtonAddPair->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnAddFolderPair ), NULL, this ); + m_bpButtonRemovePair->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnRemoveTopFolderPair ), NULL, this ); m_radioBtnSizeDate->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( BatchDlgGenerated::OnChangeCompareVar ), NULL, this ); m_radioBtnContent->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( BatchDlgGenerated::OnChangeCompareVar ), NULL, this ); m_checkBoxAutomatic->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnCheckAutomatic ), NULL, this ); @@ -1565,6 +1616,7 @@ BatchDlgGenerated::~BatchDlgGenerated() // Disconnect Events this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( BatchDlgGenerated::OnClose ) ); m_bpButtonAddPair->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnAddFolderPair ), NULL, this ); + m_bpButtonRemovePair->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnRemoveTopFolderPair ), NULL, this ); m_radioBtnSizeDate->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( BatchDlgGenerated::OnChangeCompareVar ), NULL, this ); m_radioBtnContent->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( BatchDlgGenerated::OnChangeCompareVar ), NULL, this ); m_checkBoxAutomatic->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( BatchDlgGenerated::OnCheckAutomatic ), NULL, this ); @@ -1767,7 +1819,7 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const fgSizer1->Add( m_buttonAutomatic, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - m_staticText81 = new wxStaticText( this, wxID_ANY, _("Synchronize both sides using a database. Deletions are detected automatically."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText81 = new wxStaticText( this, wxID_ANY, _("Identify and propagate changes on both sides using a database. Deletions and conflicts are detected automatically."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText81->Wrap( 300 ); fgSizer1->Add( m_staticText81, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); @@ -1801,16 +1853,20 @@ SyncCfgDlgGenerated::SyncCfgDlgGenerated( wxWindow* parent, wxWindowID id, const m_radioBtnTwoWay = new wxRadioButton( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_radioBtnTwoWay->SetFont( wxFont( 11, 74, 90, 92, false, wxT("Tahoma") ) ); + m_radioBtnTwoWay->Hide(); fgSizer1->Add( m_radioBtnTwoWay, 0, wxALIGN_CENTER_VERTICAL, 5 ); m_buttonTwoWay = new wxButton( this, wxID_ANY, _("Two way <->"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); m_buttonTwoWay->SetFont( wxFont( 11, 74, 90, 92, false, wxT("Tahoma") ) ); + m_buttonTwoWay->Hide(); fgSizer1->Add( m_buttonTwoWay, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); m_staticText10 = new wxStaticText( this, wxID_ANY, _("Synchronize both sides simultaneously: Copy new or updated files in both directions."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText10->Wrap( 300 ); + m_staticText10->Hide(); + fgSizer1->Add( m_staticText10, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); m_radioBtnCustom = new wxRadioButton( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); @@ -2107,7 +2163,7 @@ CmpCfgDlgGenerated::CmpCfgDlgGenerated( wxWindow* parent, wxWindowID id, const w sbSizer6 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Compare by...") ), wxHORIZONTAL ); wxFlexGridSizer* fgSizer16; - fgSizer16 = new wxFlexGridSizer( 2, 2, 0, 0 ); + fgSizer16 = new wxFlexGridSizer( 2, 3, 0, 0 ); fgSizer16->SetFlexibleDirection( wxBOTH ); fgSizer16->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); @@ -2117,22 +2173,32 @@ CmpCfgDlgGenerated::CmpCfgDlgGenerated( wxWindow* parent, wxWindowID id, const w fgSizer16->Add( m_radioBtnSizeDate, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_buttonTimeSize = new wxButton( this, wxID_ANY, _("File size and date"), wxDefaultPosition, wxSize( -1,40 ), 0 ); + m_bitmapByTime = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); + m_bitmapByTime->SetToolTip( _("Files are found equal if\n - filesize\n - last write time and date\nare the same.") ); + + fgSizer16->Add( m_bitmapByTime, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_buttonTimeSize = new wxButton( this, wxID_ANY, _("File size and date"), wxDefaultPosition, wxSize( -1,42 ), 0 ); m_buttonTimeSize->SetFont( wxFont( 11, 74, 90, 92, false, wxT("Tahoma") ) ); m_buttonTimeSize->SetToolTip( _("Files are found equal if\n - filesize\n - last write time and date\nare the same.") ); - fgSizer16->Add( m_buttonTimeSize, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + fgSizer16->Add( m_buttonTimeSize, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, 5 ); m_radioBtnContent = new wxRadioButton( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_radioBtnContent->SetToolTip( _("Files are found equal if\n - file content\nis the same.") ); fgSizer16->Add( m_radioBtnContent, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_buttonContent = new wxButton( this, wxID_ANY, _("File content"), wxDefaultPosition, wxSize( -1,40 ), 0 ); + m_bitmapByContent = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); + m_bitmapByContent->SetToolTip( _("Files are found equal if\n - file content\nis the same.") ); + + fgSizer16->Add( m_bitmapByContent, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_buttonContent = new wxButton( this, wxID_ANY, _("File content"), wxDefaultPosition, wxSize( -1,42 ), 0 ); m_buttonContent->SetFont( wxFont( 11, 74, 90, 92, false, wxT("Tahoma") ) ); m_buttonContent->SetToolTip( _("Files are found equal if\n - file content\nis the same.") ); - fgSizer16->Add( m_buttonContent, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + fgSizer16->Add( m_buttonContent, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); sbSizer6->Add( fgSizer16, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); @@ -2186,8 +2252,8 @@ CmpCfgDlgGenerated::~CmpCfgDlgGenerated() SyncStatusDlgGenerated::SyncStatusDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style ) { - this->SetSizeHints( wxDefaultSize, wxDefaultSize ); - this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); + this->SetSizeHints( wxSize( 470,300 ), wxDefaultSize ); + this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) ); wxBoxSizer* bSizer27; bSizer27 = new wxBoxSizer( wxVERTICAL ); @@ -2575,6 +2641,79 @@ HelpDlgGenerated::~HelpDlgGenerated() m_button8->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( HelpDlgGenerated::OnOK ), NULL, this ); } +ReadmeDlgGenerated::ReadmeDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer20; + bSizer20 = new wxBoxSizer( wxVERTICAL ); + + + bSizer20->Add( 0, 10, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer85; + bSizer85 = new wxBoxSizer( wxHORIZONTAL ); + + m_bitmap25 = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 40,40 ), 0 ); + bSizer85->Add( m_bitmap25, 1, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_panel8 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER|wxTAB_TRAVERSAL ); + m_panel8->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DLIGHT ) ); + + wxBoxSizer* bSizer72; + bSizer72 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer72->Add( 20, 0, 0, 0, 5 ); + + m_staticText56 = new wxStaticText( m_panel8, wxID_ANY, _("&Readme.txt"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText56->Wrap( -1 ); + m_staticText56->SetFont( wxFont( 16, 74, 90, 92, false, wxT("Tahoma") ) ); + + bSizer72->Add( m_staticText56, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer72->Add( 20, 0, 0, 0, 5 ); + + m_panel8->SetSizer( bSizer72 ); + m_panel8->Layout(); + bSizer72->Fit( m_panel8 ); + bSizer85->Add( m_panel8, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + + bSizer85->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer20->Add( bSizer85, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_textCtrlMain = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_RICH ); + m_textCtrlMain->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Courier") ) ); + m_textCtrlMain->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_INACTIVEBORDER ) ); + + bSizer20->Add( m_textCtrlMain, 1, wxALL|wxEXPAND, 5 ); + + m_buttonOkay = new wxButton( this, wxID_OK, _("&OK"), wxDefaultPosition, wxSize( 100,32 ), 0 ); + m_buttonOkay->SetDefault(); + m_buttonOkay->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); + + bSizer20->Add( m_buttonOkay, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + this->SetSizer( bSizer20 ); + this->Layout(); + + this->Centre( wxBOTH ); + + // Connect Events + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( ReadmeDlgGenerated::OnClose ) ); + m_buttonOkay->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ReadmeDlgGenerated::OnOK ), NULL, this ); +} + +ReadmeDlgGenerated::~ReadmeDlgGenerated() +{ + // Disconnect Events + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( ReadmeDlgGenerated::OnClose ) ); + m_buttonOkay->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ReadmeDlgGenerated::OnOK ), NULL, this ); +} + AboutDlgGenerated::AboutDlgGenerated( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) { this->SetSizeHints( wxDefaultSize, wxDefaultSize ); @@ -3112,11 +3251,11 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w wxBoxSizer* bSizer72; bSizer72 = new wxBoxSizer( wxVERTICAL ); - m_staticText56 = new wxStaticText( m_panel8, wxID_ANY, _("Filter files"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText56->Wrap( -1 ); - m_staticText56->SetFont( wxFont( 16, 74, 90, 92, false, wxT("Tahoma") ) ); + m_staticTexHeader = new wxStaticText( m_panel8, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTexHeader->Wrap( -1 ); + m_staticTexHeader->SetFont( wxFont( 16, 74, 90, 92, false, wxT("Tahoma") ) ); - bSizer72->Add( m_staticText56, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); + bSizer72->Add( m_staticTexHeader, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 ); m_panel8->SetSizer( bSizer72 ); m_panel8->Layout(); @@ -3202,6 +3341,13 @@ FilterDlgGenerated::FilterDlgGenerated( wxWindow* parent, wxWindowID id, const w bSizer69->Fit( m_panel13 ); bSizer21->Add( m_panel13, 0, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxEXPAND, 5 ); + m_staticTextFilteringInactive = new wxStaticText( this, wxID_ANY, _("Filtering is deactivated"), wxDefaultPosition, wxDefaultSize, 0|wxRAISED_BORDER ); + m_staticTextFilteringInactive->Wrap( -1 ); + m_staticTextFilteringInactive->SetFont( wxFont( 12, 74, 90, 92, false, wxT("Arial Black") ) ); + m_staticTextFilteringInactive->SetForegroundColour( wxColour( 255, 0, 0 ) ); + + bSizer21->Add( m_staticTextFilteringInactive, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); + wxStaticBoxSizer* sbSizer8; sbSizer8 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxEmptyString ), wxVERTICAL ); @@ -3447,7 +3593,27 @@ GlobalSettingsDlgGenerated::GlobalSettingsDlgGenerated( wxWindow* parent, wxWind bSizer120->Add( m_checkBoxIgnoreOneHour, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - sbSizer23->Add( bSizer120, 1, wxEXPAND, 5 ); + sbSizer23->Add( bSizer120, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer1201; + bSizer1201 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticTextCopyLocked = new wxStaticText( this, wxID_ANY, _("Copy locked files"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextCopyLocked->Wrap( -1 ); + m_staticTextCopyLocked->SetToolTip( _("Use Volume Shadow Copy Service to copy locked or shared files.") ); + + bSizer1201->Add( m_staticTextCopyLocked, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer1201->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_checkBoxCopyLocked = new wxCheckBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + + m_checkBoxCopyLocked->SetToolTip( _("Use Volume Shadow Copy Service to copy locked or shared files.") ); + + bSizer1201->Add( m_checkBoxCopyLocked, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + sbSizer23->Add( bSizer1201, 0, wxEXPAND, 5 ); m_staticline10 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); sbSizer23->Add( m_staticline10, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxTOP|wxBOTTOM, 5 ); diff --git a/ui/guiGenerated.h b/ui/guiGenerated.h index f51a5f41..70cce976 100644 --- a/ui/guiGenerated.h +++ b/ui/guiGenerated.h @@ -10,6 +10,7 @@ #include <wx/intl.h> +class CustomComboBox; class CustomGridLeft; class CustomGridMiddle; class CustomGridRight; @@ -36,7 +37,6 @@ class wxButtonWithImage; #include <wx/scrolwin.h> #include <wx/grid.h> #include <wx/choice.h> -#include <wx/hyperlink.h> #include <wx/checkbox.h> #include <wx/notebook.h> #include <wx/statbmp.h> @@ -48,6 +48,7 @@ class wxButtonWithImage; #include <wx/gauge.h> #include <wx/animate.h> #include <wx/treectrl.h> +#include <wx/hyperlink.h> #include <wx/checklst.h> /////////////////////////////////////////////////////////////////////////// @@ -90,25 +91,20 @@ class MainDialogGenerated : public wxFrame wxBitmapButton* m_bpButtonSyncConfig; wxButtonWithImage* m_buttonStartSync; - wxPanel* m_panelTopLeft; wxStaticBoxSizer* sbSizer2; - wxComboBox* m_directoryLeft; - wxDirPickerCtrl* m_dirPickerLeft; wxPanel* m_panelTopMiddle; wxBoxSizer* bSizerMiddle; wxBitmapButton* m_bpButtonSwapSides; - wxPanel* m_panelTopRight; + + + wxBitmapButton* m_bpButtonAddPair; - wxComboBox* m_directoryRight; - wxDirPickerCtrl* m_dirPickerRight; wxScrolledWindow* m_scrolledWindowFolderPairs; wxBoxSizer* bSizerAddFolderPairs; - wxPanel* m_panelLeft; CustomGridLeft* m_gridLeft; wxPanel* m_panelMiddle; CustomGridMiddle* m_gridMiddle; - wxPanel* m_panelRight; CustomGridRight* m_gridRight; wxBoxSizer* bSizer3; wxNotebook* m_notebookBottomLeft; @@ -118,7 +114,7 @@ class MainDialogGenerated : public wxFrame wxChoice* m_choiceHistory; wxPanel* m_panelFilter; wxBitmapButton* m_bpButtonFilter; - wxHyperlinkCtrl* m_hyperlinkCfgFilter; + wxCheckBox* m_checkBoxActivateFilter; wxCheckBox* m_checkBoxHideFilt; wxPanel* m_panel112; @@ -175,14 +171,15 @@ class MainDialogGenerated : public wxFrame virtual void OnMenuGlobalSettings( wxCommandEvent& event ){ event.Skip(); } virtual void OnMenuBatchJob( wxCommandEvent& event ){ event.Skip(); } virtual void OnMenuExportFileList( wxCommandEvent& event ){ event.Skip(); } + virtual void OnShowHelp( wxCommandEvent& event ){ event.Skip(); } virtual void OnMenuCheckVersion( wxCommandEvent& event ){ event.Skip(); } virtual void OnMenuAbout( wxCommandEvent& event ){ event.Skip(); } virtual void OnCmpSettings( wxCommandEvent& event ){ event.Skip(); } virtual void OnSyncSettings( wxCommandEvent& event ){ event.Skip(); } - virtual void OnFolderHistoryKeyEvent( wxKeyEvent& event ){ event.Skip(); } virtual void OnDirSelected( wxFileDirPickerEvent& event ){ event.Skip(); } virtual void OnSwapSides( wxCommandEvent& event ){ event.Skip(); } virtual void OnAddFolderPair( wxCommandEvent& event ){ event.Skip(); } + virtual void OnRemoveTopFolderPair( wxCommandEvent& event ){ event.Skip(); } virtual void OnLeftGridDoubleClick( wxGridEvent& event ){ event.Skip(); } virtual void OnContextRim( wxGridEvent& event ){ event.Skip(); } virtual void OnSortLeftGrid( wxGridEvent& event ){ event.Skip(); } @@ -195,8 +192,8 @@ class MainDialogGenerated : public wxFrame virtual void OnContextRimLabelRight( wxGridEvent& event ){ event.Skip(); } virtual void OnCfgHistoryKeyEvent( wxKeyEvent& event ){ event.Skip(); } virtual void OnLoadFromHistory( wxCommandEvent& event ){ event.Skip(); } + virtual void OnConfigureFilter( wxCommandEvent& event ){ event.Skip(); } virtual void OnFilterButton( wxCommandEvent& event ){ event.Skip(); } - virtual void OnConfigureFilter( wxHyperlinkEvent& event ){ event.Skip(); } virtual void OnHideFilteredButton( wxCommandEvent& event ){ event.Skip(); } virtual void OnLeftOnlyFiles( wxCommandEvent& event ){ event.Skip(); } virtual void OnLeftNewerFiles( wxCommandEvent& event ){ event.Skip(); } @@ -216,6 +213,17 @@ class MainDialogGenerated : public wxFrame public: + wxPanel* m_panelTopLeft; + CustomComboBox* m_directoryLeft; + wxDirPickerCtrl* m_dirPickerLeft; + wxBitmapButton* m_bpButtonLocalFilter; + wxBitmapButton* m_bpButtonAltSyncCfg; + wxPanel* m_panelTopRight; + wxBitmapButton* m_bpButtonRemovePair; + CustomComboBox* m_directoryRight; + wxDirPickerCtrl* m_dirPickerRight; + wxPanel* m_panelLeft; + wxPanel* m_panelRight; MainDialogGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("FreeFileSync - Folder Comparison and Synchronization"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 933,612 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL ); ~MainDialogGenerated(); @@ -231,8 +239,7 @@ class FolderPairGenerated : public wxPanel protected: wxPanel* m_panel20; - wxBitmapButton* m_bpButtonAltFilter; - wxBitmapButton* m_bpButtonAltSyncCfg; + public: @@ -240,6 +247,8 @@ class FolderPairGenerated : public wxPanel wxTextCtrl* m_directoryLeft; wxDirPickerCtrl* m_dirPickerLeft; wxPanel* m_panel21; + wxBitmapButton* m_bpButtonLocalFilter; + wxBitmapButton* m_bpButtonAltSyncCfg; wxPanel* m_panelRight; wxBitmapButton* m_bpButtonRemovePair; wxTextCtrl* m_directoryRight; @@ -261,17 +270,17 @@ class BatchFolderPairGenerated : public wxPanel wxStaticText* m_staticText53; wxStaticText* m_staticText541; wxPanel* m_panelLeft; - wxBitmapButton* m_bpButtonAltFilter; wxPanel* m_panelRight; - wxBitmapButton* m_bpButtonAltSyncCfg; public: wxBitmapButton* m_bpButtonRemovePair; wxTextCtrl* m_directoryLeft; wxDirPickerCtrl* m_dirPickerLeft; + wxBitmapButton* m_bpButtonLocalFilter; wxTextCtrl* m_directoryRight; wxDirPickerCtrl* m_dirPickerRight; + wxBitmapButton* m_bpButtonAltSyncCfg; BatchFolderPairGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); ~BatchFolderPairGenerated(); @@ -297,13 +306,10 @@ class BatchDlgGenerated : public wxDialog wxStaticText* m_staticText531; wxNotebook* m_notebookSettings; wxPanel* m_panelOverview; - wxScrolledWindow* m_scrolledWindow6; wxBoxSizer* sbSizerMainPair; wxPanel* m_panelMainPair; wxStaticText* m_staticText532; wxStaticText* m_staticText5411; - wxPanel* m_panelLeft; - wxPanel* m_panelRight; wxBoxSizer* bSizerAddFolderPairs; @@ -363,6 +369,7 @@ class BatchDlgGenerated : public wxDialog // Virtual event handlers, overide them in your derived class virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } virtual void OnAddFolderPair( wxCommandEvent& event ){ event.Skip(); } + virtual void OnRemoveTopFolderPair( wxCommandEvent& event ){ event.Skip(); } virtual void OnChangeCompareVar( wxCommandEvent& event ){ event.Skip(); } virtual void OnCheckAutomatic( wxCommandEvent& event ){ event.Skip(); } virtual void OnCheckFilter( wxCommandEvent& event ){ event.Skip(); } @@ -381,11 +388,17 @@ class BatchDlgGenerated : public wxDialog public: + wxScrolledWindow* m_scrolledWindow6; wxBitmapButton* m_bpButtonAddPair; + wxBitmapButton* m_bpButtonRemovePair; + wxPanel* m_panelLeft; wxTextCtrl* m_directoryLeft; wxDirPickerCtrl* m_dirPickerLeft; + wxBitmapButton* m_bpButtonLocalFilter; + wxPanel* m_panelRight; wxTextCtrl* m_directoryRight; wxDirPickerCtrl* m_dirPickerRight; + wxBitmapButton* m_bpButtonAltSyncCfg; BatchDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Create a batch job"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~BatchDlgGenerated(); @@ -520,8 +533,10 @@ class CmpCfgDlgGenerated : public wxDialog protected: wxRadioButton* m_radioBtnSizeDate; + wxStaticBitmap* m_bitmapByTime; wxButton* m_buttonTimeSize; wxRadioButton* m_radioBtnContent; + wxStaticBitmap* m_bitmapByContent; wxButton* m_buttonContent; wxStaticLine* m_staticline14; wxBitmapButton* m_bpButtonHelp; @@ -648,6 +663,35 @@ class HelpDlgGenerated : public wxDialog }; /////////////////////////////////////////////////////////////////////////////// +/// Class ReadmeDlgGenerated +/////////////////////////////////////////////////////////////////////////////// +class ReadmeDlgGenerated : public wxDialog +{ + private: + + protected: + + wxStaticBitmap* m_bitmap25; + wxPanel* m_panel8; + + wxStaticText* m_staticText56; + + + wxTextCtrl* m_textCtrlMain; + wxButton* m_buttonOkay; + + // Virtual event handlers, overide them in your derived class + virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } + virtual void OnOK( wxCommandEvent& event ){ event.Skip(); } + + + public: + ReadmeDlgGenerated( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 706,475 ), long style = wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER ); + ~ReadmeDlgGenerated(); + +}; + +/////////////////////////////////////////////////////////////////////////////// /// Class AboutDlgGenerated /////////////////////////////////////////////////////////////////////////////// class AboutDlgGenerated : public wxDialog @@ -836,7 +880,7 @@ class FilterDlgGenerated : public wxDialog protected: wxStaticBitmap* m_bitmap26; wxPanel* m_panel8; - wxStaticText* m_staticText56; + wxStaticText* m_staticTexHeader; wxStaticText* m_staticText44; wxBitmapButton* m_bpButtonHelp; @@ -849,6 +893,7 @@ class FilterDlgGenerated : public wxDialog wxStaticText* m_staticText85; wxStaticText* m_staticText181; wxStaticText* m_staticText1811; + wxStaticText* m_staticTextFilteringInactive; wxStaticText* m_staticText15; wxStaticBitmap* m_bitmap8; @@ -924,6 +969,9 @@ class GlobalSettingsDlgGenerated : public wxDialog wxStaticText* m_staticText114; wxCheckBox* m_checkBoxIgnoreOneHour; + wxStaticText* m_staticTextCopyLocked; + + wxCheckBox* m_checkBoxCopyLocked; wxStaticLine* m_staticline10; wxStaticText* m_staticText100; diff --git a/ui/settingsDialog.cpp b/ui/settingsDialog.cpp index 90437453..230d187d 100644 --- a/ui/settingsDialog.cpp +++ b/ui/settingsDialog.cpp @@ -489,48 +489,14 @@ void SyncCfgDialog::OnConflict(wxCommandEvent& event) toggleSyncDirection(localSyncConfiguration.conflict); updateConfigIcons(cmpVariant, localSyncConfiguration); } -//################################################################################################################################### - - -typedef FreeFileSync::FolderPairPanelBasic<BatchFolderPairGenerated> FolderPairParent; - -class BatchFolderPairPanel : public FolderPairParent -{ -public: - BatchFolderPairPanel(wxWindow* parent, BatchDialog* batchDialog) : - FolderPairParent(parent), - batchDlg(batchDialog) {} - -private: - virtual wxWindow* getParentWindow() - { - return batchDlg; - } - virtual MainConfiguration getMainConfig() const - { - return batchDlg->getCurrentConfiguration().mainCfg; - } - - virtual void OnAltFilterCfgChange(bool defaultValueSet) - { - if (!defaultValueSet) - { - //activate filter - batchDlg->m_checkBoxFilter->SetValue(true); - batchDlg->updateVisibleTabs(); - } - } - BatchDialog* batchDlg; -}; //################################################################################################################################### - class BatchFileDropEvent : public wxFileDropTarget { public: - BatchFileDropEvent(BatchDialog* dlg) : + BatchFileDropEvent(BatchDialog& dlg) : batchDlg(dlg) {} virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames) @@ -543,7 +509,7 @@ public: //test if ffs batch file has been dropped if (fileType == xmlAccess::XML_BATCH_CONFIG) - batchDlg->loadBatchFile(droppedFileName); + batchDlg.loadBatchFile(droppedFileName); else { wxString errorMessage = _("%x is not a valid FreeFileSync batch file!"); @@ -555,10 +521,89 @@ public: } private: - BatchDialog* batchDlg; + BatchDialog& batchDlg; +}; + +//################################################################################################################################### + +//------------------------------------------------------------------ +/* class hierarchy: + + template<> + FolderPairPanelBasic + /|\ + | + template<> + FolderPairCallback BatchFolderPairGenerated + /|\ /|\ + _________|______________ ________| + | | | + FirstBatchFolderPairCfg BatchFolderPairPanel +*/ + +template <class GuiPanel> +class FolderPairCallback : public FolderPairPanelBasic<GuiPanel> //implements callback functionality to BatchDialog as imposed by FolderPairPanelBasic +{ +public: + FolderPairCallback(GuiPanel& basicPanel, BatchDialog& batchDialog) : + FolderPairPanelBasic<GuiPanel>(basicPanel), //pass FolderPairGenerated part... + batchDlg(batchDialog) {} + +private: + virtual wxWindow* getParentWindow() + { + return &batchDlg; + } + + virtual MainConfiguration getMainConfig() const + { + return batchDlg.getCurrentConfiguration().mainCfg; + } + + BatchDialog& batchDlg; +}; + + +class BatchFolderPairPanel : + public BatchFolderPairGenerated, //BatchFolderPairPanel "owns" BatchFolderPairGenerated! + public FolderPairCallback<BatchFolderPairGenerated> +{ +public: + BatchFolderPairPanel(wxWindow* parent, BatchDialog& batchDialog) : + BatchFolderPairGenerated(parent), + FolderPairCallback<BatchFolderPairGenerated>(static_cast<BatchFolderPairGenerated&>(*this), batchDialog), //pass BatchFolderPairGenerated part... + dragDropOnLeft( m_panelLeft, m_dirPickerLeft, m_directoryLeft), + dragDropOnRight(m_panelRight, m_dirPickerRight, m_directoryRight) {} + +private: + //support for drag and drop + DragDropOnDlg dragDropOnLeft; + DragDropOnDlg dragDropOnRight; }; +class FirstBatchFolderPairCfg : public FolderPairCallback<BatchDlgGenerated> +{ +public: + FirstBatchFolderPairCfg(BatchDialog& batchDialog) : + FolderPairCallback<BatchDlgGenerated>(batchDialog, batchDialog), + + //prepare drag & drop + dragDropOnLeft(batchDialog.m_panelLeft, + batchDialog.m_dirPickerLeft, + batchDialog.m_directoryLeft), + dragDropOnRight(batchDialog.m_panelRight, + batchDialog.m_dirPickerRight, + batchDialog.m_directoryRight) {} + +private: + //support for drag and drop + DragDropOnDlg dragDropOnLeft; + DragDropOnDlg dragDropOnRight; +}; + + +//################################################################################################################################### BatchDialog::BatchDialog(wxWindow* window, const xmlAccess::XmlBatchConfig& batchCfg) : BatchDlgGenerated(window) { @@ -577,14 +622,17 @@ BatchDialog::BatchDialog(wxWindow* window, const wxString& filename) : void BatchDialog::init() { + wxWindowUpdateLocker dummy(this); //avoid display distortion + + //init handling of first folder pair + firstFolderPair.reset(new FirstBatchFolderPairCfg(*this)); + + //prepare drag & drop for loading of *.ffs_batch files - SetDropTarget(new BatchFileDropEvent(this)); + SetDropTarget(new BatchFileDropEvent(*this)); dragDropOnLogfileDir.reset(new DragDropOnDlg(m_panelLogging, m_dirPickerLogfileDir, m_textCtrlLogfileDir)); - //support for drag and drop on main pair - dragDropOnLeft.reset( new DragDropOnDlg(m_panelLeft, m_dirPickerLeft, m_directoryLeft)); - dragDropOnRight.reset(new DragDropOnDlg(m_panelRight, m_dirPickerRight, m_directoryRight)); - + //support for drag and drop: user-defined deletion directory dragDropCustomDelFolder.reset(new DragDropOnDlg(m_panelCustomDeletionDir, m_dirPickerCustomDelFolder, m_textCtrlCustomDelFolder)); @@ -769,6 +817,16 @@ void BatchDialog::OnConflict(wxCommandEvent& event) void BatchDialog::OnCheckFilter(wxCommandEvent& event) { updateVisibleTabs(); + + //update main local filter + firstFolderPair->refreshButtons(); + + //update folder pairs + for (std::vector<BatchFolderPairPanel*>::const_iterator i = additionalFolderPairs.begin(); i != additionalFolderPairs.end(); ++i) + { + BatchFolderPairPanel* dirPair = *i; + dirPair->refreshButtons(); + } } @@ -798,7 +856,7 @@ void BatchDialog::OnCheckSilent(wxCommandEvent& event) void BatchDialog::updateVisibleTabs() { - showNotebookpage(m_panelFilter, _("Filter"), m_checkBoxFilter->GetValue()); + showNotebookpage(m_panelFilter, _("Filter"), m_checkBoxFilter->GetValue()); showNotebookpage(m_panelLogging, _("Logging"), m_checkBoxSilent->GetValue()); } @@ -936,8 +994,8 @@ void BatchDialog::OnLoadBatchJob(wxCommandEvent& event) inline FolderPairEnh getEnahncedPair(const BatchFolderPairPanel* panel) { - return FolderPairEnh(wxToZ(panel->m_directoryLeft->GetValue()), - wxToZ(panel->m_directoryRight->GetValue()), + return FolderPairEnh(panel->getLeftDir(), + panel->getRightDir(), panel->getAltSyncConfig(), panel->getAltFilterConfig()); } @@ -956,9 +1014,11 @@ xmlAccess::XmlBatchConfig BatchDialog::getCurrentConfiguration() const batchCfg.mainCfg.handleDeletion = getDeletionHandling(); batchCfg.mainCfg.customDeletionDirectory = m_textCtrlCustomDelFolder->GetValue(); - //main pair - batchCfg.mainCfg.mainFolderPair.leftDirectory = wxToZ(m_directoryLeft->GetValue()); - batchCfg.mainCfg.mainFolderPair.rightDirectory = wxToZ(m_directoryRight->GetValue()); + //first folder pair + batchCfg.mainCfg.firstPair = FolderPairEnh(firstFolderPair->getLeftDir(), + firstFolderPair->getRightDir(), + firstFolderPair->getAltSyncConfig(), + firstFolderPair->getAltFilterConfig()); //add additional pairs batchCfg.mainCfg.additionalPairs.clear(); @@ -1053,10 +1113,11 @@ void BatchDialog::loadBatchCfg(const xmlAccess::XmlBatchConfig& batchCfg) //error handling is dependent from m_checkBoxSilent! /|\ \|/ setSelectionHandleError(batchCfg.handleError); - - //set main folder pair - FreeFileSync::setDirectoryName(zToWx(batchCfg.mainCfg.mainFolderPair.leftDirectory), m_directoryLeft, m_dirPickerLeft); - FreeFileSync::setDirectoryName(zToWx(batchCfg.mainCfg.mainFolderPair.rightDirectory), m_directoryRight, m_dirPickerRight); + //set first folder pair + firstFolderPair->setValues(batchCfg.mainCfg.firstPair.leftDirectory, + batchCfg.mainCfg.firstPair.rightDirectory, + batchCfg.mainCfg.firstPair.altSyncConfig, + batchCfg.mainCfg.firstPair.localFilter); //remove existing additional folder pairs clearAddFolderPairs(); @@ -1074,14 +1135,19 @@ void BatchDialog::loadBatchCfg(const xmlAccess::XmlBatchConfig& batchCfg) void BatchDialog::OnAddFolderPair(wxCommandEvent& event) { + wxWindowUpdateLocker dummy(this); //avoid display distortion + std::vector<FolderPairEnh> newPairs; - newPairs.push_back( - FolderPairEnh(Zstring(), - Zstring(), - boost::shared_ptr<AlternateSyncConfig>(), - boost::shared_ptr<AlternateFilter>())); + newPairs.push_back(getCurrentConfiguration().mainCfg.firstPair); + + addFolderPair(newPairs, true); //add pair in front of additonal pairs - addFolderPair(newPairs, false); //add pair at the end of additional pairs + //clear first pair + const FolderPairEnh cfgEmpty; + firstFolderPair->setValues(cfgEmpty.leftDirectory, + cfgEmpty.rightDirectory, + cfgEmpty.altSyncConfig, + cfgEmpty.localFilter); } @@ -1104,13 +1170,16 @@ void BatchDialog::OnRemoveTopFolderPair(wxCommandEvent& event) { if (additionalFolderPairs.size() > 0) { - const wxString leftDir = (*additionalFolderPairs.begin())->m_directoryLeft ->GetValue().c_str(); - const wxString rightDir = (*additionalFolderPairs.begin())->m_directoryRight->GetValue().c_str(); + //get settings from second folder pair + const FolderPairEnh cfgSecond = getEnahncedPair(additionalFolderPairs[0]); - FreeFileSync::setDirectoryName(leftDir, m_directoryLeft, m_dirPickerLeft); - FreeFileSync::setDirectoryName(rightDir, m_directoryRight, m_dirPickerRight); + //reset first pair + firstFolderPair->setValues(cfgSecond.leftDirectory, + cfgSecond.rightDirectory, + cfgSecond.altSyncConfig, + cfgSecond.localFilter); - removeAddFolderPair(0); //remove first of additional folder pairs + removeAddFolderPair(0); //remove second folder pair (first of additional folder pairs) } } @@ -1118,18 +1187,45 @@ void BatchDialog::OnRemoveTopFolderPair(wxCommandEvent& event) const size_t MAX_FOLDER_PAIRS = 3; -void BatchDialog::addFolderPair(const std::vector<FreeFileSync::FolderPairEnh>& newPairs, bool addFront) +void BatchDialog::updateGuiForFolderPair() { - if (newPairs.size() == 0) - return; + //adapt delete top folder pair button + if (additionalFolderPairs.size() == 0) + m_bpButtonRemovePair->Hide(); + else + m_bpButtonRemovePair->Show(); + + //adapt local filter and sync cfg for first folder pair + if ( additionalFolderPairs.size() == 0 && + firstFolderPair->getAltSyncConfig().get() == NULL && + NameFilter(firstFolderPair->getAltFilterConfig().includeFilter, + firstFolderPair->getAltFilterConfig().excludeFilter).isNull()) + { + m_bpButtonLocalFilter->Hide(); + m_bpButtonAltSyncCfg->Hide(); + } + else + { + m_bpButtonLocalFilter->Show(); + m_bpButtonAltSyncCfg->Show(); + } + + m_scrolledWindow6->Fit(); //adjust scrolled window size + m_panelOverview->Layout(); //adjust stuff inside scrolled window +} + +void BatchDialog::addFolderPair(const std::vector<FreeFileSync::FolderPairEnh>& newPairs, bool addFront) +{ wxWindowUpdateLocker dummy(m_panelOverview); //avoid display distortion + if (!newPairs.empty()) +{ //add folder pairs int pairHeight = 0; for (std::vector<FreeFileSync::FolderPairEnh>::const_iterator i = newPairs.begin(); i != newPairs.end(); ++i) { - BatchFolderPairPanel* newPair = new BatchFolderPairPanel(m_scrolledWindow6, this); + BatchFolderPairPanel* newPair = new BatchFolderPairPanel(m_scrolledWindow6, *this); if (addFront) { @@ -1148,12 +1244,11 @@ void BatchDialog::addFolderPair(const std::vector<FreeFileSync::FolderPairEnh>& //register events newPair->m_bpButtonRemovePair->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BatchDialog::OnRemoveFolderPair), NULL, this ); - //insert directory names - FreeFileSync::setDirectoryName(zToWx(i->leftDirectory), newPair->m_directoryLeft, newPair->m_dirPickerLeft); - FreeFileSync::setDirectoryName(zToWx(i->rightDirectory), newPair->m_directoryRight, newPair->m_dirPickerRight); - //set alternate configuration - newPair->setValues(i->altSyncConfig, i->altFilter); + newPair->setValues(i->leftDirectory, + i->rightDirectory, + i->altSyncConfig, + i->localFilter); } //set size of scrolled window const int visiblePairs = std::min(additionalFolderPairs.size() + 1, MAX_FOLDER_PAIRS); //up to MAX_FOLDER_PAIRS pairs shall be shown @@ -1168,13 +1263,16 @@ void BatchDialog::addFolderPair(const std::vector<FreeFileSync::FolderPairEnh>& m_bpButtonLeftOnly->SetFocus(); } + updateGuiForFolderPair(); +} + void BatchDialog::removeAddFolderPair(const int pos) { - if (0 <= pos && pos < static_cast<int>(additionalFolderPairs.size())) - { wxWindowUpdateLocker dummy(m_panelOverview); //avoid display distortion + if (0 <= pos && pos < static_cast<int>(additionalFolderPairs.size())) + { //remove folder pairs from window BatchFolderPairPanel* pairToDelete = additionalFolderPairs[pos]; const int pairHeight = pairToDelete->GetSize().GetHeight(); @@ -1197,6 +1295,8 @@ void BatchDialog::removeAddFolderPair(const int pos) //after changing folder pairs window focus is lost: results in scrolled window scrolling to top each time window is shown: we don't want this m_bpButtonLeftOnly->SetFocus(); } + + updateGuiForFolderPair(); } diff --git a/ui/settingsDialog.h b/ui/settingsDialog.h index feb763a9..0864cf92 100644 --- a/ui/settingsDialog.h +++ b/ui/settingsDialog.h @@ -7,6 +7,7 @@ class BatchFileDropEvent; class BatchFolderPairPanel; +class FirstBatchFolderPairCfg; namespace FreeFileSync { @@ -97,7 +98,8 @@ private: class BatchDialog: public BatchDlgGenerated { friend class BatchFileDropEvent; - friend class BatchFolderPairPanel; + template <class GuiPanel> + friend class FolderPairCallback; public: BatchDialog(wxWindow* window, const xmlAccess::XmlBatchConfig& batchCfg); @@ -135,6 +137,8 @@ private: void removeAddFolderPair(const int pos); void clearAddFolderPairs(); +void updateGuiForFolderPair(); + FreeFileSync::CompareVariant getCurrentCompareVar() const; void updateConfigIcons(const FreeFileSync::CompareVariant cmpVar, const FreeFileSync::SyncConfiguration& syncConfig); @@ -163,6 +167,8 @@ private: xmlAccess::XmlBatchConfig getCurrentConfiguration() const; FreeFileSync::SyncConfiguration localSyncConfiguration; + + boost::shared_ptr<FirstBatchFolderPairCfg> firstFolderPair; //always bound!!! std::vector<BatchFolderPairPanel*> additionalFolderPairs; //used when saving batch file @@ -170,11 +176,6 @@ private: //add drag & drop support when selecting logfile directory std::auto_ptr<FreeFileSync::DragDropOnDlg> dragDropOnLogfileDir; - - //support for drag and drop on main pair - std::auto_ptr<FreeFileSync::DragDropOnDlg> dragDropOnLeft; - std::auto_ptr<FreeFileSync::DragDropOnDlg> dragDropOnRight; - std::auto_ptr<FreeFileSync::DragDropOnDlg> dragDropCustomDelFolder; }; diff --git a/ui/sorting.h b/ui/sorting.h index e65344e6..04ecc171 100644 --- a/ui/sorting.h +++ b/ui/sorting.h @@ -72,7 +72,8 @@ bool sortByFileName(const FileSystemObject& a, const FileSystemObject& b) if (dynamic_cast<const DirMapping*>(&b)) return true; else - return Compare<ascending>().isSmallerThan(a.getShortName<side>(), b.getShortName<side>()); + return Compare<ascending>().isSmallerThan( + compareString(a.getShortName<side>(), b.getShortName<side>()), 0); } } diff --git a/ui/trayIcon.cpp b/ui/trayIcon.cpp index 42847eb0..478d135a 100644 --- a/ui/trayIcon.cpp +++ b/ui/trayIcon.cpp @@ -1,7 +1,7 @@ #include "trayIcon.h" #include "../library/resources.h" #include "smallDialogs.h" -#include "../library/statusHandler.h" +//#include "../library/statusHandler.h" #include <wx/taskbar.h> @@ -79,7 +79,7 @@ void MinimizeToTray::resumeFromTray() //remove trayIcon and restore windows: Mi trayIcon->RemoveIcon(); //hide icon until final deletion takes place trayIcon->Disconnect(wxEVT_TASKBAR_LEFT_DCLICK, wxCommandEventHandler(MinimizeToTray::OnDoubleClick), NULL, this); - //delayed destruction: delete during next idle loop iteration (handle late window messages, e.g. when double-clicking) + //use wxWidgets delayed destruction: delete during next idle loop iteration (handle late window messages, e.g. when double-clicking) if (!wxPendingDelete.Member(trayIcon)) wxPendingDelete.Append(trayIcon); diff --git a/ui/trayIcon.h b/ui/trayIcon.h index 370e85f3..94e75518 100644 --- a/ui/trayIcon.h +++ b/ui/trayIcon.h @@ -13,6 +13,7 @@ public: void setToolTip(const wxString& toolTipText); void keepHidden(); //do not show windows again: avoid window flashing shortly before it is destroyed + private: void OnContextMenuSelection(wxCommandEvent& event); void OnDoubleClick(wxCommandEvent& event); diff --git a/version/version.h b/version/version.h index 2e65aaf5..647be5ba 100644 --- a/version/version.h +++ b/version/version.h @@ -2,5 +2,5 @@ namespace FreeFileSync { - static const wxString currentVersion = wxT("3.1"); //internal linkage! + static const wxString currentVersion = wxT("3.2"); //internal linkage! } |